Author: mattm Date: 2016-09-21 12:44:51 +0200 (Wed, 21 Sep 2016) New Revision: 26243
Modified: trunk/openvas-manager/ChangeLog trunk/openvas-manager/src/manage.c trunk/openvas-manager/src/manage.h trunk/openvas-manager/src/manage_sql.c trunk/openvas-manager/src/omp.c trunk/openvas-manager/src/omp.h trunk/openvas-manager/src/ompd.c trunk/openvas-manager/src/ompd.h trunk/openvas-manager/src/openvasmd.c Log: Add option to server clients on UNIX socket instead of TLS. * src/manage.c (manage_schedule): Use connection instead of session. * src/manage_sql.c (escalate_2, init_manage): Use connection instead of session. * src/omp.c (init_omp): Use connection instead of session. * src/ompd.c (init_ompd): Use connection instead of session. (read_from_client_unix, read_from_client_tls): New functions. (read_from_client): Call through according to type. (write_to_client_unix, write_to_client_tls): New functions. (write_to_client): Call through according to type. (session_clean, serve_omp): Use connection instead of session. * src/manage.h, src/omp.h, src/ompd.h: Update headers accordingly. * src/openvasmd.c (use_tls): New variable. (serve_client, accept_and_maybe_fork, fork_connection_internal) (fork_connection_for_scheduler, fork_connection_for_event) (update_or_rebuild_nvt_cache): Use connection instead of socket. (manager_listen): Listen on TCP or UNIX, depending on args. (main): Add option --unix-socket. Modified: trunk/openvas-manager/ChangeLog =================================================================== --- trunk/openvas-manager/ChangeLog 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/ChangeLog 2016-09-21 10:44:51 UTC (rev 26243) @@ -1,3 +1,29 @@ +2016-09-14 Matthew Mundell <matthew.mund...@greenbone.net> + + Add option to server clients on UNIX socket instead of TLS. + + * src/manage.c (manage_schedule): Use connection instead of session. + + * src/manage_sql.c (escalate_2, init_manage): Use connection instead of session. + + * src/omp.c (init_omp): Use connection instead of session. + + * src/ompd.c (init_ompd): Use connection instead of session. + (read_from_client_unix, read_from_client_tls): New functions. + (read_from_client): Call through according to type. + (write_to_client_unix, write_to_client_tls): New functions. + (write_to_client): Call through according to type. + (session_clean, serve_omp): Use connection instead of session. + + * src/manage.h, src/omp.h, src/ompd.h: Update headers accordingly. + + * src/openvasmd.c (use_tls): New variable. + (serve_client, accept_and_maybe_fork, fork_connection_internal) + (fork_connection_for_scheduler, fork_connection_for_event) + (update_or_rebuild_nvt_cache): Use connection instead of socket. + (manager_listen): Listen on TCP or UNIX, depending on args. + (main): Add option --unix-socket. + 2016-09-21 Timo Pollmeier <timo.pollme...@greenbone.net> * src/manage_sql.c (task_average_scan_duration): New function. @@ -17,7 +43,7 @@ 2016-09-21 Christian Fischer <christian.fisc...@greenbone.net> - * INSTALL: Added apt-get install prerequisites + * INSTALL: Added apt-get install prerequisites 2016-09-20 Timo Pollmeier <timo.pollme...@greenbone.net> Modified: trunk/openvas-manager/src/manage.c =================================================================== --- trunk/openvas-manager/src/manage.c 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/manage.c 2016-09-21 10:44:51 UTC (rev 26243) @@ -6266,10 +6266,7 @@ * @return 0 success, 1 failed to get lock, -1 error. */ int -manage_schedule (int (*fork_connection) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), +manage_schedule (int (*fork_connection) (openvas_connection_t *, gchar *), gboolean run_tasks, sigset_t *sigmask_current) { @@ -6409,11 +6406,11 @@ while (starts) { - int socket, pid; - gnutls_session_t session; - gnutls_certificate_credentials_t credentials; + int pid; + openvas_connection_t connection; gchar *task_uuid, *owner, *owner_uuid; GSList *head; + omp_authenticate_info_opts_t auth_opts; owner = starts->data; assert (starts->next); @@ -6470,7 +6467,7 @@ /* Run the callback to fork a child connected to the Manager. */ - pid = fork_connection (&socket, &session, &credentials, owner_uuid); + pid = fork_connection (&connection, owner_uuid); switch (pid) { case 0: @@ -6590,30 +6587,32 @@ /* Start the task. */ - if (omp_authenticate (&session, owner, "")) + auth_opts = omp_authenticate_info_opts_defaults; + auth_opts.username = owner; + if (omp_authenticate_info_ext_c (&connection, auth_opts)) { g_warning ("%s: omp_authenticate failed", __FUNCTION__); g_free (task_uuid); g_free (owner); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } g_free (owner); - if (omp_resume_task_report (&session, task_uuid, NULL)) + if (omp_resume_task_report_c (&connection, task_uuid, NULL)) { - if (omp_start_task_report (&session, task_uuid, NULL)) + if (omp_start_task_report_c (&connection, task_uuid, NULL)) { g_warning ("%s: omp_start_task and omp_resume_task failed", __FUNCTION__); g_free (task_uuid); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } } g_free (task_uuid); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_SUCCESS); } @@ -6621,11 +6620,10 @@ while (stops) { - int socket; - gnutls_session_t session; - gnutls_certificate_credentials_t credentials; + openvas_connection_t connection; gchar *task_uuid, *owner, *owner_uuid; GSList *head; + omp_authenticate_info_opts_t auth_opts; owner = stops->data; assert (stops->next); @@ -6643,7 +6641,7 @@ /* Run the callback to fork a child connected to the Manager. */ - switch (fork_connection (&socket, &session, &credentials, owner_uuid)) + switch (fork_connection (&connection, owner_uuid)) { case 0: /* Child. Break, stop task, exit. */ @@ -6679,28 +6677,30 @@ /* Stop the task. */ - if (omp_authenticate (&session, owner, "")) + auth_opts = omp_authenticate_info_opts_defaults; + auth_opts.username = owner; + if (omp_authenticate_info_ext_c (&connection, auth_opts)) { g_free (task_uuid); g_free (owner); g_free (owner_uuid); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } - if (omp_stop_task (&session, task_uuid)) + if (omp_stop_task_c (&connection, task_uuid)) { g_free (task_uuid); g_free (owner); g_free (owner_uuid); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } g_free (task_uuid); g_free (owner); g_free (owner_uuid); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_SUCCESS); } Modified: trunk/openvas-manager/src/manage.h =================================================================== --- trunk/openvas-manager/src/manage.h 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/manage.h 2016-09-21 10:44:51 UTC (rev 26243) @@ -39,6 +39,7 @@ #include <openvas/base/nvti.h> /* for nvti_t */ #include <openvas/base/openvas_networking.h> #include <openvas/osp/osp.h> +#include <openvas/misc/openvas_server.h> /** * @brief Flag with all Glib log levels. @@ -66,9 +67,8 @@ } name_value_t; int -init_manage (GSList*, int, const gchar*, int, int, int, void (*) (), - int (*) (int *, gnutls_session_t *, - gnutls_certificate_credentials_t *, gchar*), +init_manage (GSList*, int, const gchar *, int, int, int, void (*) (), + int (*) (openvas_connection_t *, gchar *), int); int @@ -2746,12 +2746,9 @@ set_scheduled_user_uuid (gchar* uuid); int -manage_schedule (int (*) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), +manage_schedule (int (*) (openvas_connection_t *, gchar *), gboolean, - sigset_t *sigmask_current); + sigset_t *); char * schedule_uuid (schedule_t); Modified: trunk/openvas-manager/src/manage_sql.c =================================================================== --- trunk/openvas-manager/src/manage_sql.c 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/manage_sql.c 2016-09-21 10:44:51 UTC (rev 26243) @@ -338,11 +338,7 @@ /** * @brief Function to fork a connection that will accept OMP requests. */ -int (*manage_fork_connection) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*) - = NULL; +int (*manage_fork_connection) (openvas_connection_t *, gchar*) = NULL; /** * @brief Function to mark progress. @@ -11663,10 +11659,9 @@ } case ALERT_METHOD_START_TASK: { - int socket; - gnutls_session_t session; - gnutls_certificate_credentials_t credentials; + openvas_connection_t connection; char *task_id, *report_id; + omp_authenticate_info_opts_t auth_opts; if (event == EVENT_NEW_SECINFO || event == EVENT_UPDATED_SECINFO) { @@ -11687,8 +11682,7 @@ task_id = alert_data (alert, "method", "start_task_task"); - switch (manage_fork_connection (&socket, &session, &credentials, - current_credentials.uuid)) + switch (manage_fork_connection (&connection, current_credentials.uuid)) { case 0: /* Child. Break, stop task, exit. */ @@ -11710,22 +11704,24 @@ /* Start the task. */ - if (omp_authenticate (&session, current_credentials.username, "")) + auth_opts = omp_authenticate_info_opts_defaults; + auth_opts.username = current_credentials.username; + if (omp_authenticate_info_ext_c (&connection, auth_opts)) { - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } - if (omp_start_task_report (&session, task_id, &report_id)) + if (omp_start_task_report_c (&connection, task_id, &report_id)) { g_free (task_id); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_FAILURE); } g_free (task_id); g_free (report_id); - openvas_server_free (socket, session, credentials); + openvas_connection_free (&connection); exit (EXIT_SUCCESS); } case ALERT_METHOD_ERROR: @@ -15545,10 +15541,7 @@ void (*update_progress) (), int stop_tasks, int (*fork_connection) - (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), + (openvas_connection_t *, gchar *), int skip_db_check, int check_encryption_key) { @@ -15684,10 +15677,7 @@ init_manage (GSList *log_config, int nvt_cache_mode, const gchar *database, int max_ips_per_target, int max_email_attachment_size, int max_email_include_size, void (*update_progress) (), - int (*fork_connection) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), + int (*fork_connection) (openvas_connection_t*, gchar*), int skip_db_check) { return init_manage_internal (log_config, Modified: trunk/openvas-manager/src/omp.c =================================================================== --- trunk/openvas-manager/src/omp.c 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/omp.c 2016-09-21 10:44:51 UTC (rev 26243) @@ -31276,10 +31276,7 @@ init_omp (GSList *log_config, int nvt_cache_mode, const gchar *database, int max_ips_per_target, int max_email_attachment_size, int max_email_include_size, void (*progress) (), - int (*fork_connection) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), + int (*fork_connection) (openvas_connection_t *, gchar*), int skip_db_check) { g_log_set_handler (G_LOG_DOMAIN, Modified: trunk/openvas-manager/src/omp.h =================================================================== --- trunk/openvas-manager/src/omp.h 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/omp.h 2016-09-21 10:44:51 UTC (rev 26243) @@ -27,6 +27,7 @@ #define OPENVAS_MANAGER_OMP_H #include "types.h" +#include <openvas/misc/openvas_server.h> #include <glib.h> #include <gnutls/gnutls.h> #include <sys/types.h> @@ -38,8 +39,7 @@ int init_omp (GSList*, int, const gchar*, int, int, int, void (*) (), - int (*) (int *, gnutls_session_t *, - gnutls_certificate_credentials_t *, gchar*), + int (*) (openvas_connection_t *, gchar*), int); void Modified: trunk/openvas-manager/src/ompd.c =================================================================== --- trunk/openvas-manager/src/ompd.c 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/ompd.c 2016-09-21 10:44:51 UTC (rev 26243) @@ -116,10 +116,7 @@ init_ompd (GSList *log_config, int nvt_cache_mode, const gchar *database, int max_ips_per_target, int max_email_attachment_size, int max_email_include_size, void (*progress) (), - int (*fork_connection) (int *, - gnutls_session_t *, - gnutls_certificate_credentials_t *, - gchar*), + int (*fork_connection) (openvas_connection_t *, gchar*), int skip_db_check) { return init_omp (log_config, nvt_cache_mode, database, max_ips_per_target, @@ -145,15 +142,52 @@ /** * @brief Read as much from the client as the \ref from_client buffer will hold. * + * @param[in] client_socket The socket. + * + * @return 0 on reading everything available, -1 on error, -2 if + * from_client buffer is full or -3 on reaching end of file. + */ +static int +read_from_client_unix (int client_socket) +{ + while (from_client_end < from_buffer_size) + { + int count; + count = read (client_socket, + from_client + from_client_end, + from_buffer_size - from_client_end); + if (count < 0) + { + if (errno == EAGAIN) + /* Got everything available, return to `select'. */ + return 0; + if (errno == EINTR) + /* Interrupted, try read again. */ + continue; + g_warning ("%s: failed to read from client: %s\n", + __FUNCTION__, strerror (errno)); + return -1; + } + if (count == 0) + /* End of file. */ + return -3; + from_client_end += count; + } + + /* Buffer full. */ + return -2; +} + +/** + * @brief Read as much from the client as the \ref from_client buffer will hold. + * * @param[in] client_session The TLS session with the client. - * @param[in] client_socket The socket connected to the client. * * @return 0 on reading everything available, -1 on error, -2 if * from_client buffer is full or -3 on reaching end of file. */ static int -read_from_client (gnutls_session_t* client_session, - /* unused */ int client_socket) +read_from_client_tls (gnutls_session_t* client_session) { while (from_client_end < from_buffer_size) { @@ -198,6 +232,23 @@ return -2; } +/** + * @brief Read as much from the client as the \ref from_client buffer will hold. + * + * @param[in] client_session The TLS session with the client. + * @param[in] client_socket The socket connected to the client. + * + * @return 0 on reading everything available, -1 on error, -2 if + * from_client buffer is full or -3 on reaching end of file. + */ +static int +read_from_client (openvas_connection_t *client_connection) +{ + if (client_connection->tls) + return read_from_client_tls (&client_connection->session); + return read_from_client_unix (client_connection->socket); +} + /** @todo Move to openvas-libraries? */ /** * @brief Write as much as possible from \ref to_client to the client. @@ -207,7 +258,7 @@ * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted. */ static int -write_to_client (gnutls_session_t* client_session) +write_to_client_tls (gnutls_session_t* client_session) { while (to_client_start < to_client_end) { @@ -245,6 +296,63 @@ } /** + * @brief Write as much as possible from \ref to_client to the client. + * + * @param[in] client_socket The client socket. + * + * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted. + */ +static int +write_to_client_unix (int client_socket) +{ + while (to_client_start < to_client_end) + { + ssize_t count; + count = write (client_socket, + to_client + to_client_start, + to_client_end - to_client_start); + if (count < 0) + { + if (errno == EAGAIN) + /* Wrote as much as client would accept. */ + return -2; + if (errno == EINTR) + /* Interrupted, try write again. */ + continue; + g_warning ("%s: failed to write to client: %s\n", + __FUNCTION__, + strerror (errno)); + return -1; + } + logf ("=> client %.*s\n", + to_client_end - to_client_start, + to_client + to_client_start); + to_client_start += count; + g_debug ("=> client %u bytes\n", (unsigned int) count); + } + g_debug ("=> client done\n"); + to_client_start = to_client_end = 0; + + /* Wrote everything. */ + return 0; +} + +/** + * @brief Write as much as possible from \ref to_client to the client. + * + * @param[in] client_connection The client connection. + * + * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted. + */ +static int +write_to_client (openvas_connection_t *client_connection) +{ + if (client_connection->tls) + return write_to_client_tls (&client_connection->session); + return write_to_client_unix (client_connection->socket); +} + +/** * @brief Send a response message to the client. * * Queue a message in \ref to_client. @@ -306,18 +414,23 @@ return FALSE; } +/** + * @brief Clean session. + * + * @param[in] client_connection Connection. + */ static void -session_clean (gnutls_session_t *sess, gnutls_certificate_credentials_t *creds) +session_clean (openvas_connection_t *client_connection) { - if (sess && *sess) + if (client_connection->session) { - gnutls_deinit (*sess); - *sess = NULL; + gnutls_deinit (client_connection->session); + client_connection->session = NULL; } - if (creds && *creds) + if (client_connection->credentials) { - gnutls_certificate_free_credentials (*creds); - *creds = NULL; + gnutls_certificate_free_credentials (client_connection->credentials); + client_connection->credentials = NULL; } } @@ -345,9 +458,7 @@ * * If client_socket is 0 or less, then update the NVT cache and exit. * - * @param[in] client_session The TLS session with the client. - * @param[in] client_credentials The TSL client credentials. - * @param[in] client_socket The socket connected to the client, if any. + * @param[in] client_connection Connection. * @param[in] database Location of manage database. * @param[in] disable Commands to disable. * @param[in] progress Function to mark progress, or NULL. @@ -355,10 +466,8 @@ * @return 0 success, 1 scanner still loading, -1 error, -2 scanner has no cert. */ int -serve_omp (gnutls_session_t* client_session, - gnutls_certificate_credentials_t* client_credentials, - int client_socket, const gchar* database, gchar **disable, - void (*progress) ()) +serve_omp (openvas_connection_t *client_connection, const gchar *database, + gchar **disable, void (*progress) ()) { int nfds, scan_handler = 0, rc = 0; /* True if processing of the client input is waiting for space in the @@ -366,10 +475,10 @@ short client_input_stalled; /* Client status flag. Set to 0 when the client closes the connection * while the scanner is active. */ - short client_active = client_socket > 0; + short client_active = client_connection->socket > 0; - if (client_socket < 0) - ompd_nvt_cache_mode = client_socket; + if (client_connection->socket < 0) + ompd_nvt_cache_mode = client_connection->socket; if (ompd_nvt_cache_mode) g_info (" Updating NVT cache.\n"); @@ -380,7 +489,7 @@ init_omp_process (ompd_nvt_cache_mode, database, (int (*) (const char*, void*)) ompd_send_to_client, - (void*) client_session, + (void*) client_connection, disable); #if 0 /** @todo Consider free_omp_data (); on return. */ @@ -443,7 +552,7 @@ * to_scanner buffer filling up (during initialisation). */ - nfds = openvas_scanner_get_nfds (client_socket); + nfds = openvas_scanner_get_nfds (client_connection->socket); while (1) { int ret; @@ -462,10 +571,10 @@ { /* See whether to read from the client. */ if (from_client_end < from_buffer_size) - FD_SET (client_socket, &readfds); + FD_SET (client_connection->socket, &readfds); /* See whether to write to the client. */ if (to_client_start < to_client_end) - FD_SET (client_socket, &writefds); + FD_SET (client_connection->socket, &writefds); } /* See whether we need to read from the scannner. */ @@ -498,13 +607,15 @@ * exhibit a problem in OpenVAS due to a different buffering * strategy. */ ret = 0; - if (client_socket > 0 && FD_ISSET (client_socket, &readfds) - && gnutls_record_check_pending (*client_session)) + if (client_connection->socket > 0 + && client_connection->tls + && FD_ISSET (client_connection->socket, &readfds) + && gnutls_record_check_pending (client_connection->session)) { FD_ZERO (&readfds); FD_ZERO (&writefds); ret++; - FD_SET (client_socket, &readfds); + FD_SET (client_connection->socket, &readfds); } if (openvas_scanner_fd_isset (&readfds)) { @@ -555,11 +666,12 @@ } /* Read any data from the client. */ - if (client_socket > 0 && FD_ISSET (client_socket, &readfds)) + if (client_connection->socket > 0 + && FD_ISSET (client_connection->socket, &readfds)) { buffer_size_t initial_start = from_client_end; - switch (read_from_client (client_session, client_socket)) + switch (read_from_client (client_connection)) { case 0: /* Read everything. */ break; @@ -604,7 +716,7 @@ * without closing it, for usage by the child process. */ set_scanner_init_state (SCANNER_INIT_TOP); openvas_scanner_free (); - nfds = openvas_scanner_get_nfds (client_socket); + nfds = openvas_scanner_get_nfds (client_connection->socket); client_input_stalled = 0; /* Skip the rest of the loop because the scanner socket is * a new socket. This is asking for select trouble, really. */ @@ -616,7 +728,7 @@ * successfully started the task. Close the client * connection, as the parent process has continued the * session with the client. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); client_active = 0; client_input_stalled = 0; scan_handler = 1; @@ -627,14 +739,14 @@ * successfully completed. Close the client connection, * and exit, as the parent process has continued the * session with the client. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); return 0; } else if (ret == -10) { /* Now in a process forked to run a task, which has * failed in starting the task. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); return -1; } else if (ret == -1 || ret == -4) @@ -642,7 +754,7 @@ /* Error. Write rest of to_client to client, so that the * client gets any buffered output and the response to the * error. */ - write_to_client (client_session); + write_to_client (client_connection); rc = -1; goto client_free; } @@ -724,11 +836,12 @@ } /* Write any data to the client. */ - if (client_socket > 0 && FD_ISSET (client_socket, &writefds)) + if (client_connection->socket > 0 + && FD_ISSET (client_connection->socket, &writefds)) { /* Write as much as possible to the client. */ - switch (write_to_client (client_session)) + switch (write_to_client (client_connection)) { case 0: /* Wrote everything in to_client. */ break; @@ -757,7 +870,7 @@ * without closing it, for usage by the child process. */ openvas_scanner_free (); set_scanner_init_state (SCANNER_INIT_TOP); - nfds = openvas_scanner_get_nfds (client_socket); + nfds = openvas_scanner_get_nfds (client_connection->socket); /* Skip the rest of the loop because the scanner socket is * a new socket. This is asking for select trouble, really. */ continue; @@ -768,7 +881,7 @@ * successfully started the task. Close the client * connection, as the parent process has continued the * session with the client. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); scan_handler = 1; client_active = 0; } @@ -778,14 +891,14 @@ * successfully completed. Close the client connection, * and exit, as the parent process has continued the * session with the client. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); return 0; } else if (ret == -10) { /* Now in a process forked to run a task, which has * failed in starting the task. */ - session_clean (client_session, client_credentials); + session_clean (client_connection); return -1; } else if (ret == -1) @@ -793,7 +906,7 @@ /* Error. Write rest of to_client to client, so that the * client gets any buffered output and the response to the * error. */ - write_to_client (client_session); + write_to_client (client_connection); rc = -1; goto client_free; } @@ -833,7 +946,7 @@ if (client_active == 0) return 0; openvas_scanner_free (); - nfds = openvas_scanner_get_nfds (client_socket); + nfds = openvas_scanner_get_nfds (client_connection->socket); } else if (ret == 2) { @@ -874,8 +987,6 @@ client_free: if (client_active) - openvas_server_free (client_socket, - *client_session, - *client_credentials); + openvas_connection_free (client_connection); return rc; } Modified: trunk/openvas-manager/src/ompd.h =================================================================== --- trunk/openvas-manager/src/ompd.h 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/ompd.h 2016-09-21 10:44:51 UTC (rev 26243) @@ -27,6 +27,7 @@ #define OPENVAS_MANAGER_OMPD_H #include "types.h" +#include <openvas/misc/openvas_server.h> #include <glib.h> #include <netinet/in.h> #include <gnutls/gnutls.h> @@ -56,16 +57,14 @@ int init_ompd (GSList*, int, const gchar*, int, int, int, void (*) (), - int (*) (int *, gnutls_session_t *, - gnutls_certificate_credentials_t *, gchar*), + int (*) (openvas_connection_t *, gchar *), int); void init_ompd_process (const gchar *, gchar **); int -serve_omp (gnutls_session_t*, gnutls_certificate_credentials_t*, - int, const gchar*, gchar**, void (*progress) ()); +serve_omp (openvas_connection_t*, const gchar*, gchar**, void (*progress) ()); /** @todo Temporarily declared here, for omp.c SEND_TO_CLIENT. */ extern char to_client[]; Modified: trunk/openvas-manager/src/openvasmd.c =================================================================== --- trunk/openvas-manager/src/openvasmd.c 2016-09-21 10:28:41 UTC (rev 26242) +++ trunk/openvas-manager/src/openvasmd.c 2016-09-21 10:44:51 UTC (rev 26243) @@ -93,6 +93,7 @@ #include <string.h> #include <sys/select.h> #include <sys/socket.h> +#include <sys/un.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> @@ -215,6 +216,11 @@ #endif /** + * @brief Whether to use TLS for client connections. + */ +int use_tls = 0; + +/** * @brief The client session. */ gnutls_session_t client_session; @@ -327,7 +333,7 @@ * @return EXIT_SUCCESS on success, EXIT_FAILURE on failure. */ int -serve_client (int server_socket, int client_socket) +serve_client (int server_socket, openvas_connection_t *client_connection) { if (server_socket > 0) { @@ -345,17 +351,18 @@ } } - if (openvas_server_attach (client_socket, &client_session)) + if (client_connection->tls + && openvas_server_attach (client_connection->socket, &client_session)) { g_debug ("%s: failed to attach client session to socket %i\n", __FUNCTION__, - client_socket); + client_connection->socket); goto fail; } /* The socket must have O_NONBLOCK set, in case an "asynchronous network * error" removes the data between `select' and `read'. */ - if (fcntl (client_socket, F_SETFL, O_NONBLOCK) == -1) + if (fcntl (client_connection->socket, F_SETFL, O_NONBLOCK) == -1) { g_warning ("%s: failed to set real client socket flag: %s\n", __FUNCTION__, @@ -366,15 +373,12 @@ /* Serve OMP. */ /* It's up to serve_omp to openvas_server_free client_*. */ - if (serve_omp (&client_session, &client_credentials, client_socket, database, - disabled_commands, NULL)) + if (serve_omp (client_connection, database, disabled_commands, NULL)) goto server_fail; return EXIT_SUCCESS; fail: - openvas_server_free (client_socket, - client_session, - client_credentials); + openvas_connection_free (client_connection); server_fail: return EXIT_FAILURE; } @@ -422,6 +426,7 @@ { int ret; struct sigaction action; + openvas_connection_t client_connection; is_parent = 0; @@ -455,7 +460,11 @@ } /* Reopen the database (required after fork). */ cleanup_manage_process (FALSE); - ret = serve_client (server_socket, client_socket); + client_connection.tls = use_tls; + client_connection.socket = client_socket; + client_connection.session = client_session; + client_connection.credentials = client_credentials; + ret = serve_client (server_socket, &client_connection); /** @todo This should be done through libomp. */ save_tasks (); exit (ret); @@ -480,20 +489,14 @@ /** * @brief Fork a child connected to the Manager. * - * @param[in] client_socket Client socket. - * @param[in] client_session_arg Client session. - * @param[in] client_credentials_arg Client credentials. + * @param[in] client_connection Client connection. * @param[in] uuid UUID of schedule user. * @param[in] scheduler Whether this is for the scheduler. * * @return PID parent on success, 0 child on success, -1 error. */ static int -fork_connection_internal (int *client_socket, - gnutls_session_t *client_session_arg, - gnutls_certificate_credentials_t - *client_credentials_arg, - gchar* uuid, +fork_connection_internal (openvas_connection_t *client_connection, gchar* uuid, int scheduler) { int pid, parent_client_socket, ret; @@ -586,31 +589,38 @@ manage_auth_allow_all (scheduler); set_scheduled_user_uuid (uuid); - /* Create a new session, because the parent may have been in the middle - * of using the old one. */ + /* For TLS, create a new session, because the parent may have been in + * the middle of using the old one. */ - if (openvas_server_new (GNUTLS_SERVER, - CACERT, - SCANNERCERT, - SCANNERKEY, - &client_session, - &client_credentials)) + if (use_tls) { - g_critical ("%s: client server initialisation failed\n", - __FUNCTION__); - exit (EXIT_FAILURE); + if (openvas_server_new (GNUTLS_SERVER, + CACERT, + SCANNERCERT, + SCANNERKEY, + &client_session, + &client_credentials)) + { + g_critical ("%s: client server initialisation failed\n", + __FUNCTION__); + exit (EXIT_FAILURE); + } + set_gnutls_priority (&client_session, priorities_option); + if (dh_params_option + && set_gnutls_dhparams (client_credentials, dh_params_option)) + g_warning ("Couldn't set DH parameters from %s\n", dh_params_option); } - set_gnutls_priority (&client_session, priorities_option); - if (dh_params_option - && set_gnutls_dhparams (client_credentials, dh_params_option)) - g_warning ("Couldn't set DH parameters from %s\n", dh_params_option); /* Serve client. */ g_debug ("%s: serving OMP to client on socket %i", __FUNCTION__, parent_client_socket); - ret = serve_client (manager_socket, parent_client_socket); + client_connection->tls = use_tls; + client_connection->socket = parent_client_socket; + client_connection->session = client_session; + client_connection->credentials = client_credentials; + ret = serve_client (manager_socket, client_connection); /** @todo This should be done through libomp. */ save_tasks (); @@ -636,21 +646,26 @@ /** @todo Give the parent time to prepare. */ openvas_sleep (5); - *client_socket = sockets[1]; + client_connection->tls = use_tls; + client_connection->socket = sockets[1]; - if (openvas_server_new (GNUTLS_CLIENT, - CACERT, - SCANNERCERT, - SCANNERKEY, - client_session_arg, - client_credentials_arg)) - exit (EXIT_FAILURE); + if (use_tls) + { + if (openvas_server_new (GNUTLS_CLIENT, + CACERT, + SCANNERCERT, + SCANNERKEY, + &client_connection->session, + &client_connection->credentials)) + exit (EXIT_FAILURE); - if (openvas_server_attach (*client_socket, client_session_arg)) - exit (EXIT_FAILURE); + if (openvas_server_attach (client_connection->socket, + &client_connection->session)) + exit (EXIT_FAILURE); + } g_debug ("%s: all set to request OMP on socket %i", - __FUNCTION__, *client_socket); + __FUNCTION__, client_connection->socket); return 0; break; @@ -663,22 +678,15 @@ /** * @brief Fork a child connected to the Manager. * - * @param[in] client_socket Client socket. - * @param[in] client_session Client session. - * @param[in] client_credentials Client credentials. + * @param[in] client_connection Client connection. * @param[in] uuid UUID of schedule user. * * @return PID parent on success, 0 child on success, -1 error. */ static int -fork_connection_for_scheduler (int *client_socket, - gnutls_session_t *client_session, - gnutls_certificate_credentials_t - *client_credentials, - gchar* uuid) +fork_connection_for_scheduler (openvas_connection_t *client_connection, gchar* uuid) { - return fork_connection_internal (client_socket, client_session, - client_credentials, uuid, 1); + return fork_connection_internal (client_connection, uuid, 1); } /** @@ -692,14 +700,9 @@ * @return PID parent on success, 0 child on success, -1 error. */ static int -fork_connection_for_event (int *client_socket, - gnutls_session_t *client_session, - gnutls_certificate_credentials_t - *client_credentials, - gchar* uuid) +fork_connection_for_event (openvas_connection_t *client_connection, gchar* uuid) { - return fork_connection_internal (client_socket, client_session, - client_credentials, uuid, 0); + return fork_connection_internal (client_connection, uuid, 0); } @@ -965,6 +968,7 @@ void (*progress) (), int skip_create_tables) { int ret; + openvas_connection_t connection; /* Initialise OMP daemon. */ @@ -1029,8 +1033,8 @@ * value. This invokes a scanner-only manager loop which will * request and cache the plugins, then exit. */ - ret = serve_omp (NULL, NULL, update_nvt_cache ? -1 : -2, database, NULL, - progress); + connection.socket = update_nvt_cache ? -1 : -2; + ret = serve_omp (&connection, database, NULL, progress); openvas_scanner_close (); switch (ret) { @@ -1317,65 +1321,131 @@ /** * @brief Set a socket to listen for connections. * - * @param[in] address_str IP or hostname to bind to. - * @param[in] port_str Port to bind to. - * @param[out] socket Socket listened on. + * @param[in] address_str_unix IP or hostname to bind to. NULL for TLS. + * @param[in] address_str_tls IP or hostname to bind to. + * @param[in] port_str Port to bind to, for TLS. + * @param[out] socket Socket listened on. + * + * @return 0 success, -1 error. */ static int -manager_listen (const char *address_str, const char *port_str, int *soc) +manager_listen (const char *address_str_unix, const char *address_str_tls, + const char *port_str, int *soc) { - struct sockaddr_storage address; - struct sockaddr_in *addr4 = (struct sockaddr_in *) &address; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &address; - int port, optval; + struct sockaddr *address; + struct sockaddr_un address_unix; + struct sockaddr_storage address_tls; + int address_size; - if (!address_str) - return 0; - if (port_str) + memset (&address_tls, 0, sizeof (struct sockaddr_storage)); + memset (&address_unix, 0, sizeof (struct sockaddr_un)); + + g_debug ("%s: address_str_unix: %s\n", __FUNCTION__, address_str_unix); + if (address_str_unix) { - port = atoi (port_str); - if (port <= 0 || port >= 65536) + struct stat state; + + /* UNIX file socket. */ + + //address.ss_family = AF_UNIX; + + address_unix.sun_family = AF_UNIX; + strncpy (address_unix.sun_path, + address_str_unix, + sizeof (address_unix.sun_path) - 1); + + g_debug ("%s: address_unix.sun_path: %s\n", + __FUNCTION__, + address_unix.sun_path); + + *soc = socket (AF_UNIX, SOCK_STREAM, 0); + if (*soc == -1) { - g_warning ("Manager port must be a number between 1 and 65535"); - log_config_free (); + g_warning ("Failed to create manager socket (UNIX): %s", + strerror (errno)); return -1; } - port = htons (port); + + if (stat (address_unix.sun_path, &state) == 0) + { + /* Remove socket so we can bind(). */ + unlink (address_unix.sun_path); + } + + address = (struct sockaddr *) &address_unix; + address_size = sizeof (address_unix); } - else + else if (address_str_tls) { - struct servent *servent = getservbyname ("otp", "tcp"); - if (servent) - port = servent->s_port; + struct sockaddr_in *addr4; + struct sockaddr_in6 *addr6; + int port, optval; + + /* TLS TCP socket. */ + + if (port_str) + { + port = atoi (port_str); + if (port <= 0 || port >= 65536) + { + g_warning ("Manager port must be a number between 1 and 65535"); + log_config_free (); + return -1; + } + port = htons (port); + } else - port = htons (OPENVASMD_PORT); - } + { + struct servent *servent = getservbyname ("otp", "tcp"); + if (servent) + port = servent->s_port; + else + port = htons (OPENVASMD_PORT); + } - if (inet_pton (AF_INET6, address_str, &addr6->sin6_addr) > 0) - { - address.ss_family = AF_INET6; - addr6->sin6_port = port; + addr4 = (struct sockaddr_in *) &address_tls; + addr6 = (struct sockaddr_in6 *) &address_tls; + if (inet_pton (AF_INET6, address_str_tls, &addr6->sin6_addr) > 0) + { + address_tls.ss_family = AF_INET6; + addr6->sin6_port = port; + } + else if (inet_pton (AF_INET, address_str_tls, &addr4->sin_addr) > 0) + { + address_tls.ss_family = AF_INET; + addr4->sin_port = port; + } + else + { + g_warning ("Failed to create manager address %s", address_str_tls); + return -1; + } + + if (address_tls.ss_family == AF_INET6) + *soc = socket (PF_INET6, SOCK_STREAM, 0); + else + *soc = socket (PF_INET, SOCK_STREAM, 0); + if (*soc == -1) + { + g_warning ("Failed to create manager socket (TLS): %s", + strerror (errno)); + return -1; + } + + optval = 1; + if (setsockopt (*soc, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int))) + { + g_warning ("Failed to set SO_REUSEADDR on socket: %s", + strerror (errno)); + return -1; + } + + address = (struct sockaddr *) &address_tls; + address_size = sizeof (address_tls); } - else if (inet_pton (AF_INET, address_str, &addr4->sin_addr) > 0) - { - address.ss_family = AF_INET; - addr4->sin_port = port; - } else - { - g_warning ("Failed to create manager address %s", address_str); - return -1; - } + return 0; - if (address.ss_family == AF_INET6) - *soc = socket (PF_INET6, SOCK_STREAM, 0); - else - *soc = socket (PF_INET, SOCK_STREAM, 0); - if (manager_socket == -1) - { - g_warning ("Failed to create manager socket: %s", strerror (errno)); - return -1; - } /* The socket must have O_NONBLOCK set, in case an "asynchronous network * error" removes the connection between `select' and `accept'. */ if (fcntl (*soc, F_SETFL, O_NONBLOCK) == -1) @@ -1384,19 +1454,14 @@ return -1; } - optval = 1; - if (setsockopt (*soc, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int))) + if (bind (*soc, address, address_size) == -1) { - g_warning ("Failed to set SO_REUSEADDR on socket: %s", strerror (errno)); + g_warning ("Failed to bind manager socket: %s", strerror (errno)); return -1; } - if (bind (*soc, (struct sockaddr *) &address, sizeof (address)) - == -1) - { - g_warning ("Failed to bind manager socket: %s", strerror (errno)); - return -1; - } + // FIX owner,mode for unix + if (listen (*soc, MAX_CONNECTIONS) == -1) { g_warning ("Failed to listen on manager socket: %s", strerror (errno)); @@ -1465,6 +1530,7 @@ static gchar *optimize = NULL; static gchar *manager_address_string = NULL; static gchar *manager_address_string_2 = NULL; + static gchar *manager_address_string_unix = NULL; static gchar *manager_port_string = NULL; static gchar *manager_port_string_2 = NULL; static gchar *modify_setting = NULL; @@ -1540,6 +1606,7 @@ { "rebuild", '\0', 0, G_OPTION_ARG_NONE, &rebuild_nvt_cache, "Rebuild the NVT cache and exit.", NULL }, { "role", '\0', 0, G_OPTION_ARG_STRING, &role, "Role for --create-user and --get-users.", "<role>" }, { "update", 'u', 0, G_OPTION_ARG_NONE, &update_nvt_cache, "Update the NVT cache and exit.", NULL }, + { "unix-socket", 'c', 0, G_OPTION_ARG_STRING, &manager_address_string_unix, "Listen on UNIX socket at <filename>.", "<filename>" }, { "user", '\0', 0, G_OPTION_ARG_STRING, &user, "User for --new-password.", "<username>" }, { "gnutls-priorities", '\0', 0, G_OPTION_ARG_STRING, &priorities, "Sets the GnuTLS priorities for the Manager socket.", "<priorities-string>" }, { "dh-params", '\0', 0, G_OPTION_ARG_STRING, &dh_params, "Diffie-Hellman parameters file", "<file>" }, @@ -1574,6 +1641,11 @@ exit (EXIT_SUCCESS); } + if (manager_address_string_unix == NULL) + use_tls = 1; + else + use_tls = 0; + /* Set process title. */ proctitle_init (argc, argv); proctitle_set ("openvasmd: Initializing."); @@ -2068,31 +2140,44 @@ /* Setup security. */ - if (openvas_server_new (GNUTLS_SERVER, - CACERT, - SCANNERCERT, - SCANNERKEY, - &client_session, - &client_credentials)) + if (use_tls) { - g_critical ("%s: client server initialisation failed\n", - __FUNCTION__); - exit (EXIT_FAILURE); + if (openvas_server_new (GNUTLS_SERVER, + CACERT, + SCANNERCERT, + SCANNERKEY, + &client_session, + &client_credentials)) + { + g_critical ("%s: client server initialisation failed\n", + __FUNCTION__); + exit (EXIT_FAILURE); + } + priorities_option = priorities; + set_gnutls_priority (&client_session, priorities); + dh_params_option = dh_params; + if (dh_params && set_gnutls_dhparams (client_credentials, dh_params)) + g_warning ("Couldn't set DH parameters from %s\n", dh_params); } - priorities_option = priorities; - set_gnutls_priority (&client_session, priorities); - dh_params_option = dh_params; - if (dh_params && set_gnutls_dhparams (client_credentials, dh_params)) - g_warning ("Couldn't set DH parameters from %s\n", dh_params); if (disable_encrypted_credentials) g_message ("Encryption of credentials has been disabled."); - if (manager_listen (manager_address_string ?: - ipv6_is_enabled () ? "::" : "0.0.0.0", - manager_port_string, &manager_socket)) + // FIX default socket + if (manager_listen (use_tls + ? NULL + : manager_address_string_unix, + use_tls + ? (manager_address_string + ? manager_address_string + : (ipv6_is_enabled () ? "::" : "0.0.0.0")) + : NULL, + manager_port_string, + &manager_socket)) return EXIT_FAILURE; - if (manager_listen (manager_address_string_2, manager_port_string_2, + if (manager_listen (NULL, + manager_address_string_2, + manager_port_string_2, &manager_socket_2)) return EXIT_FAILURE; _______________________________________________ Openvas-commits mailing list Openvas-commits@wald.intevation.org https://lists.wald.intevation.org/cgi-bin/mailman/listinfo/openvas-commits