OpenVAS Manager  7.0.3~git
scanner.c
Go to the documentation of this file.
1 /* OpenVAS Manager
2  * $Id$
3  * Description: Module for OpenVAS Manager: Scanner Connection.
4  *
5  * Authors:
6  * Hani Benhabiles <hani.benhabiles@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2014 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 #include "scanner.h"
27 #include "ompd.h"
28 #include "otp.h"
29 #include "ovas-mngr-comm.h"
30 #include "utils.h"
31 
32 #include <dirent.h>
33 #include <assert.h>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <sys/un.h>
39 #include <fcntl.h>
40 
41 #include <openvas/misc/openvas_server.h>
42 
43 #undef G_LOG_DOMAIN
44 
47 #define G_LOG_DOMAIN "md main"
48 
49 /* Current OpenVAS Scanner connection. */
50 gnutls_session_t openvas_scanner_session = NULL;
51 gnutls_certificate_credentials_t openvas_scanner_credentials = NULL;
53 struct sockaddr_in openvas_scanner_address;
58 
62 char *from_scanner = NULL;
63 
68 
73 
78 
83 
84 /* XXX: ovas-mngr-comm.c content should be moved to scanner.c to better abstract
85  * scanner reading/writing. */
86 extern char to_server[];
87 extern int to_server_end;
88 extern int to_server_start;
89 
98 static int
99 write_string_to_server (char* const string)
100 {
101  char* point = string;
102  char* end = string + strlen (string);
103  while (point < end)
104  {
105  ssize_t count;
106 
108  {
109  count = send (openvas_scanner_socket, point, end - point, 0);
110  if (count < 0)
111  {
112  if (errno == EAGAIN)
113  return point - string;
114  else if (errno == EINTR)
115  continue;
116  else
117  {
118  g_warning ("%s: Failed to write to scanner: %s\n", __FUNCTION__,
119  strerror (errno));
120  return -1;
121  }
122  }
123  }
124  else
125  {
126  count = gnutls_record_send (openvas_scanner_session,
127  point, (size_t) (end - point));
128  if (count < 0)
129  {
130  if (count == GNUTLS_E_AGAIN)
131  /* Wrote as much as server accepted. */
132  return point - string;
133  if (count == GNUTLS_E_INTERRUPTED)
134  /* Interrupted, try write again. */
135  continue;
136  if (count == GNUTLS_E_REHANDSHAKE)
138  continue;
139  g_warning ("%s: failed to write to server: %s\n",
140  __FUNCTION__,
141  gnutls_strerror ((int) count));
142  return -1;
143  }
144  }
145 #if LOG
146  if (count) logf ("=> server %.*s\n", (int) count, point);
147 #endif
148  g_debug ("s> server (string) %.*s\n", (int) count, point);
149  point += count;
150  g_debug ("=> server (string) %zi bytes\n", count);
151  }
152  g_debug ("=> server (string) done\n");
153  /* Wrote everything. */
154  return 0;
155 }
156 
163 static int
164 write_to_server_buffer ()
165 {
167  {
168  ssize_t count;
169 
171  {
174  if (count < 0)
175  {
176  if (errno == EAGAIN)
177  return -2;
178  else if (errno == EINTR)
179  return -3;
180  else
181  {
182  g_warning ("%s: Failed to write to scanner: %s\n", __FUNCTION__,
183  strerror (errno));
184  return -1;
185  }
186  }
187  }
188  else
189  {
190  count = gnutls_record_send (openvas_scanner_session,
192  (size_t) to_server_end - to_server_start);
193  if (count < 0)
194  {
195  if (count == GNUTLS_E_AGAIN)
196  /* Wrote as much as server accepted. */
197  return -2;
198  if (count == GNUTLS_E_INTERRUPTED)
199  /* Interrupted, try write again. */
200  return -3;
201  if (count == GNUTLS_E_REHANDSHAKE)
203  continue;
204  g_warning ("%s: failed to write to server: %s\n",
205  __FUNCTION__,
206  gnutls_strerror ((int) count));
207  return -1;
208  }
209  }
210 #if LOG
211  if (count) logf ("=> server %.*s\n",
212  (int) count,
214 #endif
215  g_debug ("s> server %.*s\n", (int) count, to_server + to_server_start);
216  to_server_start += count;
217  g_debug ("=> server %zi bytes\n", count);
218  }
219  g_debug ("=> server done\n");
221  /* Wrote everything. */
222  return 0;
223 }
224 
232 int
234 {
235  if (openvas_scanner_socket == -1)
236  return -1;
237 
238  while (!openvas_scanner_full ())
239  {
240  ssize_t count;
241 
243  {
246  if (count < 0)
247  {
248  if (errno == EINTR)
249  continue;
250  else if (errno == EAGAIN)
251  return 0;
252  else
253  {
254  g_warning ("%s: Failed to read from scanner: %s\n", __FUNCTION__,
255  strerror (errno));
256  return -1;
257  }
258  }
259  }
260  else
261  {
262  count = gnutls_record_recv (openvas_scanner_session,
265  if (count < 0)
266  {
267  if (count == GNUTLS_E_AGAIN)
268  /* Got everything available, return to `select'. */
269  return 0;
270  if (count == GNUTLS_E_INTERRUPTED)
271  /* Interrupted, try read again. */
272  continue;
273  if (count == GNUTLS_E_REHANDSHAKE)
274  {
276  g_debug (" should rehandshake\n");
277  continue;
278  }
279  if (gnutls_error_is_fatal (count) == 0
280  && (count == GNUTLS_E_WARNING_ALERT_RECEIVED
281  || count == GNUTLS_E_FATAL_ALERT_RECEIVED))
282  {
283  int alert = gnutls_alert_get (openvas_scanner_session);
284  const char* alert_name = gnutls_alert_get_name (alert);
285  g_warning ("%s: TLS Alert %d: %s\n", __FUNCTION__, alert,
286  alert_name);
287  }
288  g_warning ("%s: failed to read from server: %s\n", __FUNCTION__,
289  gnutls_strerror (count));
290  return -1;
291  }
292  }
293  if (count == 0)
294  /* End of file. */
295  return -3;
296  assert (count > 0);
297  from_scanner_end += count;
298  }
299 
300  /* Buffer full. */
301  return -2;
302 }
303 
309 int
311 {
313 }
314 
320 int
322 {
324  return 1;
325  from_scanner_size *= 2;
326  g_warning ("Reallocing to %d", from_scanner_size);
328  return 0;
329 }
330 
337 int
338 openvas_scanner_write (int nvt_cache_mode)
339 {
340  int ret = 0;
341 
342  if (openvas_scanner_socket == -1)
343  return -1;
344  switch (scanner_init_state)
345  {
346  case SCANNER_INIT_TOP:
348  ret = openvas_server_connect (openvas_scanner_socket,
351  switch (ret)
352  {
353  case 0:
355  /* The socket must have O_NONBLOCK set, in case an "asynchronous network
356  * error" removes the data between `select' and `read'. */
357  if (fcntl (openvas_scanner_socket, F_SETFL, O_NONBLOCK) == -1)
358  {
359  g_warning ("%s: failed to set scanner socket flag: %s\n",
360  __FUNCTION__, strerror (errno));
361  return -1;
362  }
363  /* Fall through to SCANNER_INIT_CONNECTED case below, to write
364  * version string. */
365  break;
366  default:
367  return -1;
368  }
369  /* fallthrough */
371  {
372  char* string = "< OTP/2.0 >\n";
373 
374  scanner_init_offset = write_string_to_server
375  (string + scanner_init_offset);
376  if (scanner_init_offset == 0)
378  else if (scanner_init_offset == -1)
379  {
381  return -1;
382  }
383  if (nvt_cache_mode)
384  {
385  string = "CLIENT <|> NVT_INFO <|> CLIENT\n";
386  scanner_init_offset = write_string_to_server
387  (string + scanner_init_offset);
388  if (scanner_init_offset == -1)
389  {
391  return -1;
392  }
393  }
394  break;
395  }
397  return 0;
400  return 0;
402  if (nvt_cache_mode)
403  {
404  static char* const ack = "CLIENT <|> COMPLETE_LIST <|> CLIENT\n";
405  scanner_init_offset = write_string_to_server
406  (ack + scanner_init_offset);
407  if (scanner_init_offset == 0)
408  set_scanner_init_state (nvt_cache_mode == -1
411  else if (scanner_init_offset == -1)
412  {
414  return -1;
415  }
416  break;
417  }
418  /* fallthrough */
420  {
421  static char* const ack = "\n";
422  scanner_init_offset = write_string_to_server
423  (ack + scanner_init_offset);
424  if (scanner_init_offset == 0)
425  {
426  if (nvt_cache_mode == -1)
428  else if (nvt_cache_mode == -2)
430  else
432  }
433  else if (scanner_init_offset == -1)
434  {
436  return -1;
437  }
438  else
439  break;
440  }
441  /* fallthrough */
442  case SCANNER_INIT_DONE:
445  while (1)
446  switch (write_to_server_buffer ())
447  {
448  case 0: return 0;
449  case -1: return -1;
450  case -2: return -2;
451  case -3: continue; /* Interrupted. */
452  }
453  }
454  return -3;
455 }
456 
462 int
464 {
465  if (openvas_scanner_socket == -1)
466  return -1;
467 
468  while (1)
469  {
470  int ret;
471  struct timeval timeout;
472  fd_set writefds;
473 
474  timeout.tv_usec = 0;
475  timeout.tv_sec = 1;
476  FD_ZERO (&writefds);
477  FD_SET (openvas_scanner_socket, &writefds);
478 
479  ret = select (1 + openvas_scanner_socket, NULL, &writefds, NULL, &timeout);
480  if (ret < 0)
481  {
482  if (errno == EINTR)
483  continue;
484  g_warning ("%s: select failed (connect): %s\n", __FUNCTION__,
485  strerror (errno));
486  return -1;
487  }
488 
489  if (FD_ISSET (openvas_scanner_socket, &writefds))
490  break;
491  }
492  return 0;
493 }
494 
502 static int
503 load_cas (gnutls_certificate_credentials_t *scanner_credentials)
504 {
505  DIR *dir;
506  struct dirent *ent;
507 
508  dir = opendir (CA_DIR);
509  if (dir == NULL)
510  {
511  if (errno != ENOENT)
512  {
513  g_warning ("%s: failed to open " CA_DIR ": %s\n", __FUNCTION__,
514  strerror (errno));
515  return -1;
516  }
517  }
518  else while ((ent = readdir (dir)))
519  {
520  gchar *name;
521  struct stat state;
522 
523  if ((strcmp (ent->d_name, ".") == 0) || (strcmp (ent->d_name, "..") == 0))
524  continue;
525 
526  name = g_build_filename (CA_DIR, ent->d_name, NULL);
527  stat (name, &state);
528  if (S_ISREG (state.st_mode)
529  && (gnutls_certificate_set_x509_trust_file
530  (*scanner_credentials, name, GNUTLS_X509_FMT_PEM) < 0))
531  {
532  g_warning ("%s: gnutls_certificate_set_x509_trust_file failed: %s\n",
533  __FUNCTION__, name);
534  g_free (name);
535  closedir (dir);
536  return -1;
537  }
538  g_free (name);
539  }
540  if (dir != NULL)
541  closedir (dir);
542  return 0;
543 }
544 
550 int
552 {
553  int rc = 0;
554  if (openvas_scanner_socket == -1)
555  return -1;
557  close (openvas_scanner_socket);
558  else
559  rc = openvas_server_free (openvas_scanner_socket, openvas_scanner_session,
564  g_free (from_scanner);
565  from_scanner = NULL;
566  return rc;
567 }
568 
574 void
576 {
580  from_scanner_start = 0;
581  from_scanner_end = 0;
583 }
584 
585 int
587 {
588  struct sockaddr_un addr;
589  int len;
590 
591  openvas_scanner_socket = socket (AF_UNIX, SOCK_STREAM, 0);
592  if (openvas_scanner_socket == -1)
593  {
594  g_warning ("%s: failed to create scanner socket: %s\n", __FUNCTION__,
595  strerror (errno));
596  return -1;
597  }
598 
599  addr.sun_family = AF_UNIX;
600  strncpy (addr.sun_path, openvas_scanner_unix_path, 108);
601  len = strlen (addr.sun_path) + sizeof (addr.sun_family);
602  if (connect (openvas_scanner_socket, (struct sockaddr *) &addr, len) == -1)
603  {
604  g_warning ("%s: Failed to connect to scanner (%s): %s\n", __FUNCTION__,
605  openvas_scanner_unix_path, strerror (errno));
606  return -1;
607  }
608 
609  init_otp_data ();
610  return 0;
611 }
612 
618 int
620 {
623 
624  openvas_scanner_socket = socket (PF_INET, SOCK_STREAM, 0);
625  if (openvas_scanner_socket == -1)
626  {
627  g_warning ("%s: failed to create scanner socket: %s\n", __FUNCTION__,
628  strerror (errno));
629  return -1;
630  }
631 
632  /* Make the scanner socket. */
633  if (openvas_server_new_mem
637  {
638  close (openvas_scanner_socket);
640  return -1;
641  }
642 
643  if (load_cas (&openvas_scanner_credentials))
644  {
646  return -1;
647  }
648 
649  init_otp_data ();
650 
651  return 0;
652 }
653 
658 void
660 {
661  close (openvas_scanner_socket);
664  gnutls_deinit (openvas_scanner_session);
667  gnutls_certificate_free_credentials (openvas_scanner_credentials);
669  memset (&openvas_scanner_address, '\0', sizeof (openvas_scanner_address));
670  g_free (openvas_scanner_ca_pub);
671  g_free (openvas_scanner_key_pub);
672  g_free (openvas_scanner_key_priv);
673  g_free (openvas_scanner_unix_path);
674  openvas_scanner_ca_pub = NULL;
678 }
679 
687 int
689 {
690  if (openvas_scanner_socket == -1)
691  return 0;
692  return FD_ISSET (openvas_scanner_socket, fd);
693 }
694 
700 void
702 {
703  if (openvas_scanner_socket == -1)
704  return;
705  FD_SET (openvas_scanner_socket, fd);
706 }
707 
714 int
716 {
717  char chr;
718  if (openvas_scanner_socket == -1)
719  return 0;
720  return recv (openvas_scanner_socket, &chr, 1, MSG_PEEK);
721 }
722 
731 int
733 {
734  if (socket > openvas_scanner_socket)
735  return 1 + socket;
736  else
737  return 1 + openvas_scanner_socket;
738 }
739 
746 int
748 {
749  if (openvas_scanner_socket == -1)
750  return 0;
752  return 0;
753  else
754  return !!gnutls_record_check_pending (openvas_scanner_session);
755 }
756 
763 int
765 {
766  return openvas_scanner_socket == -1 ? 0 : 1;
767 }
768 
777 int
778 openvas_scanner_init (int cache_mode)
779 {
780  int ret;
781 
782  if (openvas_scanner_socket == -1)
783  return -1;
784  from_scanner = g_malloc0 (from_scanner_size);
785  ret = openvas_scanner_write (cache_mode);
786  if (ret != -3)
787  {
789  return -1;
790  }
791  if (openvas_scanner_wait ())
792  return -2;
793 
794  return 0;
795 }
796 
806 int
807 openvas_scanner_set_address (const char *addr, int port)
808 {
810  {
811  g_free (openvas_scanner_unix_path);
813  }
814  if (port < 1 || port > 65535)
815  return -1;
816  memset (&openvas_scanner_address, '\0', sizeof (openvas_scanner_address));
817  openvas_scanner_address.sin_family = AF_INET;
818  openvas_scanner_address.sin_port = htons (port);
819  if (openvas_resolve (addr, &openvas_scanner_address.sin_addr, AF_INET))
820  return -1;
821 
822  return 0;
823 }
824 
832 int
833 openvas_scanner_set_unix (const char *path)
834 {
835  if (!path)
836  return -1;
837 
839  memset (&openvas_scanner_address, '\0', sizeof (openvas_scanner_address));
840  openvas_scanner_unix_path = g_strdup (path);
841 
842  return 0;
843 }
844 
852 void
853 openvas_scanner_set_certs (const char *ca_pub, const char *key_pub,
854  const char *key_priv)
855 {
857  {
858  g_free (openvas_scanner_unix_path);
860  }
861  if (ca_pub)
862  openvas_scanner_ca_pub = g_strdup (ca_pub);
863  if (key_pub)
864  openvas_scanner_key_pub = g_strdup (key_pub);
865  if (key_priv)
866  openvas_scanner_key_priv = g_strdup (key_priv);
867 }
868 
875 int
877 {
878  int attempts = 5;
879  int ret = 0;
880  while (attempts >= 0)
881  {
882  /* Add little delay in case we read before scanner write, as the socket is
883  * non-blocking. */
884  attempts = attempts - 1;
885  openvas_usleep (500000);
887 
888  switch (process_otp_scanner_input (NULL))
889  {
890  case 3:
891  /* Still loading. */
892  return 1;
893  case 5:
894  /* Empty message. Try again. */
895  ret = 1;
896  break;
897  default:
898  return 0;
899  }
900  }
901  return ret;
902 }
buffer_size_t from_scanner_start
The start of the data in the from_scanner buffer.
Definition: scanner.c:67
Protos for communication between openvas-manager and openvas-server.
int openvas_scanner_read()
Read as much from the server as the from_scanner buffer will.
Definition: scanner.c:233
void openvas_scanner_free()
Free the scanner allocated data. Doesn&#39;t close socket and terminate the session.
Definition: scanner.c:659
void openvas_scanner_set_certs(const char *ca_pub, const char *key_pub, const char *key_priv)
Set the scanner&#39;s CA Certificate, and public/private key pair.
Definition: scanner.c:853
scanner_init_state_t scanner_init_state
The initialisation state of the scanner.
Definition: otp.c:411
#define logf(format, args...)
Dummy macro, enabled with LOG.
Definition: logf.h:81
int openvas_scanner_peek()
Check if there is any data to receive from connected Scanner socket.
Definition: scanner.c:715
void reset_scanner_states()
Set the scanner initialisation state, scanner_init_state.
Definition: otp.c:442
buffer_size_t from_scanner_size
The current size of the from_scanner buffer.
Definition: scanner.c:77
char * openvas_scanner_unix_path
Definition: scanner.c:57
void openvas_scanner_fd_set(fd_set *fd)
Add connected to Scanner&#39;s socket to an fd_set.
Definition: scanner.c:701
gnutls_certificate_credentials_t openvas_scanner_credentials
Definition: scanner.c:51
int openvas_scanner_connected()
Whether we have started a connection to the Scanner using openvas_scanner_connect().
Definition: scanner.c:764
int openvas_scanner_full()
Check whether the buffer for data from Scanner is full.
Definition: scanner.c:310
int openvas_scanner_connect_unix()
Definition: scanner.c:586
int openvas_scanner_realloc()
Reallocates the from_scanner buffer to a higher size.
Definition: scanner.c:321
int openvas_scanner_wait()
Wait for the scanner socket to be writable.
Definition: scanner.c:463
int openvas_scanner_socket
Definition: scanner.c:52
gnutls_session_t openvas_scanner_session
Definition: scanner.c:50
int openvas_scanner_is_loading()
Checks whether the connected to OpenVAS Scanner is still loading plugins. To be called right after op...
Definition: scanner.c:876
int openvas_scanner_set_address(const char *addr, int port)
Set the scanner&#39;s address and port. Will try to resolve addr if it is a hostname. ...
Definition: scanner.c:807
void openvas_scanner_fork()
Reset Scanner variables after a fork.
Definition: scanner.c:575
void init_otp_data()
Initialise OTP library data.
Definition: otp.c:342
int openvas_scanner_write(int nvt_cache_mode)
Write as much as possible from the to_scanner buffer to the scanner.
Definition: scanner.c:338
char * alert_name(alert_t alert)
Return the name of an alert.
Definition: manage_sql.c:8362
void set_scanner_init_state(scanner_init_state_t state)
Set the scanner initialisation state, scanner_init_state.
Definition: otp.c:432
int scanner_init_offset
Offset into initialisation string being sent to scanner.
Definition: otp.c:416
char * openvas_scanner_ca_pub
Definition: scanner.c:54
int openvas_scanner_connect()
Create a new connection to the scanner and set it as current scanner.
Definition: scanner.c:619
buffer_size_t from_scanner_end
The end of the data in the from_scanner buffer.
Definition: scanner.c:72
int openvas_scanner_get_nfds(int socket)
Get the nfds value to use for a select() call.
Definition: scanner.c:732
int openvas_usleep(unsigned int microseconds)
Sleep for some number of microseconds, handling interrupts.
Definition: utils.c:39
char to_server[]
int openvas_scanner_init(int cache_mode)
Initializes the already setup connection with the Scanner.
Definition: scanner.c:778
int openvas_scanner_session_peek()
Check if there is any data to receive from connected Scanner session.
Definition: scanner.c:747
int to_server_end
int openvas_scanner_set_unix(const char *path)
Set the scanner&#39;s unix socket path.
Definition: scanner.c:833
buffer_size_t from_scanner_max_size
The max size of the from_scanner buffer.
Definition: scanner.c:82
int to_server_start
char * openvas_scanner_key_priv
Definition: scanner.c:56
int process_otp_scanner_input(void(*progress)())
Process any lines available in from_scanner.
Definition: otp.c:781
char * from_scanner
Buffer of input from the scanner.
Definition: scanner.c:62
struct sockaddr_in openvas_scanner_address
Definition: scanner.c:53
unsigned int buffer_size_t
Definition: types.h:31
int openvas_scanner_fd_isset(fd_set *fd)
Check if connected to Scanner is set in an fd_set.
Definition: scanner.c:688
char * openvas_scanner_key_pub
Definition: scanner.c:55
int openvas_scanner_close()
Finish the connection to the Scanner and free internal buffers.
Definition: scanner.c:551