OpenVAS Libraries  9.0.3
openvas_server.c
Go to the documentation of this file.
1 
37 #define _GNU_SOURCE
38 
39 #ifdef _WIN32
40 
41 #define WINVER 0x0501
42 #define SHUT_RDWR 2
43 #include <winsock2.h>
44 #include <winsock.h>
45 
46 #else
47 
48 #include <arpa/inet.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <netdb.h>
52 #include <signal.h>
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 
56 #endif
57 
58 #include <unistd.h>
59 #include <gcrypt.h>
60 #include <glib.h>
61 #include <string.h>
62 #include <stdio.h>
63 
64 #include "openvas_server.h"
65 
71 #undef G_LOG_DOMAIN
72 
75 #define G_LOG_DOMAIN "lib serv"
76 
80 struct sockaddr_in address;
81 
82 
83 
84 static int server_attach_internal (int, gnutls_session_t *,
85  const char *, int);
86 static int server_new_internal (unsigned int, const char *,
87  const gchar *,
88  const gchar *, const gchar *,
89  gnutls_session_t *,
90  gnutls_certificate_credentials_t *);
91 
92 
93 
94 /* Connections. */
95 
103 static int
104 close_unix (openvas_connection_t *client_connection)
105 {
106  /* Turn off blocking. */
107  if (fcntl (client_connection->socket, F_SETFL, O_NONBLOCK) == -1)
108  {
109  g_warning ("%s: failed to set server socket flag: %s\n", __FUNCTION__,
110  strerror (errno));
111  return -1;
112  }
113 
114  if (shutdown (client_connection->socket, SHUT_RDWR) == -1)
115  {
116  if (errno == ENOTCONN)
117  return 0;
118  g_warning ("%s: failed to shutdown server socket: %s\n", __FUNCTION__,
119  strerror (errno));
120  return -1;
121  }
122 
123  if (close (client_connection->socket) == -1)
124  {
125  g_warning ("%s: failed to close server socket: %s\n", __FUNCTION__,
126  strerror (errno));
127  return -1;
128  }
129 
130  return 0;
131 }
132 
138 void
140 {
141  if (client_connection->tls)
142  openvas_server_free (client_connection->socket,
143  client_connection->session,
144  client_connection->credentials);
145  else
146  close_unix (client_connection);
147 }
148 
149 
150 /* Certificate verification. */
151 
159 int
160 openvas_server_verify (gnutls_session_t session)
161 {
162  unsigned int status;
163  int ret;
164 
165  ret = gnutls_certificate_verify_peers2 (session, &status);
166  if (ret < 0)
167  {
168  g_warning ("%s: failed to verify peers: %s",
169  __FUNCTION__,
170  gnutls_strerror (ret));
171  return -1;
172  }
173 
174  if (status & GNUTLS_CERT_INVALID)
175  g_warning ("%s: the certificate is not trusted", __FUNCTION__);
176 
177  if (status & GNUTLS_CERT_SIGNER_NOT_CA)
178  g_warning ("%s: the certificate's issuer is not a CA", __FUNCTION__);
179 
180  if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
181  g_warning ("%s: the certificate was signed using an insecure algorithm",
182  __FUNCTION__);
183 
184  if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
185  g_warning ("%s: the certificate hasn't got a known issuer", __FUNCTION__);
186 
187  if (status & GNUTLS_CERT_REVOKED)
188  g_warning ("%s: the certificate has been revoked", __FUNCTION__);
189 
190  if (status & GNUTLS_CERT_EXPIRED)
191  g_warning ("%s: the certificate has expired", __FUNCTION__);
192 
193  if (status & GNUTLS_CERT_NOT_ACTIVATED)
194  g_warning ("%s: the certificate is not yet activated", __FUNCTION__);
195 
196  if (status)
197  return 1;
198 
199  return 0;
200 }
201 
210 int
211 load_gnutls_file (const char *file, gnutls_datum_t *loaded_file)
212 {
213  FILE *f = NULL;
214  int64_t filelen;
215  void *ptr;
216 
217  if (!(f = fopen (file, "r"))
218  || fseek (f, 0, SEEK_END) != 0
219  || (filelen = ftell (f)) < 0
220  || fseek (f, 0, SEEK_SET) != 0
221  || !(ptr = g_malloc0 ((size_t) filelen))
222  || fread (ptr, 1, (size_t) filelen, f) < (size_t) filelen)
223  {
224  if (f)
225  fclose (f);
226  return -1;
227  }
228 
229  loaded_file->data = ptr;
230  loaded_file->size = filelen;
231  fclose (f);
232  return 0;
233 }
234 
240 void
241 unload_gnutls_file(gnutls_datum_t *data)
242 {
243  if (data)
244  g_free (data->data);
245 }
246 
247 static char *cert_pub_mem = NULL;
248 static char *cert_priv_mem = NULL;
249 
250 static void
251 set_cert_pub_mem (const char *data)
252 {
253  if (cert_pub_mem)
254  g_free (cert_pub_mem);
255  cert_pub_mem = g_strdup (data);
256 }
257 
258 static void
259 set_cert_priv_mem (const char *data)
260 {
261  if (cert_priv_mem)
262  g_free (cert_priv_mem);
263  cert_priv_mem = g_strdup (data);
264 }
265 
266 static const char *
267 get_cert_priv_mem ()
268 {
269  return cert_priv_mem;
270 }
271 
272 static const char *
273 get_cert_pub_mem ()
274 {
275  return cert_pub_mem;
276 }
277 
278 static int
279 client_cert_callback (gnutls_session_t session,
280  const gnutls_datum_t * req_ca_rdn, int nreqs,
281  const gnutls_pk_algorithm_t * sign_algos,
282  int sign_algos_length, gnutls_retr2_st * st)
283 {
284  int ret;
285  gnutls_datum_t data;
286  static gnutls_x509_crt_t crt;
287  static gnutls_x509_privkey_t key;
288 
289  (void) session;
290  (void) req_ca_rdn;
291  (void) nreqs;
292  (void) sign_algos;
293  (void) sign_algos_length;
294  data.data = (unsigned char *) g_strdup (get_cert_pub_mem ());
295  data.size = strlen (get_cert_pub_mem ());
296  gnutls_x509_crt_init (&crt);
297  ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
298  g_free (data.data);
299  if (ret)
300  return ret;
301  st->cert.x509 = &crt;
302  st->cert_type = GNUTLS_CRT_X509;
303  st->ncerts = 1;
304 
305  data.data = (unsigned char *) g_strdup (get_cert_priv_mem ());
306  data.size = strlen (get_cert_priv_mem ());
307  gnutls_x509_privkey_init (&key);
308  ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
309  g_free (data.data);
310  if (ret)
311  return ret;
312  st->key.x509 = key;
313  st->key_type = GNUTLS_PRIVKEY_X509;
314  return 0;
315 }
316 
330 int
331 openvas_server_open_verify (gnutls_session_t *session, const char *host,
332  int port, const char *ca_mem,
333  const char *pub_mem, const char *priv_mem,
334  int verify)
335 {
336  int ret;
337  int server_socket;
338  struct addrinfo address_hints;
339  struct addrinfo *addresses, *address;
340  gchar *port_string;
341 #ifdef _WIN32
342  WSADATA wsaData;
343 #endif
344 
345  gnutls_certificate_credentials_t credentials;
346 
354  if (openvas_server_new_mem (GNUTLS_CLIENT, ca_mem, pub_mem, priv_mem, session,
355  &credentials))
356  {
357  g_warning ("Failed to create client TLS session.");
358  return -1;
359  }
360 
361  if (ca_mem && pub_mem && priv_mem)
362  {
363  set_cert_pub_mem (pub_mem);
364  set_cert_priv_mem (priv_mem);
365 
366  gnutls_certificate_set_retrieve_function (credentials,
367  client_cert_callback);
368  }
369 
370  /* Create the port string. */
371 
372  port_string = g_strdup_printf ("%i", port);
373 
374  /* WSA Start for win32 */
375 #ifdef _WIN32
376  if (WSAStartup (MAKEWORD (2, 2), &wsaData))
377  {
378  g_warning ("WSAStartup failed");
379  gnutls_deinit (*session);
380  gnutls_certificate_free_credentials (credentials);
381  g_free (port_string);
382  return -1;
383  }
384 #endif
385 
386  /* Get all possible addresses. */
387 
388  memset (&address_hints, 0, sizeof (address_hints));
389  address_hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6. */
390  address_hints.ai_socktype = SOCK_STREAM;
391 #ifndef _WIN32
392  address_hints.ai_flags = AI_NUMERICSERV;
393 #endif
394  address_hints.ai_protocol = 0;
395 
396  if (getaddrinfo (host, port_string, &address_hints, &addresses))
397  {
398  g_free (port_string);
399  g_warning ("Failed to get server addresses for %s: %s", host,
400  gai_strerror (errno));
401  gnutls_deinit (*session);
402  gnutls_certificate_free_credentials (credentials);
403  return -1;
404  }
405  g_free (port_string);
406 
407  /* Try to connect to each address in turn. */
408 
409  for (address = addresses; address; address = address->ai_next)
410  {
411  /* Make server socket. */
412 
413  if (address->ai_family == AF_INET6)
414  server_socket = socket (PF_INET6, SOCK_STREAM, 0);
415  else
416  server_socket = socket (PF_INET, SOCK_STREAM, 0);
417  if (server_socket == -1)
418  {
419  g_warning ("Failed to create server socket");
420  freeaddrinfo (addresses);
421  gnutls_deinit (*session);
422  gnutls_certificate_free_credentials (credentials);
423  return -1;
424  }
425 
428  /* Connect to server. */
429 
430  if (connect (server_socket, address->ai_addr, address->ai_addrlen) == -1)
431  {
432  close (server_socket);
433  continue;
434  }
435  break;
436  }
437 
438  freeaddrinfo (addresses);
439 
440  if (address == NULL)
441  {
442  g_warning ("Failed to connect to server");
443  gnutls_deinit (*session);
444  gnutls_certificate_free_credentials (credentials);
445  return -1;
446  }
447 
448  g_debug (" Connected to server '%s' port %d.", host, port);
449 
450  /* Complete setup of server session. */
451  ret = server_attach_internal (server_socket, session, host, port);
452  if (ret)
453  {
454  if (ret == -2)
455  {
456  close (server_socket);
457  gnutls_deinit (*session);
458  gnutls_certificate_free_credentials (credentials);
459  }
460  return -1;
461  }
462  if (verify && openvas_server_verify (*session))
463  return -1;
464 
465  return server_socket;
466 }
467 
482 int
483 openvas_server_open_with_cert (gnutls_session_t *session, const char *host,
484  int port, const char *ca_mem,
485  const char *pub_mem, const char *priv_mem)
486 {
487  return openvas_server_open_verify (session, host, port, ca_mem, pub_mem,
488  priv_mem, ca_mem && pub_mem && priv_mem);
489 }
490 
500 int
501 openvas_server_open (gnutls_session_t * session, const char *host, int port)
502 {
503  return openvas_server_open_with_cert (session, host, port, NULL, NULL, NULL);
504 }
505 
514 int
515 openvas_server_close (int socket, gnutls_session_t session)
516 {
517  return openvas_server_free (socket, session, NULL);
518 }
519 
527 void
529 {
530  openvas_connection_free (connection);
531 }
532 
542 int
543 openvas_server_connect (int server_socket, struct sockaddr_in *server_address,
544  gnutls_session_t * server_session)
545 {
546  int ret;
547 
548  if (connect (server_socket, (struct sockaddr *) server_address,
549  sizeof (struct sockaddr_in)) == -1)
550  {
551  g_warning ("%s: failed to connect to server: %s\n", __FUNCTION__,
552  strerror (errno));
553  return -1;
554  }
555  g_debug (" Connected to server on socket %i.\n", server_socket);
556 
557  ret = openvas_server_attach (server_socket, server_session);
558  if (ret < 0)
559  return ret;
560  return openvas_server_verify (*server_session);
561 }
562 
574 static int
575 server_attach_internal (int socket, gnutls_session_t * session,
576  const char *host, int port)
577 {
578  unsigned int retries;
579 #ifndef _WIN32
580  struct sigaction new_action, original_action;
581 #endif
582 
583  gnutls_transport_set_ptr (*session,
584  (gnutls_transport_ptr_t) GSIZE_TO_POINTER (socket));
585 
586 #ifndef _WIN32
587  new_action.sa_flags = 0;
588  if (sigemptyset (&new_action.sa_mask))
589  return -1;
590  new_action.sa_handler = SIG_IGN;
591  if (sigaction (SIGPIPE, &new_action, &original_action))
592  return -1;
593 #endif
594 
595  retries = 0;
596  while (1)
597  {
598  int ret = gnutls_handshake (*session);
599  if (ret >= 0)
600  break;
601  if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
602  {
603  if (retries > 10)
604  usleep (MIN ((retries - 10) * 10000, 5000000));
605  retries++;
606  continue;
607  }
608  if (host)
609  g_debug ("Failed to shake hands with server '%s' port %d: %s",
610  host, port, gnutls_strerror (ret));
611  else
612  g_debug ("Failed to shake hands with peer: %s",
613  gnutls_strerror (ret));
614  if (shutdown (socket, SHUT_RDWR) == -1)
615  g_debug ("Failed to shutdown server socket");
616 #ifndef _WIN32
617  sigaction (SIGPIPE, &original_action, NULL);
618 #endif
619  return -2;
620  }
621  if (host)
622  g_debug (" Shook hands with server '%s' port %d.", host, port);
623  else
624  g_debug (" Shook hands with peer.");
625 
626 #ifndef _WIN32
627  if (sigaction (SIGPIPE, &original_action, NULL))
628  return -1;
629 #endif
630 
631  return 0;
632 }
633 
643 int
644 openvas_server_attach (int socket, gnutls_session_t * session)
645 {
646  int ret;
647 
648  ret = server_attach_internal (socket, session, NULL, 0);
649  return ret? -1 : 0;
650 }
651 
663 static int
664 openvas_server_vsendf_internal (gnutls_session_t *session, const char *fmt,
665  va_list ap, int quiet)
666 {
667 #ifndef _WIN32
668  struct sigaction new_action, original_action;
669 #endif
670  char *sref, *string;
671  int rc = 0, left;
672 
673 #ifndef _WIN32
674  new_action.sa_flags = 0;
675  if (sigemptyset (&new_action.sa_mask))
676  return -1;
677  new_action.sa_handler = SIG_IGN;
678  if (sigaction (SIGPIPE, &new_action, &original_action))
679  return -1;
680 #endif
681 
682  left = vasprintf (&string, fmt, ap);
683  if (left == -1)
684  string = NULL;
685 
686  sref = string;
687  while (left > 0)
688  {
689  ssize_t count;
690 
691  if (quiet == 0)
692  g_debug (" send %d from %.*s[...]",
693  left, left < 30 ? left : 30, string);
694  count = gnutls_record_send (*session, string, left);
695  if (count < 0)
696  {
697  if (count == GNUTLS_E_INTERRUPTED)
698  /* Interrupted, try write again. */
699  continue;
700  if (count == GNUTLS_E_REHANDSHAKE)
701  {
702  /* \todo Rehandshake. */
703  if (quiet == 0)
704  g_message (" %s rehandshake", __FUNCTION__);
705  continue;
706  }
707  g_warning ("Failed to write to server: %s", gnutls_strerror (count));
708 
709 #ifndef _WIN32
710  sigaction (SIGPIPE, &original_action, NULL);
711 #endif
712 
713  rc = -1;
714  goto out;
715  }
716  if (count == 0)
717  {
718  /* Server closed connection. */
719  if (quiet == 0)
720  g_debug ("= server closed");
721 
722 #ifndef _WIN32
723  sigaction (SIGPIPE, &original_action, NULL);
724 #endif
725 
726  rc = 1;
727  goto out;
728  }
729  if (quiet == 0)
730  g_debug ("=> %.*s", (int) count, string);
731  string += count;
732  left -= count;
733  }
734  if (quiet == 0)
735  g_debug ("=> done");
736 
737 #ifndef _WIN32
738  sigaction (SIGPIPE, &original_action, NULL);
739 #endif
740 
741 out:
742  g_free (sref);
743  return rc;
744 }
745 
757 static int
758 unix_vsendf_internal (int socket, const char *fmt, va_list ap, int quiet)
759 {
760 #ifndef _WIN32
761  struct sigaction new_action, original_action;
762 #endif
763  char *string_start, *string;
764  int rc = 0, left;
765 
766 #ifndef _WIN32
767  new_action.sa_flags = 0;
768  if (sigemptyset (&new_action.sa_mask))
769  // FIX warning
770  return -1;
771  new_action.sa_handler = SIG_IGN;
772  if (sigaction (SIGPIPE, &new_action, &original_action))
773  // FIX warning
774  return -1;
775 #endif
776 
777  left = vasprintf (&string, fmt, ap);
778  if (left == -1)
779  string = NULL;
780 
781  string_start = string;
782  while (left > 0)
783  {
784  ssize_t count;
785 
786  if (quiet == 0)
787  g_debug (" send %d from %.*s[...]",
788  left, left < 30 ? left : 30, string);
789  count = write (socket, string, left);
790  if (count < 0)
791  {
792  if (errno == EINTR || errno == EAGAIN)
793  continue;
794  g_warning ("Failed to write to server: %s", strerror (errno));
795 
796 #ifndef _WIN32
797  sigaction (SIGPIPE, &original_action, NULL);
798 #endif
799 
800  rc = -1;
801  goto out;
802  }
803  if (quiet == 0)
804  g_debug ("=> %.*s", (int) count, string);
805 
806  string += count;
807  left -= count;
808  }
809  if (quiet == 0)
810  g_debug ("=> done");
811 
812 #ifndef _WIN32
813  sigaction (SIGPIPE, &original_action, NULL);
814 #endif
815 
816 out:
817  g_free (string_start);
818  return rc;
819 }
820 
832 static int
833 openvas_connection_vsendf_internal (openvas_connection_t *connection,
834  const char *fmt, va_list ap, int quiet)
835 {
836  if (connection->tls)
837  return openvas_server_vsendf_internal (&connection->session, fmt, ap, quiet);
838  return unix_vsendf_internal (connection->socket, fmt, ap, quiet);
839 }
840 
850 int
851 openvas_server_vsendf (gnutls_session_t *session, const char *fmt, va_list ap)
852 {
853  return openvas_server_vsendf_internal (session, fmt, ap, 0);
854 }
855 
865 int
866 openvas_connection_vsendf (openvas_connection_t *connection, const char *fmt,
867  va_list ap)
868 {
869  return openvas_connection_vsendf_internal (connection, fmt, ap, 0);
870 }
871 
881 int
882 openvas_server_vsendf_quiet (gnutls_session_t *session, const char *fmt,
883  va_list ap)
884 {
885  return openvas_server_vsendf_internal (session, fmt, ap, 1);
886 }
887 
897 int
899  const char *fmt,
900  va_list ap)
901 {
902  return openvas_connection_vsendf_internal (connection, fmt, ap, 1);
903 }
904 
913 int
914 openvas_server_sendf (gnutls_session_t * session, const char *format, ...)
915 {
916  va_list ap;
917  int rc;
918 
919  va_start (ap, format);
920  rc = openvas_server_vsendf (session, format, ap);
921  va_end (ap);
922  return rc;
923 }
924 
933 int
935  const char *format,
936  ...)
937 {
938  va_list ap;
939  int rc;
940 
941  va_start (ap, format);
942  rc = openvas_connection_vsendf (connection, format, ap);
943  va_end (ap);
944  return rc;
945 }
946 
955 int
956 openvas_server_sendf_quiet (gnutls_session_t * session, const char *format, ...)
957 {
958  va_list ap;
959  int rc;
960 
961  va_start (ap, format);
962  rc = openvas_server_vsendf_quiet (session, format, ap);
963  va_end (ap);
964  return rc;
965 }
966 
975 int
977  const char *format,
978  ...)
979 {
980  va_list ap;
981  int rc;
982 
983  va_start (ap, format);
984  rc = openvas_connection_vsendf_quiet (connection, format, ap);
985  va_end (ap);
986  return rc;
987 }
988 
999 int
1000 openvas_server_sendf_xml (gnutls_session_t * session, const char *format, ...)
1001 {
1002  va_list ap;
1003  gchar *msg;
1004  int rc;
1005 
1006  va_start (ap, format);
1007  msg = g_markup_vprintf_escaped (format, ap);
1008  rc = openvas_server_sendf (session, "%s", msg);
1009  g_free (msg);
1010  va_end (ap);
1011  return rc;
1012 }
1013 
1024 int
1026  const char *format, ...)
1027 {
1028  va_list ap;
1029  gchar *msg;
1030  int rc;
1031 
1032  va_start (ap, format);
1033  msg = g_markup_vprintf_escaped (format, ap);
1034  rc = openvas_connection_sendf (connection, "%s", msg);
1035  g_free (msg);
1036  va_end (ap);
1037  return rc;
1038 }
1039 
1052 int
1053 openvas_server_sendf_xml_quiet (gnutls_session_t * session,
1054  const char *format, ...)
1055 {
1056  va_list ap;
1057  gchar *msg;
1058  int rc;
1059 
1060  va_start (ap, format);
1061  msg = g_markup_vprintf_escaped (format, ap);
1062  rc = openvas_server_sendf_quiet (session, "%s", msg);
1063  g_free (msg);
1064  va_end (ap);
1065  return rc;
1066 }
1067 
1080 int
1082  const char *format,
1083  ...)
1084 {
1085  va_list ap;
1086  gchar *msg;
1087  int rc;
1088 
1089  va_start (ap, format);
1090  msg = g_markup_vprintf_escaped (format, ap);
1091  rc = openvas_connection_sendf_quiet (connection, "%s", msg);
1092  g_free (msg);
1093  va_end (ap);
1094  return rc;
1095 }
1096 
1097 static int
1098 server_new_gnutls_init (gnutls_certificate_credentials_t *server_credentials)
1099 {
1100  /* Turn off use of /dev/random, as this can block. */
1101  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1102 
1103  /* Initialize security library. */
1104  if (gnutls_global_init ())
1105  {
1106  g_warning ("Failed to initialize GNUTLS.");
1107  return -1;
1108  }
1109  /* Setup server session. */
1110  if (gnutls_certificate_allocate_credentials (server_credentials))
1111  {
1112  g_warning ("%s: failed to allocate server credentials\n", __FUNCTION__);
1113  return -1;
1114  }
1115  return 0;
1116 }
1117 
1118 static int
1119 server_new_gnutls_set (unsigned int end_type, const char *priority,
1120  gnutls_session_t *server_session,
1121  gnutls_certificate_credentials_t *server_credentials)
1122 {
1123  int err_gnutls;
1124 
1125  if (gnutls_init (server_session, end_type))
1126  {
1127  g_warning ("%s: failed to initialise server session\n", __FUNCTION__);
1128  return -1;
1129  }
1130 
1131  /* Depending on gnutls version different priority strings are
1132  possible. At least from 3.0 this is an option:
1133  "NONE:+VERS-TLS1.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"
1134  But in fact this function is only for OpenVAS internal
1135  purposes, not for scanning abilities. So, the conservative "NORMAL"
1136  is chosen.
1137  */
1138 
1139  if ((err_gnutls = gnutls_priority_set_direct (*server_session,
1140  priority ? priority : "NORMAL",
1141  NULL)))
1142  {
1143  g_warning ("%s: failed to set tls priorities: %s\n", __FUNCTION__,
1144  gnutls_strerror (err_gnutls));
1145  gnutls_deinit (*server_session);
1146  return -1;
1147  }
1148 
1149  if (gnutls_credentials_set
1150  (*server_session, GNUTLS_CRD_CERTIFICATE, *server_credentials))
1151  {
1152  g_warning ("%s: failed to set server credentials\n", __FUNCTION__);
1153  gnutls_deinit (*server_session);
1154  return -1;
1155  }
1156 
1157  if (end_type == GNUTLS_SERVER)
1158  gnutls_certificate_server_set_request (*server_session,
1159  GNUTLS_CERT_REQUEST);
1160  return 0;
1161 }
1162 
1177 static int
1178 server_new_internal (unsigned int end_type, const char *priority,
1179  const gchar *ca_cert_file,
1180  const gchar *cert_file, const gchar *key_file,
1181  gnutls_session_t *server_session,
1182  gnutls_certificate_credentials_t *server_credentials)
1183 {
1184  if (server_new_gnutls_init (server_credentials))
1185  return -1;
1186 
1187  if (cert_file && key_file
1188  &&
1189  (gnutls_certificate_set_x509_key_file
1190  (*server_credentials, cert_file, key_file, GNUTLS_X509_FMT_PEM) < 0))
1191  {
1192  g_warning ("%s: failed to set credentials key file\n", __FUNCTION__);
1193  g_warning ("%s: cert file: %s\n", __FUNCTION__, cert_file);
1194  g_warning ("%s: key file : %s\n", __FUNCTION__, key_file);
1195  gnutls_certificate_free_credentials (*server_credentials);
1196  return -1;
1197  }
1198 
1199  if (ca_cert_file
1200  &&
1201  (gnutls_certificate_set_x509_trust_file
1202  (*server_credentials, ca_cert_file, GNUTLS_X509_FMT_PEM) < 0))
1203  {
1204  g_warning ("%s: failed to set credentials trust file: %s\n", __FUNCTION__,
1205  ca_cert_file);
1206  gnutls_certificate_free_credentials (*server_credentials);
1207  return -1;
1208  }
1209 
1210  if (server_new_gnutls_set (end_type, priority, server_session,
1211  server_credentials))
1212  {
1213  gnutls_certificate_free_credentials (*server_credentials);
1214  return -1;
1215  }
1216 
1217  return 0;
1218 }
1219 
1233 int
1234 openvas_server_new (unsigned int end_type,
1235  gchar * ca_cert_file,
1236  gchar * cert_file, gchar * key_file,
1237  gnutls_session_t * server_session,
1238  gnutls_certificate_credentials_t * server_credentials)
1239 {
1240  return server_new_internal (end_type, NULL,
1241  ca_cert_file, cert_file, key_file,
1242  server_session, server_credentials);
1243 }
1244 
1258 int
1259 openvas_server_new_mem (unsigned int end_type, const char *ca_cert,
1260  const char *pub_key, const char *priv_key,
1261  gnutls_session_t *session,
1262  gnutls_certificate_credentials_t *credentials)
1263 {
1264  if (server_new_gnutls_init (credentials))
1265  return -1;
1266 
1267  if (pub_key && priv_key)
1268  {
1269  int ret;
1270  gnutls_datum_t pub, priv;
1271 
1272  pub.data = (void *) pub_key;
1273  pub.size = strlen (pub_key);
1274  priv.data = (void *) priv_key;
1275  priv.size = strlen (priv_key);
1276 
1277  ret = gnutls_certificate_set_x509_key_mem (*credentials, &pub, &priv,
1278  GNUTLS_X509_FMT_PEM);
1279  if (ret < 0)
1280  {
1281  g_warning ("%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1282  return -1;
1283  }
1284  }
1285 
1286  if (ca_cert)
1287  {
1288  int ret;
1289  gnutls_datum_t data;
1290 
1291  data.data = (void *) ca_cert;
1292  data.size = strlen (ca_cert);
1293  ret = gnutls_certificate_set_x509_trust_mem (*credentials, &data,
1294  GNUTLS_X509_FMT_PEM);
1295  if (ret < 0)
1296  {
1297  g_warning ("%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1298  gnutls_certificate_free_credentials (*credentials);
1299  return -1;
1300  }
1301  }
1302 
1303  if (server_new_gnutls_set (end_type, NULL, session, credentials))
1304  {
1305  gnutls_certificate_free_credentials (*credentials);
1306  return -1;
1307  }
1308 
1309  return 0;
1310 }
1311 
1320 int
1321 set_gnutls_dhparams (gnutls_certificate_credentials_t creds,
1322  const char *dhparams_file)
1323 {
1324  int ret;
1325  gnutls_datum_t data;
1326 
1327  if (!creds || !dhparams_file)
1328  return -1;
1329 
1330  if (load_gnutls_file (dhparams_file, &data))
1331  return -1;
1332  gnutls_dh_params_t params = g_malloc0 (sizeof (gnutls_dh_params_t));
1333  ret = gnutls_dh_params_import_pkcs3 (params, &data, GNUTLS_X509_FMT_PEM);
1334  unload_gnutls_file (&data);
1335  if (ret)
1336  return -1;
1337  else
1338  gnutls_certificate_set_dh_params (creds, params);
1339  return 0;
1340 }
1341 
1354 int
1355 openvas_server_free (int server_socket, gnutls_session_t server_session,
1356  gnutls_certificate_credentials_t server_credentials)
1357 {
1358 #ifndef _WIN32
1359  struct sigaction new_action, original_action;
1360 #endif
1361 
1362 #if 0
1363  /* Turn on blocking. */
1364  // FIX get flags first
1365  if (fcntl (server_socket, F_SETFL, 0L) == -1)
1366  {
1367  g_warning ("%s: failed to set server socket flag: %s\n", __FUNCTION__,
1368  strerror (errno));
1369  return -1;
1370  }
1371 #endif
1372 #if 1
1373  /* Turn off blocking. */
1374  // FIX get flags first
1375 #ifndef _WIN32
1376  if (fcntl (server_socket, F_SETFL, O_NONBLOCK) == -1)
1377  {
1378  g_warning ("%s: failed to set server socket flag: %s\n", __FUNCTION__,
1379  strerror (errno));
1380  return -1;
1381  }
1382 #endif
1383 #endif
1384 
1385 #ifndef _WIN32
1386  new_action.sa_flags = 0;
1387  if (sigemptyset (&new_action.sa_mask))
1388  return -1;
1389  new_action.sa_handler = SIG_IGN;
1390  if (sigaction (SIGPIPE, &new_action, &original_action))
1391  return -1;
1392 #endif
1393 
1394  while (1)
1395  {
1396  int ret = gnutls_bye (server_session, GNUTLS_SHUT_WR);
1397  if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
1398  {
1399  continue;
1400  }
1401  if (ret)
1402  {
1403  g_debug (" Failed to gnutls_bye: %s\n",
1404  gnutls_strerror ((int) ret));
1405  /* Carry on successfully anyway, as this often fails, perhaps
1406  * because the server is closing the connection first. */
1407  break;
1408  }
1409  break;
1410  }
1411 
1412  /* The former separate code in openvas_server_close and here
1413  differed in the order the TLS session and socket was closed. The
1414  way we do it here seems to be the right thing but for full
1415  backward compatibility we do it for calls from
1416  openvas_server_close in the old way. We can distinguish the two
1417  modes by the existence of server_credentials. */
1418  if (server_credentials)
1419  {
1420 #ifndef _WIN32
1421  if (sigaction (SIGPIPE, &original_action, NULL))
1422  return -1;
1423 
1424  if (shutdown (server_socket, SHUT_RDWR) == -1)
1425  {
1426  if (errno == ENOTCONN)
1427  return 0;
1428  g_warning ("%s: failed to shutdown server socket: %s\n", __FUNCTION__,
1429  strerror (errno));
1430  return -1;
1431  }
1432 #endif
1433 
1434  if (close (server_socket) == -1)
1435  {
1436  g_warning ("%s: failed to close server socket: %s\n", __FUNCTION__,
1437  strerror (errno));
1438  return -1;
1439  }
1440  gnutls_deinit (server_session);
1441  gnutls_certificate_free_credentials (server_credentials);
1442  }
1443  else
1444  {
1445  gnutls_deinit (server_session);
1446 #ifndef _WIN32
1447  if (sigaction (SIGPIPE, &original_action, NULL))
1448  return -1;
1449 #endif
1450  close (server_socket);
1451  }
1452 
1453  gnutls_global_deinit ();
1454 
1455  return 0;
1456 }
int openvas_server_new(unsigned int end_type, gchar *ca_cert_file, gchar *cert_file, gchar *key_file, gnutls_session_t *server_session, gnutls_certificate_credentials_t *server_credentials)
Make a session for connecting to a server.
int openvas_server_open_verify(gnutls_session_t *session, const char *host, int port, const char *ca_mem, const char *pub_mem, const char *priv_mem, int verify)
Connect to the server using a given host, port and cert.
int openvas_connection_vsendf(openvas_connection_t *connection, const char *fmt, va_list ap)
Send a string to the server.
int set_gnutls_dhparams(gnutls_certificate_credentials_t creds, const char *dhparams_file)
Set a gnutls session&#39;s Diffie-Hellman parameters.
void openvas_connection_free(openvas_connection_t *client_connection)
Free connection.
int openvas_server_sendf(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
int openvas_connection_sendf_xml(openvas_connection_t *connection, const char *format,...)
Format and send an XML string to the server.
gnutls_session_t session
Session.
int openvas_server_sendf_xml(gnutls_session_t *session, const char *format,...)
Format and send an XML string to the server.
gnutls_certificate_credentials_t credentials
Credentials.
void unload_gnutls_file(gnutls_datum_t *data)
Unloads a gnutls_datum_t struct&#39;s data.
int openvas_server_new_mem(unsigned int end_type, const char *ca_cert, const char *pub_key, const char *priv_key, gnutls_session_t *session, gnutls_certificate_credentials_t *credentials)
Make a session for connecting to a server, with certificates stored in memory.
int openvas_server_open(gnutls_session_t *session, const char *host, int port)
Connect to the server using a given host and port.
void openvas_connection_close(openvas_connection_t *connection)
Close a server connection and its socket.
int openvas_server_attach(int socket, gnutls_session_t *session)
Attach a socket to a session, and shake hands with the peer.
int openvas_connection_vsendf_quiet(openvas_connection_t *connection, const char *fmt, va_list ap)
Send a string to the server, refraining from logging besides warnings.
int openvas_server_vsendf_quiet(gnutls_session_t *session, const char *fmt, va_list ap)
Send a string to the server, refraining from logging besides warnings.
int openvas_server_sendf_quiet(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
int openvas_server_connect(int server_socket, struct sockaddr_in *server_address, gnutls_session_t *server_session)
Connect to a server.
struct sockaddr_in address
Server address.
int openvas_server_sendf_xml_quiet(gnutls_session_t *session, const char *format,...)
Format and send an XML string to the server.
int openvas_server_vsendf(gnutls_session_t *session, const char *fmt, va_list ap)
Send a string to the server.
GnuTLS based functions for communication with an OpenVAS server - header file.
int tls
Whether uses TCP-TLS (vs UNIX socket).
int openvas_server_close(int socket, gnutls_session_t session)
Close a server connection and its socket.
gchar * string
int openvas_connection_sendf(openvas_connection_t *connection, const char *format,...)
Format and send a string to the server.
int openvas_server_open_with_cert(gnutls_session_t *session, const char *host, int port, const char *ca_mem, const char *pub_mem, const char *priv_mem)
Connect to the server using a given host, port and cert.
int openvas_connection_sendf_xml_quiet(openvas_connection_t *connection, const char *format,...)
Format and send an XML string to the server.
int openvas_server_free(int server_socket, gnutls_session_t server_session, gnutls_certificate_credentials_t server_credentials)
Cleanup a server session.
int load_gnutls_file(const char *file, gnutls_datum_t *loaded_file)
Loads a file&#39;s data into gnutls_datum_t struct.
int openvas_server_verify(gnutls_session_t session)
Verify certificate.
int openvas_connection_sendf_quiet(openvas_connection_t *connection, const char *format,...)
Format and send a string to the server.