"Fossies" - the Fresh Open Source Software Archive

Member "gvm-7.0.3/src/ompd.c" (29 Mar 2018, 35058 Bytes) of package /linux/misc/openvas/openvas-manager-7.0.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ompd.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.0.2_vs_7.0.3.

    1 /* OpenVAS Manager
    2  * $Id$
    3  * Description: Module for OpenVAS Manager: the OMP daemon.
    4  *
    5  * Authors:
    6  * Matthew Mundell <matthew.mundell@greenbone.net>
    7  *
    8  * Copyright:
    9  * Copyright (C) 2009, 2013 Greenbone Networks GmbH
   10  *
   11  * This program is free software; you can redistribute it and/or
   12  * modify it under the terms of the GNU General Public License
   13  * as published by the Free Software Foundation; either version 2
   14  * of the License, or (at your option) any later version.
   15  *
   16  * This program is distributed in the hope that it will be useful,
   17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19  * GNU General Public License for more details.
   20  *
   21  * You should have received a copy of the GNU General Public License
   22  * along with this program; if not, write to the Free Software
   23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24  */
   25 
   26 /**
   27  * @file  ompd.c
   28  * @brief The OpenVAS Manager OMP daemon.
   29  *
   30  * This file defines the OpenVAS Manager daemon.  The Manager serves the OpenVAS
   31  * Management Protocol (OMP) to clients such as OpenVAS-Client.  The Manager
   32  * and OMP give clients full access to an OpenVAS Scanner.
   33  *
   34  * The library provides two functions: \ref init_ompd and \ref serve_omp.
   35  * \ref init_ompd initialises the daemon.
   36  * \ref serve_omp serves OMP to a single client socket until end of file is
   37  * reached on the socket.
   38  */
   39 
   40 #include "ompd.h"
   41 #include "scanner.h"
   42 #include "logf.h"
   43 #include "omp.h"
   44 /** @todo For scanner_init_state. */
   45 #include "otp.h"
   46 #include "ovas-mngr-comm.h"
   47 
   48 #include <assert.h>
   49 #include <dirent.h>
   50 #include <errno.h>
   51 #include <string.h>
   52 #include <sys/select.h>
   53 #include <sys/socket.h>
   54 #include <sys/time.h>
   55 #include <sys/types.h>
   56 #include <sys/stat.h>
   57 #include <unistd.h>
   58 
   59 #include <openvas/misc/openvas_server.h>
   60 
   61 #if FROM_BUFFER_SIZE > SSIZE_MAX
   62 #error FROM_BUFFER_SIZE too big for "read"
   63 #endif
   64 
   65 #undef G_LOG_DOMAIN
   66 /**
   67  * @brief GLib log domain.
   68  */
   69 #define G_LOG_DOMAIN "md   main"
   70 
   71 /**
   72  * @brief Buffer of input from the client.
   73  */
   74 char from_client[FROM_BUFFER_SIZE];
   75 
   76 /**
   77  * @brief Size of \ref from_client data buffer, in bytes.
   78  */
   79 buffer_size_t from_buffer_size = FROM_BUFFER_SIZE;
   80 
   81 /**
   82  * @brief The start of the data in the \ref from_client buffer.
   83  */
   84 buffer_size_t from_client_start = 0;
   85 
   86 /**
   87  * @brief The end of the data in the \ref from_client buffer.
   88  */
   89 buffer_size_t from_client_end = 0;
   90 
   91 /**
   92  * @brief Flag for running in NVT cache mode.
   93  */
   94 static int ompd_nvt_cache_mode = 0;
   95 
   96 /**
   97  * @brief Initialise the OMP library for the OMP daemon.
   98  *
   99  * @param[in]  log_config      Log configuration
  100  * @param[in]  nvt_cache_mode  0 operate normally, -1 just update NVT cache,
  101  *                             -2 just rebuild NVT cache.
  102  * @param[in]  database        Location of manage database.
  103  * @param[in]  max_ips_per_target  Max number of IPs per target.
  104  * @param[in]  max_email_attachment_size  Max size of email attachments.
  105  * @param[in]  max_email_include_size     Max size of email inclusions.
  106  * @param[in]  max_email_message_size     Max size of email user message text.
  107  * @param[in]  progress         Function to update progress, or NULL.
  108  * @param[in]  fork_connection  Function to fork a connection to the OMP
  109  *                              daemon layer, or NULL.
  110  * @param[in]  skip_db_check    Skip DB check.
  111  *
  112  * @return 0 success, -1 error, -2 database is wrong version, -3 database
  113  *         needs to be initialized from server, -4 max_ips_per_target out of
  114  *         range.
  115  */
  116 int
  117 init_ompd (GSList *log_config, int nvt_cache_mode, const gchar *database,
  118            int max_ips_per_target, int max_email_attachment_size,
  119            int max_email_include_size, int max_email_message_size,
  120            void (*progress) (),
  121            int (*fork_connection) (openvas_connection_t *, gchar*),
  122            int skip_db_check)
  123 {
  124   return init_omp (log_config, nvt_cache_mode, database, max_ips_per_target,
  125                    max_email_attachment_size, max_email_include_size,
  126                    max_email_message_size,
  127                    progress, fork_connection, skip_db_check);
  128 }
  129 
  130 /**
  131  * @brief Initialise a process forked within the OMP daemon.
  132  *
  133  * @param[in]  database  Location of manage database.
  134  * @param[in]  disable   Commands to disable.
  135  */
  136 void
  137 init_ompd_process (const gchar *database, gchar **disable)
  138 {
  139   openvas_scanner_fork ();
  140   from_client_start = 0;
  141   from_client_end = 0;
  142   init_omp_process (0, database, NULL, NULL, disable);
  143 }
  144 
  145 /**
  146  * @brief Read as much from the client as the \ref from_client buffer will hold.
  147  *
  148  * @param[in]  client_socket  The socket.
  149  *
  150  * @return 0 on reading everything available, -1 on error, -2 if
  151  *         from_client buffer is full or -3 on reaching end of file.
  152  */
  153 static int
  154 read_from_client_unix (int client_socket)
  155 {
  156   while (from_client_end < from_buffer_size)
  157     {
  158       int count;
  159       count = read (client_socket,
  160                     from_client + from_client_end,
  161                     from_buffer_size - from_client_end);
  162       if (count < 0)
  163         {
  164           if (errno == EAGAIN)
  165             /* Got everything available, return to `select'. */
  166             return 0;
  167           if (errno == EINTR)
  168             /* Interrupted, try read again. */
  169             continue;
  170           g_warning ("%s: failed to read from client: %s\n",
  171                      __FUNCTION__, strerror (errno));
  172           return -1;
  173         }
  174       if (count == 0)
  175         {
  176           /* End of file. */
  177 
  178           if (from_client_end)
  179             /* There's still client input to process, so pretend we read
  180              * something, to prevent serve_omp from exiting.
  181              *
  182              * This should instead be dealt with in serve_omp, but that function
  183              * has got quite complex. */
  184             return 0;
  185 
  186           return -3;
  187         }
  188       from_client_end += count;
  189     }
  190 
  191   /* Buffer full. */
  192   return -2;
  193 }
  194 
  195 /**
  196  * @brief Read as much from the client as the \ref from_client buffer will hold.
  197  *
  198  * @param[in]  client_session  The TLS session with the client.
  199  *
  200  * @return 0 on reading everything available, -1 on error, -2 if
  201  * from_client buffer is full or -3 on reaching end of file.
  202  */
  203 static int
  204 read_from_client_tls (gnutls_session_t* client_session)
  205 {
  206   while (from_client_end < from_buffer_size)
  207     {
  208       ssize_t count;
  209       count = gnutls_record_recv (*client_session,
  210                                   from_client + from_client_end,
  211                                   from_buffer_size - from_client_end);
  212       if (count < 0)
  213         {
  214           if (count == GNUTLS_E_AGAIN)
  215             /* Got everything available, return to `select'. */
  216             return 0;
  217           if (count == GNUTLS_E_INTERRUPTED)
  218             /* Interrupted, try read again. */
  219             continue;
  220           if (count == GNUTLS_E_REHANDSHAKE)
  221             {
  222               /** @todo Rehandshake. */
  223               g_debug ("   should rehandshake\n");
  224               continue;
  225             }
  226           if (gnutls_error_is_fatal ((int) count) == 0
  227               && (count == GNUTLS_E_WARNING_ALERT_RECEIVED
  228                   || count == GNUTLS_E_FATAL_ALERT_RECEIVED))
  229             {
  230               int alert = gnutls_alert_get (*client_session);
  231               const char* alert_name = gnutls_alert_get_name (alert);
  232               g_warning ("%s: TLS Alert %d: %s\n",
  233                          __FUNCTION__, alert, alert_name);
  234             }
  235           g_warning ("%s: failed to read from client: %s\n",
  236                      __FUNCTION__, gnutls_strerror ((int) count));
  237           return -1;
  238         }
  239       if (count == 0)
  240         {
  241           /* End of file. */
  242 
  243           if (from_client_end)
  244             /* There's still client input to process, so pretend we read
  245              * something, to prevent serve_omp from exiting.
  246              *
  247              * This should instead be dealt with in serve_omp, but that function
  248              * has got quite complex. */
  249             return 0;
  250 
  251           return -3;
  252         }
  253       from_client_end += count;
  254     }
  255 
  256   /* Buffer full. */
  257   return -2;
  258 }
  259 
  260 /**
  261  * @brief Read as much from the client as the \ref from_client buffer will hold.
  262  *
  263  * @param[in]  client_connection  The connection with the client.
  264  *
  265  * @return 0 on reading everything available, -1 on error, -2 if
  266  * from_client buffer is full or -3 on reaching end of file.
  267  */
  268 static int
  269 read_from_client (openvas_connection_t *client_connection)
  270 {
  271   if (client_connection->tls)
  272     return read_from_client_tls (&client_connection->session);
  273   return read_from_client_unix (client_connection->socket);
  274 }
  275 
  276 /** @todo Move to openvas-libraries? */
  277 /**
  278  * @brief Write as much as possible from \ref to_client to the client.
  279  *
  280  * @param[in]  client_session  The client session.
  281  *
  282  * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted.
  283  */
  284 static int
  285 write_to_client_tls (gnutls_session_t* client_session)
  286 {
  287   while (to_client_start < to_client_end)
  288     {
  289       ssize_t count;
  290       count = gnutls_record_send (*client_session,
  291                                   to_client + to_client_start,
  292                                   to_client_end - to_client_start);
  293       if (count < 0)
  294         {
  295           if (count == GNUTLS_E_AGAIN)
  296             /* Wrote as much as client would accept. */
  297             return -2;
  298           if (count == GNUTLS_E_INTERRUPTED)
  299             /* Interrupted, try write again. */
  300             continue;
  301           if (count == GNUTLS_E_REHANDSHAKE)
  302             /** @todo Rehandshake. */
  303             continue;
  304           g_warning ("%s: failed to write to client: %s\n",
  305                      __FUNCTION__,
  306                      gnutls_strerror ((int) count));
  307           return -1;
  308         }
  309       logf ("=> client %.*s\n",
  310             to_client_end - to_client_start,
  311             to_client + to_client_start);
  312       to_client_start += count;
  313       g_debug ("=> client  %u bytes\n", (unsigned int) count);
  314     }
  315   g_debug ("=> client  done\n");
  316   to_client_start = to_client_end = 0;
  317 
  318   /* Wrote everything. */
  319   return 0;
  320 }
  321 
  322 /**
  323  * @brief Write as much as possible from \ref to_client to the client.
  324  *
  325  * @param[in]  client_socket  The client socket.
  326  *
  327  * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted.
  328  */
  329 static int
  330 write_to_client_unix (int client_socket)
  331 {
  332   while (to_client_start < to_client_end)
  333     {
  334       ssize_t count;
  335       count = write (client_socket,
  336                      to_client + to_client_start,
  337                      to_client_end - to_client_start);
  338       if (count < 0)
  339         {
  340           if (errno == EAGAIN)
  341             /* Wrote as much as client would accept. */
  342             return -2;
  343           if (errno == EINTR)
  344             /* Interrupted, try write again. */
  345             continue;
  346           g_warning ("%s: failed to write to client: %s\n",
  347                      __FUNCTION__,
  348                      strerror (errno));
  349           return -1;
  350         }
  351       logf ("=> client %.*s\n",
  352             to_client_end - to_client_start,
  353             to_client + to_client_start);
  354       to_client_start += count;
  355       g_debug ("=> client  %u bytes\n", (unsigned int) count);
  356     }
  357   g_debug ("=> client  done\n");
  358   to_client_start = to_client_end = 0;
  359 
  360   /* Wrote everything. */
  361   return 0;
  362 }
  363 
  364 /**
  365  * @brief Write as much as possible from \ref to_client to the client.
  366  *
  367  * @param[in]  client_connection  The client connection.
  368  *
  369  * @return 0 wrote everything, -1 error, -2 wrote as much as client accepted.
  370  */
  371 static int
  372 write_to_client (openvas_connection_t *client_connection)
  373 {
  374   if (client_connection->tls)
  375     return write_to_client_tls (&client_connection->session);
  376   return write_to_client_unix (client_connection->socket);
  377 }
  378 
  379 /**
  380  * @brief Send a response message to the client.
  381  *
  382  * Queue a message in \ref to_client.
  383  *
  384  * @param[in]  msg                   The message, a string.
  385  * @param[in]  write_to_client_data  Argument to \p write_to_client.
  386  *
  387  * @return TRUE if write to client failed, else FALSE.
  388  */
  389 gboolean
  390 ompd_send_to_client (const char* msg, void* write_to_client_data)
  391 {
  392   assert (to_client_end <= TO_CLIENT_BUFFER_SIZE);
  393   assert (msg);
  394 
  395   while (((buffer_size_t) TO_CLIENT_BUFFER_SIZE) - to_client_end
  396          < strlen (msg))
  397     {
  398       buffer_size_t length;
  399 
  400       /* Too little space in to_client buffer for message. */
  401 
  402       switch (write_to_client (write_to_client_data))
  403         {
  404           case  0:      /* Wrote everything in to_client. */
  405             break;
  406           case -1:      /* Error. */
  407             g_debug ("   %s full (%i < %zu); client write failed\n",
  408                     __FUNCTION__,
  409                     ((buffer_size_t) TO_CLIENT_BUFFER_SIZE) - to_client_end,
  410                     strlen (msg));
  411             return TRUE;
  412           case -2:      /* Wrote as much as client was willing to accept. */
  413             break;
  414           default:      /* Programming error. */
  415             assert (0);
  416         }
  417 
  418       length = ((buffer_size_t) TO_CLIENT_BUFFER_SIZE) - to_client_end;
  419 
  420       if (length > strlen (msg))
  421         break;
  422 
  423       memmove (to_client + to_client_end, msg, length);
  424       g_debug ("-> client: %.*s\n", (int) length, msg);
  425       to_client_end += length;
  426       msg += length;
  427     }
  428 
  429   if (strlen (msg))
  430     {
  431       assert (strlen (msg)
  432               <= (((buffer_size_t) TO_CLIENT_BUFFER_SIZE) - to_client_end));
  433       memmove (to_client + to_client_end, msg, strlen (msg));
  434       g_debug ("-> client: %s\n", msg);
  435       to_client_end += strlen (msg);
  436     }
  437 
  438   return FALSE;
  439 }
  440 
  441 /**
  442  * @brief Clean session.
  443  *
  444  * @param[in]  client_connection  Connection.
  445  */
  446 static void
  447 session_clean (openvas_connection_t *client_connection)
  448 {
  449   if (client_connection->session)
  450     {
  451       gnutls_deinit (client_connection->session);
  452       client_connection->session = NULL;
  453     }
  454   if (client_connection->credentials)
  455     {
  456       gnutls_certificate_free_credentials (client_connection->credentials);
  457       client_connection->credentials = NULL;
  458     }
  459 }
  460 
  461 /**
  462  * @brief Serve the OpenVAS Management Protocol (OMP).
  463  *
  464  * Loop reading input from the sockets, processing
  465  * the input, and writing any results to the appropriate socket.
  466  * Exit the loop on reaching end of file on the client socket.
  467  *
  468  * Read input from the client and scanner.
  469  * Process the input with \ref process_omp_client_input and
  470  * \ref process_otp_scanner_input.  Write the results to the client.
  471  *
  472  * \if STATIC
  473  *
  474  * Read input with \ref read_from_client and \ref openvas_scanner_read.
  475  * Write the results with \ref write_to_client.  Write to the server
  476  * with \ref openvas_scanner_write.
  477  *
  478  * \endif
  479  *
  480  * If compiled with logging (\ref LOG) then log all input and output
  481  * with \ref logf.
  482  *
  483  * If client_socket is 0 or less, then update the NVT cache and exit.
  484  *
  485  * @param[in]  client_connection    Connection.
  486  * @param[in]  database             Location of manage database.
  487  * @param[in]  disable              Commands to disable.
  488  * @param[in]  progress             Function to mark progress, or NULL.
  489  *
  490  * @return 0 success, 1 scanner still loading, -1 error, -2 scanner has no cert.
  491  */
  492 int
  493 serve_omp (openvas_connection_t *client_connection, const gchar *database,
  494            gchar **disable, void (*progress) ())
  495 {
  496   int nfds, scan_handler = 0, rc = 0;
  497   /* True if processing of the client input is waiting for space in the
  498    * to_scanner or to_client buffer. */
  499   short client_input_stalled;
  500   /* Client status flag.  Set to 0 when the client closes the connection
  501    * while the scanner is active. */
  502   short client_active = client_connection->socket > 0;
  503 
  504   if (client_connection->socket < 0)
  505     ompd_nvt_cache_mode = client_connection->socket;
  506 
  507   if (ompd_nvt_cache_mode)
  508     g_info ("   Updating NVT cache.\n");
  509   else
  510     g_debug ("   Serving OMP.\n");
  511 
  512   /* Initialise the XML parser and the manage library. */
  513   init_omp_process (ompd_nvt_cache_mode,
  514                     database,
  515                     (int (*) (const char*, void*)) ompd_send_to_client,
  516                     (void*) client_connection,
  517                     disable);
  518 #if 0
  519   /** @todo Consider free_omp_data (); on return. */
  520   if (tasks) free_tasks ();
  521   if (current_scanner_preference) free (current_scanner_preference);
  522   free_credentials (&current_credentials);
  523   maybe_free_scanner_preferences (); // old
  524 #endif
  525 
  526   /* Setup the scanner address and try to connect. */
  527   if (ompd_nvt_cache_mode && !openvas_scanner_connected ())
  528     {
  529       int ret;
  530 
  531       /* Is here because it queries the DB and needs it initialized.
  532        * XXX: Move outside serve_omp ().
  533        */
  534 
  535       ret = manage_scanner_set_default ();
  536       if (ret)
  537         return ret;
  538       if (openvas_scanner_connect () || openvas_scanner_init (1))
  539         {
  540           openvas_scanner_close ();
  541           return -1;
  542         }
  543     }
  544 
  545   client_input_stalled = 0;
  546 
  547   /** @todo Confirm and clarify complications, especially last one. */
  548   /* Loop handling input from the sockets.
  549    *
  550    * That is, select on all the socket fds and then, as necessary
  551    *   - read from the client into buffer from_client
  552    *   - write to the scanner from buffer to_scanner
  553    *   - read from the scanner into buffer from_scanner
  554    *   - write to the client from buffer to_client.
  555    *
  556    * On reading from an fd, immediately try react to the input.  On reading
  557    * from the client call process_omp_client_input, which parses OMP
  558    * commands and may write to to_scanner and to_client.  On reading from
  559    * the scanner call process_otp_scanner_input, which updates information
  560    * kept about the scanner.
  561    *
  562    * There are a few complications here
  563    *   - the program must read from or write to an fd returned by select
  564    *     before selecting on the fd again,
  565    *   - the program need only select on the fds for writing if there is
  566    *     something to write,
  567    *   - similarly, the program need only select on the fds for reading
  568    *     if there is buffer space available,
  569    *   - the buffers from_client and from_scanner can become full during
  570    *     reading
  571    *   - a read from the client can be stalled by the to_scanner buffer
  572    *     filling up, or the to_client buffer filling up (in which case
  573    *     process_omp_client_input will try to write the to_client buffer
  574    *     itself),
  575    *   - a read from the scanner can, theoretically, be stalled by the
  576    *     to_scanner buffer filling up (during initialisation).
  577    */
  578 
  579   nfds = openvas_scanner_get_nfds (client_connection->socket);
  580   while (1)
  581     {
  582       int ret;
  583       fd_set readfds, writefds;
  584       int termination_signal = get_termination_signal ();
  585 
  586       if (termination_signal)
  587         {
  588           g_debug ("%s: Received %s signal.",
  589                    __FUNCTION__,
  590                    sys_siglist[get_termination_signal()]);
  591 
  592           if (openvas_scanner_connected ())
  593             {
  594               openvas_scanner_close ();
  595             }
  596 
  597           goto client_free;
  598         }
  599 
  600       /* Setup for select. */
  601 
  602       /** @todo nfds must only include a socket if it's in >= one set. */
  603 
  604       FD_ZERO (&readfds);
  605       FD_ZERO (&writefds);
  606 
  607       /** @todo Shutdown on failure (for example, if a read fails). */
  608 
  609       if (client_active)
  610         {
  611           /* See whether to read from the client.  */
  612           if (from_client_end < from_buffer_size)
  613             FD_SET (client_connection->socket, &readfds);
  614           /* See whether to write to the client.  */
  615           if (to_client_start < to_client_end)
  616             FD_SET (client_connection->socket, &writefds);
  617         }
  618 
  619       /* See whether we need to read from the scannner.  */
  620       if (openvas_scanner_connected ()
  621           && (scanner_init_state == SCANNER_INIT_DONE
  622               || scanner_init_state == SCANNER_INIT_DONE_CACHE_MODE
  623               || scanner_init_state == SCANNER_INIT_DONE_CACHE_MODE_UPDATE
  624               || scanner_init_state == SCANNER_INIT_SENT_COMPLETE_LIST
  625               || scanner_init_state == SCANNER_INIT_SENT_COMPLETE_LIST_UPDATE
  626               || scanner_init_state == SCANNER_INIT_SENT_VERSION)
  627           && !openvas_scanner_full ())
  628         openvas_scanner_fd_set (&readfds);
  629 
  630       /* See whether we need to write to the scanner.  */
  631       if (openvas_scanner_connected ()
  632           && (((scanner_init_state == SCANNER_INIT_TOP
  633                 || scanner_init_state == SCANNER_INIT_DONE
  634                 || scanner_init_state == SCANNER_INIT_DONE_CACHE_MODE
  635                 || scanner_init_state == SCANNER_INIT_DONE_CACHE_MODE_UPDATE)
  636                && to_server_buffer_space () > 0)
  637               || scanner_init_state == SCANNER_INIT_CONNECTED
  638               || scanner_init_state == SCANNER_INIT_GOT_FEED_VERSION
  639               || scanner_init_state == SCANNER_INIT_GOT_PLUGINS))
  640         openvas_scanner_fd_set (&writefds);
  641 
  642       /* Select, then handle result.  Due to GNUTLS internal buffering
  643        * we test for pending records first and emulate a select call
  644        * in that case.  Note, that GNUTLS guarantees that writes are
  645        * not buffered.  Note also that GNUTLS versions < 3 did not
  646        * exhibit a problem in OpenVAS due to a different buffering
  647        * strategy.  */
  648       ret = 0;
  649       if (client_connection->socket > 0
  650           && client_connection->tls
  651           && FD_ISSET (client_connection->socket, &readfds)
  652           && gnutls_record_check_pending (client_connection->session))
  653         {
  654           FD_ZERO (&readfds);
  655           FD_ZERO (&writefds);
  656           ret++;
  657           FD_SET (client_connection->socket, &readfds);
  658         }
  659       if (openvas_scanner_fd_isset (&readfds))
  660         {
  661           if (openvas_scanner_session_peek ())
  662             {
  663               if (!ret)
  664                 {
  665                   FD_ZERO (&readfds);
  666                   FD_ZERO (&writefds);
  667                 }
  668               ret++;
  669               openvas_scanner_fd_set (&readfds);
  670             }
  671           else if (openvas_scanner_peek () == 0)
  672             {
  673               /* Scanner has gone down.  Exit. */
  674               rc = -1;
  675               goto client_free;
  676             }
  677         }
  678 
  679       if (!ret)
  680         {
  681           /* Timeout periodically, so that process_omp_change runs
  682            * periodically. */
  683           struct timeval timeout;
  684 
  685           timeout.tv_usec = 0;
  686           timeout.tv_sec = 1;
  687           ret = select (nfds, &readfds, &writefds, NULL, &timeout);
  688         }
  689       if ((ret < 0 && errno == EINTR) || ret == 0)
  690         {
  691           if (process_omp_change () == -1)
  692             {
  693               rc = -1;
  694               goto client_free;
  695             }
  696           if (!scan_handler && !ompd_nvt_cache_mode)
  697             continue;
  698         }
  699       else if (ret < 0)
  700         {
  701           g_warning ("%s: child select failed: %s\n", __FUNCTION__,
  702                      strerror (errno));
  703           rc = -1;
  704           goto client_free;
  705         }
  706 
  707       /* Read any data from the client. */
  708       if (client_connection->socket > 0
  709           && FD_ISSET (client_connection->socket, &readfds))
  710         {
  711           buffer_size_t initial_start = from_client_end;
  712 
  713           switch (read_from_client (client_connection))
  714             {
  715               case  0:       /* Read everything. */
  716                 break;
  717               case -1:       /* Error. */
  718                 rc = -1;
  719                 goto client_free;
  720               case -2:       /* from_client buffer full. */
  721                 /* There may be more to read. */
  722                 break;
  723               case -3:       /* End of file. */
  724                 g_debug ("   EOF reading from client.\n");
  725                 if (client_connection->socket > 0
  726                     && FD_ISSET (client_connection->socket, &writefds))
  727                   /* Write rest of to_client to client, so that the client gets
  728                    * any buffered output and the response to the error. */
  729                   write_to_client (client_connection);
  730                 rc = 0;
  731                 goto client_free;
  732               default:       /* Programming error. */
  733                 assert (0);
  734             }
  735 
  736           /* This check prevents output in the "asynchronous network
  737            * error" case. */
  738           if (from_client_end > initial_start)
  739             {
  740               logf ("<= client %.*s\n",
  741                     from_client_end - initial_start,
  742                     from_client + initial_start);
  743               if (g_strstr_len (from_client + initial_start,
  744                                 from_client_end - initial_start,
  745                                 "<password>"))
  746                 g_debug ("<= client  Input may contain password, suppressed.\n");
  747               else
  748                 g_debug ("<= client  \"%.*s\"\n",
  749                         from_client_end - initial_start,
  750                         from_client + initial_start);
  751             }
  752 
  753           ret = process_omp_client_input ();
  754           if (ret == 0)
  755             /* Processed all input. */
  756             client_input_stalled = 0;
  757           else if (ret == 3)
  758             {
  759               /* In the parent after a start_task fork. Free the scanner session
  760                * without closing it, for usage by the child process. */
  761               set_scanner_init_state (SCANNER_INIT_TOP);
  762               openvas_scanner_free ();
  763               nfds = openvas_scanner_get_nfds (client_connection->socket);
  764               client_input_stalled = 0;
  765               /* Skip the rest of the loop because the scanner socket is
  766                * a new socket.  This is asking for select trouble, really. */
  767               continue;
  768             }
  769           else if (ret == 2)
  770             {
  771               /* Now in a process forked to run a task, which has
  772                * successfully started the task.  Close the client
  773                * connection, as the parent process has continued the
  774                * session with the client. */
  775               session_clean (client_connection);
  776               client_active = 0;
  777               client_input_stalled = 0;
  778               scan_handler = 1;
  779             }
  780           else if (ret == 4)
  781             {
  782               /* Now in a process forked for some operation which has
  783                * successfully completed.  Close the client connection,
  784                * and exit, as the parent process has continued the
  785                * session with the client. */
  786               session_clean (client_connection);
  787               return 0;
  788             }
  789           else if (ret == -10)
  790             {
  791               /* Now in a process forked to run a task, which has
  792                * failed in starting the task. */
  793               session_clean (client_connection);
  794               return -1;
  795             }
  796           else if (ret == -1 || ret == -4)
  797             {
  798               /* Error.  Write rest of to_client to client, so that the
  799                * client gets any buffered output and the response to the
  800                * error. */
  801               write_to_client (client_connection);
  802               rc = -1;
  803               goto client_free;
  804             }
  805           else if (ret == -2)
  806             {
  807               /* to_scanner buffer full. */
  808               g_debug ("   client input stalled 1\n");
  809               client_input_stalled = 1;
  810               /* Carry on to write to_scanner. */
  811             }
  812           else if (ret == -3)
  813             {
  814               /* to_client buffer full. */
  815               g_debug ("   client input stalled 2\n");
  816               client_input_stalled = 2;
  817               /* Carry on to write to_client. */
  818             }
  819           else
  820             {
  821               /* Programming error. */
  822               assert (0);
  823               client_input_stalled = 0;
  824             }
  825         }
  826 
  827       /* Read any data from the scanner. */
  828       if (openvas_scanner_connected ()
  829           && (openvas_scanner_fd_isset (&readfds) || scan_handler))
  830         {
  831           switch (openvas_scanner_read ())
  832             {
  833               case  0:       /* Read everything. */
  834                 break;
  835               case -1:       /* Error. */
  836                 /* This may be because the scanner closed the connection
  837                  * at the end of a command. */
  838                 /** @todo Then should get EOF (-3). */
  839                 set_scanner_init_state (SCANNER_INIT_TOP);
  840                 rc = -1;
  841                 goto client_free;
  842               case -2:       /* from_scanner buffer full. */
  843                 /* There may be more to read. */
  844                 break;
  845               case -3:       /* End of file. */
  846                 set_scanner_init_state (SCANNER_INIT_TOP);
  847                 if (client_active == 0)
  848                   /* The client has closed the connection, so exit. */
  849                   return 0;
  850                 /* Scanner went down, exit. */
  851                 rc = -1;
  852                 goto client_free;
  853               default:       /* Programming error. */
  854                 assert (0);
  855             }
  856         }
  857 
  858       /* Write any data to the scanner. */
  859       if (openvas_scanner_connected ()
  860           && (openvas_scanner_fd_isset (&writefds) || scan_handler))
  861         {
  862           /* Write as much as possible to the scanner. */
  863 
  864           switch (openvas_scanner_write (ompd_nvt_cache_mode))
  865             {
  866               case  0:      /* Wrote everything in to_scanner. */
  867                 break;
  868               case -1:      /* Error. */
  869                 /** @todo This may be because the scanner closed the connection
  870                  * at the end of a command? */
  871                 rc = -1;
  872                 goto client_free;
  873               case -2:      /* Wrote as much as scanner was willing to accept. */
  874                 break;
  875               case -3:      /* Did an initialisation step. */
  876                 break;
  877               default:      /* Programming error. */
  878                 assert (0);
  879             }
  880         }
  881 
  882       /* Write any data to the client. */
  883       if (client_connection->socket > 0
  884           && FD_ISSET (client_connection->socket, &writefds))
  885         {
  886           /* Write as much as possible to the client. */
  887 
  888           switch (write_to_client (client_connection))
  889             {
  890               case  0:      /* Wrote everything in to_client. */
  891                 break;
  892               case -1:      /* Error. */
  893                 rc = -1;
  894                 goto client_free;
  895               case -2:      /* Wrote as much as client was willing to accept. */
  896                 break;
  897               default:      /* Programming error. */
  898                 assert (0);
  899             }
  900         }
  901 
  902       if (client_input_stalled)
  903         {
  904           /* Try process the client input, in case writing to the scanner
  905            * or client has freed some space in to_scanner or to_client. */
  906 
  907           ret = process_omp_client_input ();
  908           if (ret == 0)
  909             /* Processed all input. */
  910             client_input_stalled = 0;
  911           else if (ret == 3)
  912             {
  913               /* In the parent after a start_task fork. Free the scanner session
  914                * without closing it, for usage by the child process. */
  915               openvas_scanner_free ();
  916               set_scanner_init_state (SCANNER_INIT_TOP);
  917               nfds = openvas_scanner_get_nfds (client_connection->socket);
  918               /* Skip the rest of the loop because the scanner socket is
  919                * a new socket.  This is asking for select trouble, really. */
  920               continue;
  921             }
  922           else if (ret == 2)
  923             {
  924               /* Now in a process forked to run a task, which has
  925                * successfully started the task.  Close the client
  926                * connection, as the parent process has continued the
  927                * session with the client. */
  928               session_clean (client_connection);
  929               scan_handler = 1;
  930               client_active = 0;
  931             }
  932           else if (ret == 4)
  933             {
  934               /* Now in a process forked for some operation which has
  935                * successfully completed.  Close the client connection,
  936                * and exit, as the parent process has continued the
  937                * session with the client. */
  938               session_clean (client_connection);
  939               return 0;
  940             }
  941           else if (ret == -10)
  942             {
  943               /* Now in a process forked to run a task, which has
  944                * failed in starting the task. */
  945               session_clean (client_connection);
  946               return -1;
  947             }
  948           else if (ret == -1)
  949             {
  950               /* Error.  Write rest of to_client to client, so that the
  951                * client gets any buffered output and the response to the
  952                * error. */
  953               write_to_client (client_connection);
  954               rc = -1;
  955               goto client_free;
  956             }
  957           else if (ret == -2)
  958             {
  959               /* to_scanner buffer full. */
  960               g_debug ("   client input still stalled (1)\n");
  961               client_input_stalled = 1;
  962             }
  963           else if (ret == -3)
  964             {
  965               /* to_client buffer full. */
  966               g_debug ("   client input still stalled (2)\n");
  967               client_input_stalled = 2;
  968             }
  969           else
  970             {
  971               /* Programming error. */
  972               assert (0);
  973               client_input_stalled = 0;
  974             }
  975         }
  976 
  977       if (openvas_scanner_connected ())
  978         {
  979           /* Try process the scanner input, in case writing to the scanner
  980            * has freed some space in to_scanner. */
  981 
  982           ret = process_otp_scanner_input (progress);
  983           if (ret == 1)
  984             {
  985               /* Received scanner BYE.  Write out the rest of to_scanner (the
  986                * BYE ACK).
  987                */
  988               openvas_scanner_write (ompd_nvt_cache_mode);
  989               set_scanner_init_state (SCANNER_INIT_TOP);
  990               if (client_active == 0)
  991                 return 0;
  992               openvas_scanner_free ();
  993               nfds = openvas_scanner_get_nfds (client_connection->socket);
  994             }
  995           else if (ret == 2)
  996             {
  997               /* Bad login to scanner. */
  998               if (client_active == 0)
  999                 return 0;
 1000               rc = -1;
 1001               goto client_free;
 1002             }
 1003           else if (ret == 3)
 1004             {
 1005               /* Calls via serve_client() should continue. */
 1006               if (ompd_nvt_cache_mode)
 1007                 return 1;
 1008               openvas_scanner_close ();
 1009             }
 1010           else if (ret == -1)
 1011             {
 1012               /* Error. */
 1013               rc = -1;
 1014               goto client_free;
 1015             }
 1016           else if (ret == -3)
 1017             /* to_scanner buffer still full. */
 1018             g_debug ("   scanner input stalled\n");
 1019           else
 1020             {
 1021               /* Programming error. */
 1022               assert (ret == 0 || ret == 5);
 1023             }
 1024         }
 1025 
 1026       if (process_omp_change () == -1)
 1027         {
 1028           rc = -1;
 1029           goto client_free;
 1030         }
 1031 
 1032     } /* while (1) */
 1033 
 1034 client_free:
 1035   if (client_active)
 1036     openvas_connection_free (client_connection);
 1037   return rc;
 1038 }