Greenbone Vulnerability Management Libraries 22.8.0
serverutils.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
14#define _GNU_SOURCE
15
16#include "serverutils.h"
17
18#include "../base/hosts.h" /* for is_hostname, is_ipv4_address, is_ipv6_add.. */
19
20#include <arpa/inet.h>
21#include <errno.h> /* for errno, ENOTCONN, EAGAIN */
22#include <fcntl.h> /* for fcntl, F_SETFL, O_NONBLOCK */
23#include <gcrypt.h> /* for gcry_control */
24#include <glib.h> /* for g_warning, g_free, g_debug, gchar, g_markup... */
25#include <gnutls/x509.h> /* for gnutls_x509_crt_..., gnutls_x509_privkey_... */
26#include <netdb.h> /* for addrinfo, freeaddrinfo, gai_strerror, getad... */
27#include <signal.h> /* for sigaction, SIGPIPE, sigemptyset, SIG_IGN */
28#include <stdio.h> /* for fclose, FILE, SEEK_END, SEEK_SET */
29#include <string.h> /* for strerror, strlen, memset */
30#include <sys/socket.h> /* for shutdown, connect, socket, SHUT_RDWR, SOCK_... */
31#include <sys/types.h>
32#include <unistd.h> /* for close, ssize_t, usleep */
33
34#undef G_LOG_DOMAIN
38#define G_LOG_DOMAIN "libgvm util"
39
40static int
41server_attach_internal (int, gnutls_session_t *, const char *, int);
42static int
43server_new_internal (unsigned int, const char *, const gchar *, const gchar *,
44 const gchar *, gnutls_session_t *,
45 gnutls_certificate_credentials_t *);
46
47/* Connections. */
48
56static int
57close_unix (gvm_connection_t *client_connection)
58{
59 /* Turn off blocking. */
60 if (fcntl (client_connection->socket, F_SETFL, O_NONBLOCK) == -1)
61 {
62 g_warning ("%s: failed to set server socket flag: %s\n", __func__,
63 strerror (errno));
64 return -1;
65 }
66
67 if (shutdown (client_connection->socket, SHUT_RDWR) == -1)
68 {
69 if (errno == ENOTCONN)
70 return 0;
71 g_warning ("%s: failed to shutdown server socket: %s\n", __func__,
72 strerror (errno));
73 return -1;
74 }
75
76 if (close (client_connection->socket) == -1)
77 {
78 g_warning ("%s: failed to close server socket: %s\n", __func__,
79 strerror (errno));
80 return -1;
81 }
82
83 return 0;
84}
85
91void
93{
94 if (client_connection->tls)
95 gvm_server_free (client_connection->socket, client_connection->session,
96 client_connection->credentials);
97 else
98 close_unix (client_connection);
99}
100
101/* Certificate verification. */
102
110int
111gvm_server_verify (gnutls_session_t session)
112{
113 unsigned int status;
114 int ret;
115
116 ret = gnutls_certificate_verify_peers2 (session, &status);
117 if (ret < 0)
118 {
119 g_warning ("%s: failed to verify peers: %s", __func__,
120 gnutls_strerror (ret));
121 return -1;
122 }
123
124 if (status & GNUTLS_CERT_INVALID)
125 g_warning ("%s: the certificate is not trusted", __func__);
126
127 if (status & GNUTLS_CERT_SIGNER_NOT_CA)
128 g_warning ("%s: the certificate's issuer is not a CA", __func__);
129
130 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
131 g_warning ("%s: the certificate was signed using an insecure algorithm",
132 __func__);
133
134 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
135 g_warning ("%s: the certificate hasn't got a known issuer", __func__);
136
137 if (status & GNUTLS_CERT_REVOKED)
138 g_warning ("%s: the certificate has been revoked", __func__);
139
140 if (status & GNUTLS_CERT_EXPIRED)
141 g_warning ("%s: the certificate has expired", __func__);
142
143 if (status & GNUTLS_CERT_NOT_ACTIVATED)
144 g_warning ("%s: the certificate is not yet activated", __func__);
145
146 if (status)
147 return 1;
148
149 return 0;
150}
151
160int
161load_gnutls_file (const char *file, gnutls_datum_t *loaded_file)
162{
163 FILE *f = NULL;
164 int64_t filelen;
165 void *ptr;
166
167 if (!(f = fopen (file, "r")) || fseek (f, 0, SEEK_END) != 0
168 || (filelen = ftell (f)) < 0 || fseek (f, 0, SEEK_SET) != 0
169 || !(ptr = g_malloc0 ((size_t) filelen))
170 || fread (ptr, 1, (size_t) filelen, f) < (size_t) filelen)
171 {
172 if (f)
173 fclose (f);
174 return -1;
175 }
176
177 loaded_file->data = ptr;
178 loaded_file->size = filelen;
179 fclose (f);
180 return 0;
181}
182
188void
189unload_gnutls_file (gnutls_datum_t *data)
190{
191 if (data)
192 g_free (data->data);
193}
194
195static char *cert_pub_mem = NULL;
196static char *cert_priv_mem = NULL;
197
203static void
204set_cert_pub_mem (const char *data)
205{
206 if (cert_pub_mem)
207 g_free (cert_pub_mem);
208 cert_pub_mem = g_strdup (data);
209}
210
216static void
217set_cert_priv_mem (const char *data)
218{
219 if (cert_priv_mem)
220 g_free (cert_priv_mem);
221 cert_priv_mem = g_strdup (data);
222}
223
229static const char *
231{
232 return cert_priv_mem;
233}
234
240static const char *
242{
243 return cert_pub_mem;
244}
245
261static int
262client_cert_callback (gnutls_session_t session,
263 const gnutls_datum_t *req_ca_rdn, int nreqs,
264 const gnutls_pk_algorithm_t *sign_algos,
265 int sign_algos_length, gnutls_retr2_st *st)
266{
267 int ret;
268 gnutls_datum_t data;
269 static gnutls_x509_crt_t crt;
270 static gnutls_x509_privkey_t key;
271
272 (void) session;
273 (void) req_ca_rdn;
274 (void) nreqs;
275 (void) sign_algos;
276 (void) sign_algos_length;
277 data.data = (unsigned char *) g_strdup (get_cert_pub_mem ());
278 data.size = strlen (get_cert_pub_mem ());
279 gnutls_x509_crt_init (&crt);
280 ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
281 g_free (data.data);
282 if (ret)
283 return ret;
284 st->cert.x509 = &crt;
285 st->cert_type = GNUTLS_CRT_X509;
286 st->ncerts = 1;
287
288 data.data = (unsigned char *) g_strdup (get_cert_priv_mem ());
289 data.size = strlen (get_cert_priv_mem ());
290 gnutls_x509_privkey_init (&key);
291 ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
292 g_free (data.data);
293 if (ret)
294 return ret;
295 st->key.x509 = key;
296 st->key_type = GNUTLS_PRIVKEY_X509;
297 return 0;
298}
299
313int
314gvm_server_open_verify (gnutls_session_t *session, const char *host, int port,
315 const char *ca_mem, const char *pub_mem,
316 const char *priv_mem, int verify)
317{
318 int ret;
319 int server_socket;
320 struct addrinfo address_hints;
321 struct addrinfo *addresses, *address;
322 gchar *port_string;
323 int host_type;
324
325 gnutls_certificate_credentials_t credentials;
326
327 /* Ensure that host and port have sane values. */
328 if (port < 1 || port > 65535)
329 {
330 g_warning ("Failed to create client TLS session. "
331 "Invalid port %d",
332 port);
333 return -1;
334 }
338 {
339 g_warning ("Failed to create client TLS session. Invalid host %s", host);
340 return -1;
341 }
342
346 if (gvm_server_new_mem (GNUTLS_CLIENT, ca_mem, pub_mem, priv_mem, session,
347 &credentials))
348 {
349 g_warning ("Failed to create client TLS session.");
350 return -1;
351 }
352
353 if (ca_mem && pub_mem && priv_mem)
354 {
355 set_cert_pub_mem (pub_mem);
356 set_cert_priv_mem (priv_mem);
357
358 gnutls_certificate_set_retrieve_function (credentials,
360 }
361
362 /* Create the port string. */
363
364 port_string = g_strdup_printf ("%i", port);
365
366 /* Get all possible addresses. */
367
368 memset (&address_hints, 0, sizeof (address_hints));
369 address_hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6. */
370 address_hints.ai_socktype = SOCK_STREAM;
371 address_hints.ai_protocol = 0;
372
373 if (getaddrinfo (host, port_string, &address_hints, &addresses))
374 {
375 g_free (port_string);
376 g_warning ("Failed to get server addresses for %s: %s", host,
377 gai_strerror (errno));
378 gnutls_deinit (*session);
379 gnutls_certificate_free_credentials (credentials);
380 return -1;
381 }
382 g_free (port_string);
383
384 /* Try to connect to each address in turn. */
385
386 for (address = addresses; address; address = address->ai_next)
387 {
388 /* Make server socket. */
389
390 if (address->ai_family == AF_INET6)
391 server_socket = socket (PF_INET6, SOCK_STREAM, 0);
392 else
393 server_socket = socket (PF_INET, SOCK_STREAM, 0);
394 if (server_socket == -1)
395 {
396 g_warning ("Failed to create server socket");
397 freeaddrinfo (addresses);
398 gnutls_deinit (*session);
399 gnutls_certificate_free_credentials (credentials);
400 return -1;
401 }
402
403 /* Connect to server. */
404
405 if (connect (server_socket, address->ai_addr, address->ai_addrlen) == -1)
406 {
407 close (server_socket);
408 continue;
409 }
410 break;
411 }
412
413 freeaddrinfo (addresses);
414
415 if (address == NULL)
416 {
417 g_warning ("Failed to connect to server");
418 gnutls_deinit (*session);
419 gnutls_certificate_free_credentials (credentials);
420 return -1;
421 }
422
423 g_debug (" Connected to server '%s' port %d.", host, port);
424
425 /* Complete setup of server session. */
426 ret = server_attach_internal (server_socket, session, host, port);
427 if (ret)
428 {
429 if (ret == -2)
430 {
431 close (server_socket);
432 gnutls_deinit (*session);
433 gnutls_certificate_free_credentials (credentials);
434 }
435 close (server_socket);
436 return -1;
437 }
438 if (verify && gvm_server_verify (*session))
439 {
440 close (server_socket);
441 return -1;
442 }
443
444 return server_socket;
445}
446
461int
462gvm_server_open_with_cert (gnutls_session_t *session, const char *host,
463 int port, const char *ca_mem, const char *pub_mem,
464 const char *priv_mem)
465{
466 return gvm_server_open_verify (session, host, port, ca_mem, pub_mem, priv_mem,
467 ca_mem && pub_mem && priv_mem);
468}
469
479int
480gvm_server_open (gnutls_session_t *session, const char *host, int port)
481{
482 return gvm_server_open_with_cert (session, host, port, NULL, NULL, NULL);
483}
484
493int
494gvm_server_close (int socket, gnutls_session_t session)
495{
496 return gvm_server_free (socket, session, NULL);
497}
498
504void
506{
507 gvm_connection_free (connection);
508}
509
521static int
522server_attach_internal (int socket, gnutls_session_t *session, const char *host,
523 int port)
524{
525 unsigned int retries;
526
527 gnutls_transport_set_ptr (*session,
528 (gnutls_transport_ptr_t) GSIZE_TO_POINTER (socket));
529
530 retries = 0;
531 while (1)
532 {
533 int ret = gnutls_handshake (*session);
534 if (ret >= 0)
535 break;
536 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
537 {
538 if (retries > 10)
539 usleep (MIN ((retries - 10) * 10000, 5000000));
540 retries++;
541 continue;
542 }
543 if (host)
544 g_debug ("Failed to shake hands with server '%s' port %d: %s", host,
545 port, gnutls_strerror (ret));
546 else
547 g_debug ("Failed to shake hands with peer: %s", gnutls_strerror (ret));
548 if (shutdown (socket, SHUT_RDWR) == -1)
549 g_debug ("Failed to shutdown server socket");
550 return -2;
551 }
552 if (host)
553 g_debug (" Shook hands with server '%s' port %d.", host, port);
554 else
555 g_debug (" Shook hands with peer.");
556
557 return 0;
558}
559
569int
570gvm_server_attach (int socket, gnutls_session_t *session)
571{
572 int ret;
573
574 ret = server_attach_internal (socket, session, NULL, 0);
575 return ret ? -1 : 0;
576}
577
589static int
590gvm_server_vsendf_internal (gnutls_session_t *session, const char *fmt,
591 va_list ap, int quiet)
592{
593 char *sref, *string;
594 int rc = 0, left;
595
596 left = vasprintf (&string, fmt, ap);
597 if (left == -1)
598 string = NULL;
599
600 sref = string;
601 while (left > 0)
602 {
603 ssize_t count;
604
605 if (quiet == 0)
606 g_debug (" send %d from %.*s[...]", left, left < 30 ? left : 30,
607 string);
608 count = gnutls_record_send (*session, string, left);
609 if (count < 0)
610 {
611 if (count == GNUTLS_E_INTERRUPTED)
612 /* Interrupted, try write again. */
613 continue;
614 if (count == GNUTLS_E_REHANDSHAKE)
615 {
616 /* \todo Rehandshake. */
617 if (quiet == 0)
618 g_message (" %s rehandshake", __func__);
619 continue;
620 }
621 g_warning ("Failed to write to server: %s", gnutls_strerror (count));
622 rc = -1;
623 goto out;
624 }
625 if (count == 0)
626 {
627 /* Server closed connection. */
628 if (quiet == 0)
629 g_debug ("= server closed");
630 rc = 1;
631 goto out;
632 }
633 if (quiet == 0)
634 g_debug ("=> %.*s", (int) count, string);
635 string += count;
636 left -= count;
637 }
638 if (quiet == 0)
639 g_debug ("=> done");
640
641out:
642 g_free (sref);
643 return rc;
644}
645
657static int
658unix_vsendf_internal (int socket, const char *fmt, va_list ap, int quiet)
659{
660 char *string_start, *string;
661 int rc = 0, left;
662
663 left = vasprintf (&string, fmt, ap);
664 if (left == -1)
665 string = NULL;
666
667 string_start = string;
668 while (left > 0)
669 {
670 ssize_t count;
671
672 if (quiet == 0)
673 g_debug (" send %d from %.*s[...]", left, left < 30 ? left : 30,
674 string);
675 count = write (socket, string, left);
676 if (count < 0)
677 {
678 if (errno == EINTR || errno == EAGAIN)
679 continue;
680 g_warning ("Failed to write to server: %s", strerror (errno));
681 rc = -1;
682 goto out;
683 }
684 if (quiet == 0)
685 g_debug ("=> %.*s", (int) count, string);
686
687 string += count;
688 left -= count;
689 }
690 if (quiet == 0)
691 g_debug ("=> done");
692
693out:
694 g_free (string_start);
695 return rc;
696}
697
709static int
711 va_list ap, int quiet)
712{
713 if (connection->tls)
714 return gvm_server_vsendf_internal (&connection->session, fmt, ap, quiet);
715 return unix_vsendf_internal (connection->socket, fmt, ap, quiet);
716}
717
727int
728gvm_server_vsendf (gnutls_session_t *session, const char *fmt, va_list ap)
729{
730 return gvm_server_vsendf_internal (session, fmt, ap, 0);
731}
732
742int
743gvm_socket_vsendf (int socket, const char *fmt, va_list ap)
744{
745 return unix_vsendf_internal (socket, fmt, ap, 0);
746}
747
757static int
758gvm_connection_vsendf (gvm_connection_t *connection, const char *fmt,
759 va_list ap)
760{
761 return gvm_connection_vsendf_internal (connection, fmt, ap, 0);
762}
763
773static int
774gvm_server_vsendf_quiet (gnutls_session_t *session, const char *fmt, va_list ap)
775{
776 return gvm_server_vsendf_internal (session, fmt, ap, 1);
777}
778
788static int
789gvm_connection_vsendf_quiet (gvm_connection_t *connection, const char *fmt,
790 va_list ap)
791{
792 return gvm_connection_vsendf_internal (connection, fmt, ap, 1);
793}
794
803int
804gvm_server_sendf (gnutls_session_t *session, const char *format, ...)
805{
806 va_list ap;
807 int rc;
808
809 va_start (ap, format);
810 rc = gvm_server_vsendf (session, format, ap);
811 va_end (ap);
812 return rc;
813}
814
823int
824gvm_connection_sendf (gvm_connection_t *connection, const char *format, ...)
825{
826 va_list ap;
827 int rc;
828
829 va_start (ap, format);
830 rc = gvm_connection_vsendf (connection, format, ap);
831 va_end (ap);
832 return rc;
833}
834
843static int
844gvm_server_sendf_quiet (gnutls_session_t *session, const char *format, ...)
845{
846 va_list ap;
847 int rc;
848
849 va_start (ap, format);
850 rc = gvm_server_vsendf_quiet (session, format, ap);
851 va_end (ap);
852 return rc;
853}
854
863static int
864gvm_connection_sendf_quiet (gvm_connection_t *connection, const char *format,
865 ...)
866{
867 va_list ap;
868 int rc;
869
870 va_start (ap, format);
871 rc = gvm_connection_vsendf_quiet (connection, format, ap);
872 va_end (ap);
873 return rc;
874}
875
886int
887gvm_server_sendf_xml (gnutls_session_t *session, const char *format, ...)
888{
889 va_list ap;
890 gchar *msg;
891 int rc;
892
893 va_start (ap, format);
894 msg = g_markup_vprintf_escaped (format, ap);
895 rc = gvm_server_sendf (session, "%s", msg);
896 g_free (msg);
897 va_end (ap);
898 return rc;
899}
900
911int
912gvm_connection_sendf_xml (gvm_connection_t *connection, const char *format, ...)
913{
914 va_list ap;
915 gchar *msg;
916 int rc;
917
918 va_start (ap, format);
919 msg = g_markup_vprintf_escaped (format, ap);
920 rc = gvm_connection_sendf (connection, "%s", msg);
921 g_free (msg);
922 va_end (ap);
923 return rc;
924}
925
938int
939gvm_server_sendf_xml_quiet (gnutls_session_t *session, const char *format, ...)
940{
941 va_list ap;
942 gchar *msg;
943 int rc;
944
945 va_start (ap, format);
946 msg = g_markup_vprintf_escaped (format, ap);
947 rc = gvm_server_sendf_quiet (session, "%s", msg);
948 g_free (msg);
949 va_end (ap);
950 return rc;
951}
952
965int
967 const char *format, ...)
968{
969 va_list ap;
970 gchar *msg;
971 int rc;
972
973 va_start (ap, format);
974 msg = g_markup_vprintf_escaped (format, ap);
975 rc = gvm_connection_sendf_quiet (connection, "%s", msg);
976 g_free (msg);
977 va_end (ap);
978 return rc;
979}
980
988static int
989server_new_gnutls_init (gnutls_certificate_credentials_t *server_credentials)
990{
991 /* Turn off use of /dev/random, as this can block. */
992 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
993
994 /* Initialize security library. */
995 if (gnutls_global_init ())
996 {
997 g_warning ("Failed to initialize GNUTLS.");
998 return -1;
999 }
1000 /* Setup server session. */
1001 if (gnutls_certificate_allocate_credentials (server_credentials))
1002 {
1003 g_warning ("%s: failed to allocate server credentials\n", __func__);
1004 return -1;
1005 }
1006 return 0;
1007}
1008
1020static int
1021server_new_gnutls_set (unsigned int end_type, const char *priority,
1022 gnutls_session_t *server_session,
1023 gnutls_certificate_credentials_t *server_credentials)
1024{
1025 int err_gnutls;
1026
1027 if (gnutls_init (server_session, end_type))
1028 {
1029 g_warning ("%s: failed to initialise server session\n", __func__);
1030 return -1;
1031 }
1032
1033 /* Depending on gnutls version different priority strings are
1034 possible. At least from 3.0 this is an option:
1035 "NONE:+VERS-TLS1.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL"
1036 But in fact this function is only for internal
1037 purposes, not for scanning abilities. So, the conservative "NORMAL"
1038 is chosen.
1039 */
1040
1041 if ((err_gnutls = gnutls_priority_set_direct (
1042 *server_session, priority ? priority : "NORMAL", NULL)))
1043 {
1044 g_warning ("%s: failed to set tls priorities: %s\n", __func__,
1045 gnutls_strerror (err_gnutls));
1046 gnutls_deinit (*server_session);
1047 return -1;
1048 }
1049
1050 if (gnutls_credentials_set (*server_session, GNUTLS_CRD_CERTIFICATE,
1051 *server_credentials))
1052 {
1053 g_warning ("%s: failed to set server credentials\n", __func__);
1054 gnutls_deinit (*server_session);
1055 return -1;
1056 }
1057
1058 if (end_type == GNUTLS_SERVER)
1059 gnutls_certificate_server_set_request (*server_session,
1060 GNUTLS_CERT_REQUEST);
1061 return 0;
1062}
1063
1078static int
1079server_new_internal (unsigned int end_type, const char *priority,
1080 const gchar *ca_cert_file, const gchar *cert_file,
1081 const gchar *key_file, gnutls_session_t *server_session,
1082 gnutls_certificate_credentials_t *server_credentials)
1083{
1084 if (server_new_gnutls_init (server_credentials))
1085 return -1;
1086
1087 if (cert_file && key_file)
1088 {
1089 int ret;
1090
1091 ret = gnutls_certificate_set_x509_key_file (
1092 *server_credentials, cert_file, key_file, GNUTLS_X509_FMT_PEM);
1093 if (ret < 0)
1094 {
1095 g_warning ("%s: failed to set credentials key file: %s\n", __func__,
1096 gnutls_strerror (ret));
1097 g_warning ("%s: cert file: %s\n", __func__, cert_file);
1098 g_warning ("%s: key file : %s\n", __func__, key_file);
1099 gnutls_certificate_free_credentials (*server_credentials);
1100 return -1;
1101 }
1102 }
1103
1104 if (ca_cert_file)
1105 {
1106 int ret;
1107
1108 ret = gnutls_certificate_set_x509_trust_file (
1109 *server_credentials, ca_cert_file, GNUTLS_X509_FMT_PEM);
1110 if (ret < 0)
1111 {
1112 g_warning ("%s: failed to set credentials trust file: %s\n", __func__,
1113 gnutls_strerror (ret));
1114 g_warning ("%s: trust file: %s\n", __func__, ca_cert_file);
1115 gnutls_certificate_free_credentials (*server_credentials);
1116 return -1;
1117 }
1118 }
1119
1120 if (server_new_gnutls_set (end_type, priority, server_session,
1121 server_credentials))
1122 {
1123 gnutls_certificate_free_credentials (*server_credentials);
1124 return -1;
1125 }
1126
1127 return 0;
1128}
1129
1143int
1144gvm_server_new (unsigned int end_type, gchar *ca_cert_file, gchar *cert_file,
1145 gchar *key_file, gnutls_session_t *server_session,
1146 gnutls_certificate_credentials_t *server_credentials)
1147{
1148 return server_new_internal (end_type, NULL, ca_cert_file, cert_file, key_file,
1149 server_session, server_credentials);
1150}
1151
1165int
1166gvm_server_new_mem (unsigned int end_type, const char *ca_cert,
1167 const char *pub_key, const char *priv_key,
1168 gnutls_session_t *session,
1169 gnutls_certificate_credentials_t *credentials)
1170{
1171 if (server_new_gnutls_init (credentials))
1172 return -1;
1173
1174 if (pub_key && priv_key)
1175 {
1176 int ret;
1177 gnutls_datum_t pub, priv;
1178
1179 pub.data = (void *) pub_key;
1180 pub.size = strlen (pub_key);
1181 priv.data = (void *) priv_key;
1182 priv.size = strlen (priv_key);
1183
1184 ret = gnutls_certificate_set_x509_key_mem (*credentials, &pub, &priv,
1185 GNUTLS_X509_FMT_PEM);
1186 if (ret < 0)
1187 {
1188 g_warning ("%s: %s\n", __func__, gnutls_strerror (ret));
1189 return -1;
1190 }
1191 }
1192
1193 if (ca_cert)
1194 {
1195 int ret;
1196 gnutls_datum_t data;
1197
1198 data.data = (void *) ca_cert;
1199 data.size = strlen (ca_cert);
1200 ret = gnutls_certificate_set_x509_trust_mem (*credentials, &data,
1201 GNUTLS_X509_FMT_PEM);
1202 if (ret < 0)
1203 {
1204 g_warning ("%s: %s\n", __func__, gnutls_strerror (ret));
1205 gnutls_certificate_free_credentials (*credentials);
1206 return -1;
1207 }
1208 }
1209
1210 if (server_new_gnutls_set (end_type, NULL, session, credentials))
1211 {
1212 gnutls_certificate_free_credentials (*credentials);
1213 return -1;
1214 }
1215
1216 return 0;
1217}
1218
1227int
1228set_gnutls_dhparams (gnutls_certificate_credentials_t creds,
1229 const char *dhparams_file)
1230{
1231 int ret;
1232 gnutls_datum_t data;
1233
1234 if (!creds || !dhparams_file)
1235 return -1;
1236
1237 if (load_gnutls_file (dhparams_file, &data))
1238 return -1;
1239
1240/* Disable false positive warning about potential leak of memory */
1241#ifndef __clang_analyzer__
1242
1243 gnutls_dh_params_t params = g_malloc0 (sizeof (gnutls_dh_params_t));
1244 ret = gnutls_dh_params_import_pkcs3 (params, &data, GNUTLS_X509_FMT_PEM);
1245 unload_gnutls_file (&data);
1246 if (ret)
1247 {
1248 g_free (params);
1249 return -1;
1250 }
1251 else
1252 gnutls_certificate_set_dh_params (creds, params);
1253 return 0;
1254
1255#endif
1256}
1257
1270int
1271gvm_server_free (int server_socket, gnutls_session_t server_session,
1272 gnutls_certificate_credentials_t server_credentials)
1273{
1274 /* Turn off blocking. */
1275 // FIX get flags first
1276 if (fcntl (server_socket, F_SETFL, O_NONBLOCK) == -1)
1277 {
1278 g_warning ("%s: failed to set server socket flag: %s\n", __func__,
1279 strerror (errno));
1280 return -1;
1281 }
1282
1283 while (1)
1284 {
1285 int ret = gnutls_bye (server_session, GNUTLS_SHUT_WR);
1286 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
1287 {
1288 continue;
1289 }
1290 if (ret)
1291 {
1292 g_debug (" Failed to gnutls_bye: %s\n",
1293 gnutls_strerror ((int) ret));
1294 /* Carry on successfully anyway, as this often fails, perhaps
1295 * because the server is closing the connection first. */
1296 break;
1297 }
1298 break;
1299 }
1300
1301 /* The former separate code in gvm_server_close and here
1302 differed in the order the TLS session and socket was closed. The
1303 way we do it here seems to be the right thing but for full
1304 backward compatibility we do it for calls from
1305 gvm_server_close in the old way. We can distinguish the two
1306 modes by the existence of server_credentials. */
1307 if (server_credentials)
1308 {
1309 if (close (server_socket) == -1)
1310 {
1311 g_warning ("%s: failed to close server socket: %s\n", __func__,
1312 strerror (errno));
1313 return -1;
1314 }
1315 gnutls_deinit (server_session);
1316 gnutls_certificate_free_credentials (server_credentials);
1317 }
1318 else
1319 {
1320 gnutls_deinit (server_session);
1321 close (server_socket);
1322 }
1323
1324 gnutls_global_deinit ();
1325
1326 return 0;
1327}
int gvm_get_host_type(const gchar *str_stripped)
Determines the host type in a buffer.
Definition: hosts.c:810
host_type
Definition: hosts.h:34
@ HOST_TYPE_NAME
Definition: hosts.h:35
@ HOST_TYPE_IPV6
Definition: hosts.h:40
@ HOST_TYPE_IPV4
Definition: hosts.h:36
static int close_unix(gvm_connection_t *client_connection)
Close UNIX socket connection.
Definition: serverutils.c:57
static int server_new_internal(unsigned int, const char *, const gchar *, const gchar *, const gchar *, gnutls_session_t *, gnutls_certificate_credentials_t *)
Make a session for connecting to a server.
Definition: serverutils.c:1079
int set_gnutls_dhparams(gnutls_certificate_credentials_t creds, const char *dhparams_file)
Set a gnutls session's Diffie-Hellman parameters.
Definition: serverutils.c:1228
static const char * get_cert_pub_mem()
Get public certificate from cert_pub_mem.
Definition: serverutils.c:241
int gvm_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.
Definition: serverutils.c:1144
int gvm_connection_sendf(gvm_connection_t *connection, const char *format,...)
Format and send a string to the server.
Definition: serverutils.c:824
int gvm_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.
Definition: serverutils.c:462
int gvm_server_sendf_xml_quiet(gnutls_session_t *session, const char *format,...)
Format and send an XML string to the server.
Definition: serverutils.c:939
static void set_cert_priv_mem(const char *data)
Save cert_priv_mem with private certificate.
Definition: serverutils.c:217
int gvm_server_vsendf(gnutls_session_t *session, const char *fmt, va_list ap)
Send a string to the server.
Definition: serverutils.c:728
static const char * get_cert_priv_mem()
Get private certificate from cert_priv_mem.
Definition: serverutils.c:230
int gvm_server_close(int socket, gnutls_session_t session)
Close a server connection and its socket.
Definition: serverutils.c:494
int gvm_server_open(gnutls_session_t *session, const char *host, int port)
Connect to the server using a given host and port.
Definition: serverutils.c:480
static int gvm_connection_vsendf_internal(gvm_connection_t *connection, const char *fmt, va_list ap, int quiet)
Send a string to the connection.
Definition: serverutils.c:710
static int client_cert_callback(gnutls_session_t session, const gnutls_datum_t *req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t *sign_algos, int sign_algos_length, gnutls_retr2_st *st)
Callback function to be called in order to retrieve the certificate to be used in the handshake.
Definition: serverutils.c:262
int gvm_connection_sendf_xml(gvm_connection_t *connection, const char *format,...)
Format and send an XML string to the server.
Definition: serverutils.c:912
static char * cert_pub_mem
Definition: serverutils.c:195
static int gvm_server_sendf_quiet(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
Definition: serverutils.c:844
void gvm_connection_close(gvm_connection_t *connection)
Close a server connection and its socket.
Definition: serverutils.c:505
static int server_attach_internal(int, gnutls_session_t *, const char *, int)
Attach a socket to a session, and shake hands with the peer.
Definition: serverutils.c:522
static int server_new_gnutls_init(gnutls_certificate_credentials_t *server_credentials)
Initialize a server session.
Definition: serverutils.c:989
int gvm_socket_vsendf(int socket, const char *fmt, va_list ap)
Send a string to the server.
Definition: serverutils.c:743
int load_gnutls_file(const char *file, gnutls_datum_t *loaded_file)
Loads a file's data into gnutls_datum_t struct.
Definition: serverutils.c:161
int gvm_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.
Definition: serverutils.c:1166
static char * cert_priv_mem
Definition: serverutils.c:196
void gvm_connection_free(gvm_connection_t *client_connection)
Free connection.
Definition: serverutils.c:92
int gvm_server_sendf_xml(gnutls_session_t *session, const char *format,...)
Format and send an XML string to the server.
Definition: serverutils.c:887
static int gvm_connection_sendf_quiet(gvm_connection_t *connection, const char *format,...)
Format and send a string to the server.
Definition: serverutils.c:864
static int unix_vsendf_internal(int socket, const char *fmt, va_list ap, int quiet)
Send a string to the server.
Definition: serverutils.c:658
static int server_new_gnutls_set(unsigned int end_type, const char *priority, gnutls_session_t *server_session, gnutls_certificate_credentials_t *server_credentials)
Set the server credencials.
Definition: serverutils.c:1021
static int gvm_connection_vsendf(gvm_connection_t *connection, const char *fmt, va_list ap)
Send a string to the server.
Definition: serverutils.c:758
void unload_gnutls_file(gnutls_datum_t *data)
Unloads a gnutls_datum_t struct's data.
Definition: serverutils.c:189
static int gvm_connection_vsendf_quiet(gvm_connection_t *connection, const char *fmt, va_list ap)
Send a string to the server, refraining from logging besides warnings.
Definition: serverutils.c:789
int gvm_server_verify(gnutls_session_t session)
Verify certificate.
Definition: serverutils.c:111
static int gvm_server_vsendf_internal(gnutls_session_t *session, const char *fmt, va_list ap, int quiet)
Send a string to the server.
Definition: serverutils.c:590
static int gvm_server_vsendf_quiet(gnutls_session_t *session, const char *fmt, va_list ap)
Send a string to the server, refraining from logging besides warnings.
Definition: serverutils.c:774
int gvm_server_sendf(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
Definition: serverutils.c:804
int gvm_server_free(int server_socket, gnutls_session_t server_session, gnutls_certificate_credentials_t server_credentials)
Cleanup a server session.
Definition: serverutils.c:1271
int gvm_server_attach(int socket, gnutls_session_t *session)
Attach a socket to a session, and shake hands with the peer.
Definition: serverutils.c:570
int gvm_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.
Definition: serverutils.c:314
static void set_cert_pub_mem(const char *data)
Save cert_pub_mem with public certificate.
Definition: serverutils.c:204
int gvm_connection_sendf_xml_quiet(gvm_connection_t *connection, const char *format,...)
Format and send an XML string to the server.
Definition: serverutils.c:966
GnuTLS based functions for server communication - header file.
Connection.
Definition: serverutils.h:30
int tls
Whether uses TCP-TLS (vs UNIX socket).
Definition: serverutils.h:31
gnutls_certificate_credentials_t credentials
Credentials.
Definition: serverutils.h:34
int socket
Socket.
Definition: serverutils.h:32
gnutls_session_t session
Session.
Definition: serverutils.h:33