Beispiel #1
0
/* Daemon init sequence */
static void
start_check(void)
{
	/* Initialize sub-system */
	ipvs_start();
	init_checkers_queue();
#ifdef _WITH_VRRP_
	init_interface_queue();
	kernel_netlink_init();
#endif
#ifdef _WITH_SNMP_
	if (!reload && snmp)
		check_snmp_agent_init();
#endif

	/* Parse configuration file */
	global_data = alloc_global_data();
	check_data = alloc_check_data();
	init_data(conf_file, check_init_keywords);
	if (!check_data) {
		stop_check();
		return;
	}

	/* Post initializations */
	log_message(LOG_INFO, "Configuration is using : %lu Bytes", mem_allocated);

	/* SSL load static data & initialize common ctx context */
	if (!init_ssl_ctx()) {
		stop_check();
		return;
	}

	/* Processing differential configuration parsing */
	if (reload) {
		clear_diff_services();
		copy_srv_states();
	}

	/* Initialize IPVS topology */
	if (!init_services()) {
		stop_check();
		return;
	}

	/* Dump configuration */
	if (debug & 4) {
		dump_global_data(global_data);
		dump_check_data(check_data);
	}

#ifdef _WITH_VRRP_
	/* Initialize linkbeat */
	init_interface_linkbeat();
#endif

	/* Register checkers thread */
	register_checkers_thread();
}
Beispiel #2
0
/* 准备连接状态
 */
int32 ssl_io::init_connect( int32 fd )
{
    if ( init_ssl_ctx( fd ) < 0 ) return -1;

    _fd = fd;
    SSL_set_connect_state( X_SSL( _ssl_ctx ) );

    return do_handshake();
}
Beispiel #3
0
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {

	cp->ssl_active = -1;

	if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_serverclient)) {
		/* write back an "SSL reject" response before returning */
		pool_write_and_flush(cp, "N", 1);
	} else {
		/* write back an "SSL accept" response */
		pool_write_and_flush(cp, "S", 1);

		SSL_set_fd(cp->ssl, cp->fd);
		SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept");
		cp->ssl_active = 1;
	}
}
Beispiel #4
0
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
	int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) };
	char server_response;

	cp->ssl_active = -1;

	if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_clientserver))
		return;

	ereport(DEBUG1,
		(errmsg("attempting to negotiate a secure connection"),
			 errdetail("sending client->server SSL request")));
	pool_write_and_flush(cp, ssl_packet, sizeof(int)*2);

	if (pool_read(cp, &server_response, 1) < 0)
	{
		ereport(WARNING,
				(errmsg("error while attempting to negotiate a secure connection, pool_read failed")));
 		return;
	}

	ereport(DEBUG1,
		(errmsg("attempting to negotiate a secure connection"),
			 errdetail("client->server SSL response: %c", server_response)));

	switch (server_response) {
		case 'S':
			SSL_set_fd(cp->ssl, cp->fd);
			SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0),
			                    "SSL_connect");
			cp->ssl_active = 1;
			break;
		case 'N':
			/*
			 * If backend does not support SSL but pgpool does, we get this.
			 * i.e. This is normal.
			 */
			ereport(DEBUG1,
				(errmsg("attempting to negotiate a secure connection"),
					 errdetail("server doesn't want to talk SSL")));
			break;
		default:
			ereport(WARNING,
					(errmsg("error while attempting to negotiate a secure connection, unhandled response: %c", server_response)));
			break;
	}
}
Beispiel #5
0
bool ApnsService::Start()
{
	auto iter = resolver_addr(false);
	if (iter == boost::asio::ip::tcp::resolver::iterator())
	{
		LOGFMTE("resolver apns host faild");
		return false;
	}

	if (!init_ssl_ctx())
	{
		return false;
	}

	for (size_t i = 0; i < apns_params_.ApnsConnCount; i++)
	{
		auto conn = std::make_shared<ApnsConnection>(*io_service_, *ssl_ctx_, iter, this);
		conn->SetIdleTime(apns_params_.IdleTime);
		conn->Connect();
		apns_conns_.push_back(conn);
	}


	//feed back service
	auto iter_feedback = resolver_addr(true);
	if (iter_feedback == boost::asio::ip::tcp::resolver::iterator())
	{
		LOGFMTE("resolver apns feedback host faild");
		return false;
	}

	fd_conn_.reset(new  ApnsFeedBackConnection(*io_service_, *ssl_ctx_, iter_feedback, this));
	//get feedback time interval
	int t = 24 * 3600;
	if (apns_params_.FeedBackTime > 0 && apns_params_.FeedBackTime < (30 * t))
	{
		t = apns_params_.FeedBackTime;
	}

	SetTimer(1, 1000 * t, NULL);

	LOGFMTD("ApnsService %s start!", apns_params_.Name.c_str());
	stopped_ = false;
	return true;
}
Beispiel #6
0
/*
  Connect to host on the given port using tls and return the BIO object
  representing the connection.
*/
BIO* connect_tls(const char *host, const char *port){
  init_ssl_lib();
  //the assignment is redundant, but it's weird not having it
  ctx = init_ssl_ctx();
  if(!ctx){return NULL;}

  BIO *bio = BIO_new_ssl_connect(ctx);
  if(!bio){goto err;}

  if(BIO_set_conn_hostname(bio, host) == 0){
    goto err;
  }
  if(BIO_set_conn_port(bio, port) == 0){
    goto err;
  }

  SSL *ssl;
  BIO_get_ssl(bio, &ssl);
  //Handle renegotiation transparently
  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
  //this is to let the server know what name we used to connect to it
  SSL_set_tlsext_host_name(ssl, host);
  if(BIO_do_connect(bio) == 0){
    goto err;
  }
  if(BIO_do_handshake(bio) == 0){
    goto err;
  }
  //make sure that the certificate was valid
  if(SSL_get_verify_result(ssl) != X509_V_OK){
    goto err;
  }

  return bio;
 err:
  print_errors();
  BIO_free_all(bio);
  SSL_CTX_free(ctx);
  return NULL;
}
Beispiel #7
0
/* Daemon init sequence */
static void
start_check(void)
{
	/* Initialize sub-system */
	if (ipvs_start() != IPVS_SUCCESS) {
		stop_check(KEEPALIVED_EXIT_FATAL);
		return;
	}

	init_checkers_queue();
#ifdef _WITH_VRRP_
	init_interface_queue();
	kernel_netlink_init();
#endif

	/* Parse configuration file */
	global_data = alloc_global_data();
	check_data = alloc_check_data();
	if (!check_data)
		stop_check(KEEPALIVED_EXIT_FATAL);

	init_data(conf_file, check_init_keywords);

	init_global_data(global_data);

	/* Post initializations */
#ifdef _MEM_CHECK_
	log_message(LOG_INFO, "Configuration is using : %zu Bytes", mem_allocated);
#endif

	/* Remove any entries left over from previous invocation */
	if (!reload && global_data->lvs_flush)
		ipvs_flush_cmd();

#ifdef _WITH_SNMP_CHECKER_
	if (!reload && global_data->enable_snmp_checker)
		check_snmp_agent_init(global_data->snmp_socket);
#endif

	/* SSL load static data & initialize common ctx context */
	if (!init_ssl_ctx())
		stop_check(KEEPALIVED_EXIT_FATAL);

	/* fill 'vsg' members of the virtual_server_t structure.
	 * We must do that after parsing config, because
	 * vs and vsg declarations may appear in any order
	 */
	link_vsg_to_vs();

	/* Set the process priority and non swappable if configured */
	if (global_data->checker_process_priority)
		set_process_priority(global_data->checker_process_priority);

	if (global_data->checker_no_swap)
		set_process_dont_swap(4096);	/* guess a stack size to reserve */

	/* Processing differential configuration parsing */
	if (reload)
		clear_diff_services();

	/* Initialize IPVS topology */
	if (!init_services())
		stop_check(KEEPALIVED_EXIT_FATAL);

	/* Dump configuration */
	if (__test_bit(DUMP_CONF_BIT, &debug)) {
		dump_global_data(global_data);
		dump_check_data(check_data);
	}

#ifdef _WITH_VRRP_
	/* Initialize linkbeat */
	init_interface_linkbeat();
#endif

	/* Register checkers thread */
	register_checkers_thread();
}
Beispiel #8
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  spdylay_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];
  uint16_t spdy_proto_version;

  request_init(&req, uri);

  setup_spdylay_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx, &spdy_proto_version);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version);
  rv = spdylay_session_client_new(&connection.session, spdy_proto_version,
                                  &callbacks, &connection);
  if(rv != 0) {
    diec("spdylay_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(spdylay_session_want_read(connection.session) ||
        spdylay_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  spdylay_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Beispiel #9
0
/* Daemon init sequence */
static void
start_check(void)
{
	/* Initialize sub-system */
	if (ipvs_start() != IPVS_SUCCESS) {
		stop_check();
		return;
	}
	init_checkers_queue();
#ifdef _WITH_VRRP_
	init_interface_queue();
	kernel_netlink_init();
#endif
#ifdef _WITH_SNMP_
	if (!reload && snmp)
		check_snmp_agent_init(snmp_socket);
#endif

	/* Parse configuration file */
	global_data = alloc_global_data();
	check_data = alloc_check_data();
	init_data(conf_file, check_init_keywords);
	if (!check_data) {
		stop_check();
		return;
	}
	init_global_data(global_data);

	/* Post initializations */
#ifdef _DEBUG_
	log_message(LOG_INFO, "Configuration is using : %lu Bytes", mem_allocated);
#endif

	/* SSL load static data & initialize common ctx context */
	if (!init_ssl_ctx()) {
		stop_check();
		return;
	}

	/* fill 'vsg' members of the virtual_server_t structure.
	 * We must do that after parsing config, because
	 * vs and vsg declarations may appear in any order
	 */
	link_vsg_to_vs();

	/* Processing differential configuration parsing */
	if (reload)
		clear_diff_services();

	/* Initialize IPVS topology */
	if (!init_services()) {
		stop_check();
		return;
	}

	/* Dump configuration */
	if (__test_bit(DUMP_CONF_BIT, &debug)) {
		dump_global_data(global_data);
		dump_check_data(check_data);
	}

#ifdef _WITH_VRRP_
	/* Initialize linkbeat */
	init_interface_linkbeat();
#endif

	/* Register checkers thread */
	register_checkers_thread();
}
Beispiel #10
0
int main(int argc, char *argv[])
{
    int lsfd;
    int ret, n, i;
    struct epoll_event event;
    struct epoll_event *events = NULL;
    connection_t *conn;
    connections_head_t *head = NULL;

    if (argc != 2) {
        fprintf(stdout, "Usage: %s [port]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* init connections cache */
    head = init_connections(MAX_CONNECTIONS);
    if (NULL == head) {
        ERROR_MSG("init_connections\n");
        goto error;
    }

    /* init SSL data */
    ret = init_OpenSSL();
    if (ret != 0) {
        ERROR_MSG("init_OpenSSL\n");
        goto error;
    }

    head->ctx = init_ssl_ctx(SRV_CERTFILE, SRV_PRIKEY, SRV_CAFILE);
    if (NULL == head->ctx) {
        ERROR_MSG("init_ssl_ctx error\n");
        goto error;
    }

    /* init epoll's data */
    head->epfd = epoll_create(MAX_CONNECTIONS);
    if (-1 == head->epfd) {
        ERROR_MSG("epoll_create\n");
        goto error;
    }

    events = calloc(MAX_EVENTS, sizeof(struct epoll_event));
    if (NULL == events) {
        ERROR_MSG("calloc\n");
        goto error;
    }

    /* listen's data */
    lsfd = start_listen(argv[1]);
    if (lsfd < 0) {
        ERROR_MSG("start_listen\n");
        goto error;
    }

    /* add the lsfd to events */
    conn = get_connection(head);
    if (NULL == conn) {
        ERROR_MSG("get_connection\n");
        goto error;
    }

    conn->fd = lsfd;
    conn->handler = accept_handler;

    event.data.ptr = conn;
    event.events = EPOLLIN | EPOLLET;
    ret = epoll_ctl(head->epfd, EPOLL_CTL_ADD, lsfd, &event);
    if (-1 == ret) {
        ERROR_MSG("epoll_ctl\n");
        goto error;
    }

    /* The event loop */
    while (1)
    {
        n = epoll_wait(head->epfd, events, MAX_EVENTS, -1);
        for (i = 0; i < n; ++i)
        {
            conn = events[i].data.ptr;

            if ((events[i].events & EPOLLERR)
                || (events[i].events & EPOLLHUP)
                || !(events[i].events & EPOLLIN))
            {
                /* it will delete the event from events at the same time 
                 * due to invoked close
                 */
                free_connection(head, conn);
            } else {
                if (conn->handler) {
                    conn->handler(head, conn);
                }
            }
        }
    }

error:
    if (events) free(events);
    destroy_connections(head);
    return EXIT_SUCCESS;
}
Beispiel #11
0
int main (int argc, char** argv)
try {
	init_signals();

	// Initialize OpenSSL
	ERR_load_crypto_strings();
	SSL_library_init();
	SSL_load_error_strings();

	// This cipher list is the "Intermediate compatibility" list from https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 as of 2014-12-09
	vhost_defaults.ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
	vhost_defaults.dhgroup = make_dh(dh_group14_prime, dh_group14_generator); // 2048 bit group
	vhost_defaults.ecdhcurve = get_ecdhcurve("prime256v1"); // a.k.a. secp256r1

	// Set default SSL options, which can be overridden by config file
	vhost_defaults.ssl_options[SSL_OP_NO_COMPRESSION] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_SSLv3] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1] = false;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1_1] = false;
	vhost_defaults.ssl_options[SSL_OP_NO_TLSv1_2] = false;
	vhost_defaults.ssl_options[SSL_OP_CIPHER_SERVER_PREFERENCE] = true;

	// These can't be overriden by config file:
	vhost_defaults.ssl_options[SSL_OP_SINGLE_DH_USE] = true;
	vhost_defaults.ssl_options[SSL_OP_SINGLE_ECDH_USE] = true;
	vhost_defaults.ssl_options[SSL_OP_NO_SSLv2] = true;

	// Command line arguments come in pairs of the form "--name value" and correspond
	// directly to the name/value option pairs in the config file (a la OpenVPN).
	for (int i = 1; i < argc; ) {
		if (std::strncmp(argv[i], "--", 2) == 0 && i + 1 < argc) {
			process_config_param(argv[i] + 2, argv[i+1]);
			i += 2;
		} else {
			std::clog << argv[0] << ": Bad arguments" << std::endl;
			return 2;
		}
	}

	if (vhost_configs.empty()) {
		// No vhosts specified, so add one implicitly that matches all local addresses / SNI names.
		// It will use the options from vhost_defaults.
		vhost_configs.emplace_back();
	}

	for (size_t i = 0; i < vhost_configs.size(); ++i) {
		vhosts.emplace_back();
		Vhost&		vhost(vhosts.back());
		Vhost_config&	config(vhost_configs[i]);

		vhost.id = i;
		vhost.servername_set = config.servername_set;
		vhost.servername = config.servername;
		init_ssl_ctx(vhost, config);
		resolve_addresses(vhost, config);
	}
	// Free up some memory that's no longer needed:
	vhost_configs.clear();
	vhost_defaults = Basic_vhost_config();

	// Listen
	listening_sock = socket(AF_INET6, SOCK_STREAM, 0);
	if (listening_sock == -1) {
		throw System_error("socket", "", errno);
	}
	set_reuseaddr(listening_sock);
	set_not_v6only(listening_sock);
	if (transparent == TRANSPARENT_ON) {
		set_transparent(listening_sock);
	}

	// TODO: support binding to specific IP addresses
	struct sockaddr_in6	listening_address;
	std::memset(&listening_address, '\0', sizeof(listening_address));
	listening_address.sin6_family = AF_INET6;
	listening_address.sin6_addr = in6addr_any;
	listening_address.sin6_port = htons(listening_port);
	if (bind(listening_sock, reinterpret_cast<const struct sockaddr*>(&listening_address), sizeof(listening_address)) == -1) {
		throw System_error("bind", "", errno);
	}

	if (listen(listening_sock, SOMAXCONN) == -1) {
		throw System_error("listen", "", errno);
	}

	// Set up UNIX domain socket for communicating with the key server.
	// Put it in a temporary directory with restrictive permissions so
	// other users can't traverse its path.  We have to use a named
	// socket as opposed to a socketpair because we need every child process
	// to communicate with the key server using its own socket.  (Duping one
	// end of a socketpair wouldn't work because then every child would
	// be referring to the same underlying socket, which provides
	// insufficient isolation.)
	temp_directory = make_temp_directory();
	filedesc keyserver_sock(make_unix_socket(temp_directory + "/server.sock", &keyserver_sockaddr, &keyserver_sockaddr_len));
	if (listen(keyserver_sock, SOMAXCONN) == -1) {
		throw System_error("listen", "", errno);
	}

	// Write PID file, daemonize, etc.
	std::ofstream		pid_file_out;
	if (!pid_file.empty()) {
		// Open PID file before forking so we can report errors
		pid_file_out.open(pid_file.c_str(), std::ofstream::out | std::ofstream::trunc);
		if (!pid_file_out) {
			throw Configuration_error("Unable to open PID file " + pid_file + " for writing.");
		}
		pid_file_created = true;
	}
	if (run_as_daemon) {
		daemonize();
	}
	if (pid_file_out) {
		pid_file_out << getpid() << '\n';
		pid_file_out.close();
	}

	// Spawn the master key server process
	keyserver_pid = spawn(keyserver_main, std::move(keyserver_sock));

	// Spawn spare children to accept() and service connections
	if (pipe(children_pipe) == -1) {
		throw System_error("pipe", "", errno);
	}
	set_nonblocking(children_pipe[0], true);

	spawn_children();

	// Wait for signals and readability on children_pipe
	sigset_t		empty_sigset;
	sigemptyset(&empty_sigset);
	fd_set			readfds;
	FD_ZERO(&readfds);
	FD_SET(children_pipe[0], &readfds);

	is_running = 1;
	struct timespec		timeout = { 2, 0 };
	int			select_res = 0;
	while (is_running && ((select_res = pselect(children_pipe[0] + 1, &readfds, NULL, NULL, failed_children ? &timeout : NULL, &empty_sigset)) >= 0 || errno == EINTR)) {
		if (failed_children && std::time(NULL) >= last_failed_child_time + 2) {
			failed_children = 0;
		}
		if (pending_sigchld) {
			on_sigchld();
			pending_sigchld = 0;
		}
		if (select_res > 0) {
			read_children_pipe();
		}
		FD_SET(children_pipe[0], &readfds);
	}

	if (is_running && select_res == -1) {
		throw System_error("pselect", "", errno);
	}


	cleanup();
	return 0;
} catch (const System_error& error) {
	std::clog << "titus: System error: " << error.syscall;
	if (!error.target.empty()) {
		std::clog << ": " << error.target;
	}
	std::clog << ": " << std::strerror(error.number) << std::endl;
	cleanup();
	return 3;
} catch (const Openssl_error& error) {
	std::clog << "titus: OpenSSL error: " << error.message() << std::endl;
	cleanup();
	return 4;
} catch (const Configuration_error& error) {
	std::clog << "titus: Configuration error: " << error.message << std::endl;
	cleanup();
	return 5;
} catch (const Too_many_failed_children& error) {
	// TODO: better error reporting when this happens
	std::clog << "titus: Too many child processes failed." << std::endl;
	cleanup();
	return 7;
} catch (const Keyserver_died& error) {
	// TODO: better error reporting when this happens
	std::clog << "titus: Key server died." << std::endl;
	cleanup();
	return 8;
}
/**
 * @brief openvassd.
 * @param argc Argument count.
 * @param argv Argument vector.
 */
int
main (int argc, char *argv[])
{
  int exit_early = 0, scanner_port = 9391;
  pid_t handler_pid;
  char *myself;
  struct arglist *options = emalloc (sizeof (struct arglist));
  struct addrinfo *mysaddr;
  struct addrinfo hints;
  struct addrinfo ai;
  struct sockaddr_in saddr;
  struct sockaddr_in6 s6addr;

  proctitle_init (argc, argv);
  gcrypt_init ();

  if ((myself = strrchr (*argv, '/')) == 0)
    myself = *argv;
  else
    myself++;

  static gboolean display_version = FALSE;
  static gboolean dont_fork = FALSE;
  static gchar *address = NULL;
  static gchar *port = NULL;
  static gchar *config_file = NULL;
  static gchar *gnutls_priorities = "NORMAL";
  static gchar *dh_params = NULL;
  static gboolean print_specs = FALSE;
  static gboolean print_sysconfdir = FALSE;
  static gboolean only_cache = FALSE;
  GError *error = NULL;
  GOptionContext *option_context;
  static GOptionEntry entries[] = {
    {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
     "Display version information", NULL},
    {"foreground", 'f', 0, G_OPTION_ARG_NONE, &dont_fork,
     "Do not run in daemon mode but stay in foreground", NULL},
    {"listen", 'a', 0, G_OPTION_ARG_STRING, &address,
     "Listen on <address>", "<address>"},
    {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
     "Use port number <number>", "<number>"},
    {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
     "Configuration file", "<.rcfile>"},
    {"cfg-specs", 's', 0, G_OPTION_ARG_NONE, &print_specs,
     "Print configuration settings", NULL},
    {"sysconfdir", 'y', 0, G_OPTION_ARG_NONE, &print_sysconfdir,
     "Print system configuration directory (set at compile time)", NULL},
    {"only-cache", 'C', 0, G_OPTION_ARG_NONE, &only_cache,
     "Exit once the NVT cache has been initialized or updated", NULL},
    {"gnutls-priorities", '\0', 0, G_OPTION_ARG_STRING, &gnutls_priorities,
     "GnuTLS priorities string", "<string>"},
    {"dh-params", '\0', 0, G_OPTION_ARG_STRING, &dh_params,
     "Diffie-Hellman parameters file", "<string>"},
    {NULL}
  };

  option_context =
    g_option_context_new ("- Scanner of the Open Vulnerability Assessment System");
  g_option_context_add_main_entries (option_context, entries, NULL);
  if (!g_option_context_parse (option_context, &argc, &argv, &error))
    {
      g_print ("%s\n\n", error->message);
      exit (0);
    }
  g_option_context_free (option_context);

  if (print_sysconfdir)
    {
      g_print ("%s\n", SYSCONFDIR);
      exit (0);
    }

  /* Switch to UTC so that OTP times are always in UTC. */
  if (setenv ("TZ", "utc 0", 1) == -1)
    {
      g_print ("%s\n\n", strerror (errno));
      exit (0);
    }
  tzset ();

  if (print_specs)
    exit_early = 2;           /* no cipher initialization */

  if (address != NULL)
    {
      memset (&hints, 0, sizeof (hints));
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
      hints.ai_flags = AI_NUMERICHOST;
      if (getaddrinfo (address, NULL, &hints, &mysaddr))
        {
          printf ("Invalid IP address.\n");
          printf ("Please use %s --help for more information.\n", myself);
          exit (0);
        }
      /* deep copy */
      ai.ai_family = mysaddr->ai_family;
      if (ai.ai_family == AF_INET)
        {
          memcpy (&saddr, mysaddr->ai_addr, mysaddr->ai_addrlen);
          ai.ai_addr = (struct sockaddr *) &saddr;
        }
      else
        {
          memcpy (&s6addr, mysaddr->ai_addr, mysaddr->ai_addrlen);
          ai.ai_addr = (struct sockaddr *) &s6addr;
        }
      ai.ai_family = mysaddr->ai_family;
      ai.ai_protocol = mysaddr->ai_protocol;
      ai.ai_socktype = mysaddr->ai_socktype;
      ai.ai_addrlen = mysaddr->ai_addrlen;
      freeaddrinfo (mysaddr);
    }
  else
    {
      /* Default to IPv4 */
      /*Warning: Not filling all the fields */
      saddr.sin_addr.s_addr = INADDR_ANY;
      saddr.sin_family = ai.ai_family = AF_INET;
      ai.ai_addrlen = sizeof (saddr);
      ai.ai_addr = (struct sockaddr *) &saddr;
    }

  if (port != NULL)
    {
      scanner_port = atoi (port);
      if ((scanner_port <= 0) || (scanner_port >= 65536))
        {
          printf ("Invalid port specification.\n");
          printf ("Please use %s --help for more information.\n", myself);
          exit (1);
        }
    }

  if (display_version)
    {
      printf ("OpenVAS Scanner %s\n", OPENVASSD_VERSION);
      printf
        ("Nessus origin: (C) 2004 Renaud Deraison <*****@*****.**>\n");
      printf
        ("Most new code since OpenVAS: (C) 2013 Greenbone Networks GmbH\n");
      printf ("License GPLv2: GNU GPL version 2\n");
      printf
        ("This is free software: you are free to change and redistribute it.\n"
         "There is NO WARRANTY, to the extent permitted by law.\n\n");
      exit (0);
    }

  if (config_file != NULL)
    arg_add_value (options, "acc_hint", ARG_INT, sizeof (int), (void *) 1);

  if (!config_file)
    {
      config_file = emalloc (strlen (OPENVASSD_CONF) + 1);
      strncpy (config_file, OPENVASSD_CONF, strlen (OPENVASSD_CONF));
    }

  arg_add_value (options, "scanner_port", ARG_INT, sizeof (gpointer),
                 GSIZE_TO_POINTER (scanner_port));
  arg_add_value (options, "config_file", ARG_STRING, strlen (config_file),
                 config_file);
  arg_add_value (options, "addr", ARG_PTR, -1, &ai);

  if (only_cache)
    {
      init_openvassd (options, 0, 1, dont_fork);
      init_plugins (options);
      exit (0);
    }

  init_openvassd (options, 1, exit_early, dont_fork);
  g_options = options;
  global_iana_socket = GPOINTER_TO_SIZE (arg_get_value (options, "isck"));
  global_plugins = arg_get_value (options, "plugins");

  /* special treatment */
  if (print_specs)
    dump_cfg_specs (global_preferences);
  if (exit_early)
    exit (0);

  init_ssl_ctx (gnutls_priorities, dh_params);
  // Daemon mode:
  if (dont_fork == FALSE)
    set_daemon_mode ();
  pidfile_create ("openvassd");
  handler_pid = loading_handler_start ();
  init_plugins (options);
  loading_handler_stop (handler_pid);
  main_loop ();
  exit (0);
}