25#include <gnutls/x509.h>
30#include <sys/socket.h>
38#define G_LOG_DOMAIN "libgvm util"
44 const gchar *, gnutls_session_t *,
45 gnutls_certificate_credentials_t *);
60 if (fcntl (client_connection->
socket, F_SETFL, O_NONBLOCK) == -1)
62 g_warning (
"%s: failed to set server socket flag: %s\n", __func__,
67 if (shutdown (client_connection->
socket, SHUT_RDWR) == -1)
69 if (errno == ENOTCONN)
71 g_warning (
"%s: failed to shutdown server socket: %s\n", __func__,
76 if (close (client_connection->
socket) == -1)
78 g_warning (
"%s: failed to close server socket: %s\n", __func__,
94 if (client_connection->
tls)
116 ret = gnutls_certificate_verify_peers3 (session, host, &status);
119 g_warning (
"%s: failed to verify peers: %s", __func__,
120 gnutls_strerror (ret));
124 if (status & GNUTLS_CERT_UNEXPECTED_OWNER)
125 g_warning (
"%s: the certificate's host does not match the actual host",
128 if (status & GNUTLS_CERT_INVALID)
129 g_warning (
"%s: the certificate is not trusted", __func__);
131 if (status & GNUTLS_CERT_SIGNER_NOT_CA)
132 g_warning (
"%s: the certificate's issuer is not a CA", __func__);
134 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
135 g_warning (
"%s: the certificate was signed using an insecure algorithm",
138 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
139 g_warning (
"%s: the certificate hasn't got a known issuer", __func__);
141 if (status & GNUTLS_CERT_REVOKED)
142 g_warning (
"%s: the certificate has been revoked", __func__);
144 if (status & GNUTLS_CERT_EXPIRED)
145 g_warning (
"%s: the certificate has expired", __func__);
147 if (status & GNUTLS_CERT_NOT_ACTIVATED)
148 g_warning (
"%s: the certificate is not yet activated", __func__);
171 if (!(f = fopen (file,
"r")) || fseek (f, 0, SEEK_END) != 0
172 || (filelen = ftell (f)) < 0 || fseek (f, 0, SEEK_SET) != 0
173 || !(ptr = g_malloc0 ((
size_t) filelen))
174 || fread (ptr, 1, (
size_t) filelen, f) < (
size_t) filelen)
181 loaded_file->data = ptr;
182 loaded_file->size = filelen;
266 const gnutls_datum_t *req_ca_rdn,
int nreqs,
267 const gnutls_pk_algorithm_t *sign_algos,
268 int sign_algos_length, gnutls_retr2_st *st)
272 static gnutls_x509_crt_t crt;
273 static gnutls_x509_privkey_t key;
279 (void) sign_algos_length;
282 gnutls_x509_crt_init (&crt);
283 ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
287 st->cert.x509 = &crt;
288 st->cert_type = GNUTLS_CRT_X509;
293 gnutls_x509_privkey_init (&key);
294 ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
299 st->key_type = GNUTLS_PRIVKEY_X509;
318 const char *ca_mem,
const char *pub_mem,
319 const char *priv_mem,
int verify)
323 struct addrinfo address_hints;
324 struct addrinfo *addresses, *address;
328 gnutls_certificate_credentials_t credentials;
331 if (port < 1 || port > 65535)
333 g_warning (
"Failed to create client TLS session. "
342 g_warning (
"Failed to create client TLS session. Invalid host %s", host);
352 g_warning (
"Failed to create client TLS session.");
356 if (ca_mem && pub_mem && priv_mem)
361 gnutls_certificate_set_retrieve_function (credentials,
367 port_string = g_strdup_printf (
"%i", port);
371 memset (&address_hints, 0,
sizeof (address_hints));
372 address_hints.ai_family = AF_UNSPEC;
373 address_hints.ai_socktype = SOCK_STREAM;
374 address_hints.ai_protocol = 0;
376 if (getaddrinfo (host, port_string, &address_hints, &addresses))
378 g_free (port_string);
379 g_warning (
"Failed to get server addresses for %s: %s", host,
380 gai_strerror (errno));
381 gnutls_deinit (*session);
382 gnutls_certificate_free_credentials (credentials);
385 g_free (port_string);
389 for (address = addresses; address; address = address->ai_next)
393 if (address->ai_family == AF_INET6)
394 server_socket = socket (PF_INET6, SOCK_STREAM, 0);
396 server_socket = socket (PF_INET, SOCK_STREAM, 0);
397 if (server_socket == -1)
399 g_warning (
"Failed to create server socket");
400 freeaddrinfo (addresses);
401 gnutls_deinit (*session);
402 gnutls_certificate_free_credentials (credentials);
408 if (connect (server_socket, address->ai_addr, address->ai_addrlen) == -1)
410 close (server_socket);
416 freeaddrinfo (addresses);
420 g_warning (
"Failed to connect to server");
421 gnutls_deinit (*session);
422 gnutls_certificate_free_credentials (credentials);
426 g_debug (
" Connected to server '%s' port %d.", host, port);
434 close (server_socket);
435 gnutls_deinit (*session);
436 gnutls_certificate_free_credentials (credentials);
438 close (server_socket);
443 close (server_socket);
447 return server_socket;
466 int port,
const char *ca_mem,
const char *pub_mem,
467 const char *priv_mem)
470 ca_mem && pub_mem && priv_mem);
528 unsigned int retries;
530 gnutls_transport_set_ptr (*session,
531 (gnutls_transport_ptr_t) GSIZE_TO_POINTER (socket));
536 int ret = gnutls_handshake (*session);
539 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
542 usleep (MIN ((retries - 10) * 10000, 5000000));
547 g_debug (
"Failed to shake hands with server '%s' port %d: %s", host,
548 port, gnutls_strerror (ret));
550 g_debug (
"Failed to shake hands with peer: %s", gnutls_strerror (ret));
551 if (shutdown (socket, SHUT_RDWR) == -1)
552 g_debug (
"Failed to shutdown server socket");
556 g_debug (
" Shook hands with server '%s' port %d.", host, port);
558 g_debug (
" Shook hands with peer.");
594 va_list ap,
int quiet)
599 left = vasprintf (&
string, fmt, ap);
609 g_debug (
" send %d from %.*s[...]", left, left < 30 ? left : 30,
611 count = gnutls_record_send (*session,
string, left);
614 if (count == GNUTLS_E_INTERRUPTED)
617 if (count == GNUTLS_E_REHANDSHAKE)
621 g_message (
" %s rehandshake", __func__);
624 g_warning (
"Failed to write to server: %s", gnutls_strerror (count));
632 g_debug (
"= server closed");
637 g_debug (
"=> %.*s", (
int) count,
string);
663 char *string_start, *string;
666 left = vasprintf (&
string, fmt, ap);
670 string_start = string;
676 g_debug (
" send %d from %.*s[...]", left, left < 30 ? left : 30,
678 count = write (socket,
string, left);
681 if (errno == EINTR || errno == EAGAIN)
683 g_warning (
"Failed to write to server: %s", strerror (errno));
688 g_debug (
"=> %.*s", (
int) count,
string);
697 g_free (string_start);
714 va_list ap,
int quiet)
812 va_start (ap, format);
832 va_start (ap, format);
852 va_start (ap, format);
873 va_start (ap, format);
896 va_start (ap, format);
897 msg = g_markup_vprintf_escaped (format, ap);
921 va_start (ap, format);
922 msg = g_markup_vprintf_escaped (format, ap);
948 va_start (ap, format);
949 msg = g_markup_vprintf_escaped (format, ap);
970 const char *format, ...)
976 va_start (ap, format);
977 msg = g_markup_vprintf_escaped (format, ap);
995 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
998 if (gnutls_global_init ())
1000 g_warning (
"Failed to initialize GNUTLS.");
1004 if (gnutls_certificate_allocate_credentials (server_credentials))
1006 g_warning (
"%s: failed to allocate server credentials\n", __func__);
1025 gnutls_session_t *server_session,
1026 gnutls_certificate_credentials_t *server_credentials)
1030 if (gnutls_init (server_session, end_type))
1032 g_warning (
"%s: failed to initialise server session\n", __func__);
1044 err = gnutls_priority_set_direct (*server_session,
1045 priority ? priority :
"NORMAL", NULL);
1048 g_warning (
"%s: failed to set tls priorities: %s\n", __func__,
1049 gnutls_strerror (err));
1050 gnutls_deinit (*server_session);
1054 if (gnutls_credentials_set (*server_session, GNUTLS_CRD_CERTIFICATE,
1055 *server_credentials))
1057 g_warning (
"%s: failed to set server credentials\n", __func__);
1058 gnutls_deinit (*server_session);
1062 if (end_type == GNUTLS_SERVER)
1063 gnutls_certificate_server_set_request (*server_session,
1064 GNUTLS_CERT_REQUEST);
1084 const gchar *ca_cert_file,
const gchar *cert_file,
1085 const gchar *key_file, gnutls_session_t *server_session,
1086 gnutls_certificate_credentials_t *server_credentials)
1091 if (cert_file && key_file)
1095 ret = gnutls_certificate_set_x509_key_file (
1096 *server_credentials, cert_file, key_file, GNUTLS_X509_FMT_PEM);
1099 g_warning (
"%s: failed to set credentials key file: %s\n", __func__,
1100 gnutls_strerror (ret));
1101 g_warning (
"%s: cert file: %s\n", __func__, cert_file);
1102 g_warning (
"%s: key file : %s\n", __func__, key_file);
1103 gnutls_certificate_free_credentials (*server_credentials);
1112 ret = gnutls_certificate_set_x509_trust_file (
1113 *server_credentials, ca_cert_file, GNUTLS_X509_FMT_PEM);
1116 g_warning (
"%s: failed to set credentials trust file: %s\n", __func__,
1117 gnutls_strerror (ret));
1118 g_warning (
"%s: trust file: %s\n", __func__, ca_cert_file);
1119 gnutls_certificate_free_credentials (*server_credentials);
1125 server_credentials))
1127 gnutls_certificate_free_credentials (*server_credentials);
1149 gchar *key_file, gnutls_session_t *server_session,
1150 gnutls_certificate_credentials_t *server_credentials)
1153 server_session, server_credentials);
1171 const char *pub_key,
const char *priv_key,
1172 gnutls_session_t *session,
1173 gnutls_certificate_credentials_t *credentials)
1178 if (pub_key && priv_key)
1181 gnutls_datum_t pub, priv;
1183 pub.data = (
void *) pub_key;
1184 pub.size = strlen (pub_key);
1185 priv.data = (
void *) priv_key;
1186 priv.size = strlen (priv_key);
1188 ret = gnutls_certificate_set_x509_key_mem (*credentials, &pub, &priv,
1189 GNUTLS_X509_FMT_PEM);
1192 g_warning (
"%s: %s\n", __func__, gnutls_strerror (ret));
1200 gnutls_datum_t data;
1202 data.data = (
void *) ca_cert;
1203 data.size = strlen (ca_cert);
1204 ret = gnutls_certificate_set_x509_trust_mem (*credentials, &data,
1205 GNUTLS_X509_FMT_PEM);
1208 g_warning (
"%s: %s\n", __func__, gnutls_strerror (ret));
1209 gnutls_certificate_free_credentials (*credentials);
1216 gnutls_certificate_free_credentials (*credentials);
1233 const char *dhparams_file)
1236 gnutls_datum_t data;
1238 if (!creds || !dhparams_file)
1245#ifndef __clang_analyzer__
1247 gnutls_dh_params_t params = g_malloc0 (
sizeof (gnutls_dh_params_t));
1248 ret = gnutls_dh_params_import_pkcs3 (params, &data, GNUTLS_X509_FMT_PEM);
1256 gnutls_certificate_set_dh_params (creds, params);
1276 gnutls_certificate_credentials_t server_credentials)
1280 if (fcntl (server_socket, F_SETFL, O_NONBLOCK) == -1)
1282 g_warning (
"%s: failed to set server socket flag: %s\n", __func__,
1289 int ret = gnutls_bye (server_session, GNUTLS_SHUT_WR);
1290 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
1296 g_debug (
" Failed to gnutls_bye: %s\n",
1297 gnutls_strerror ((
int) ret));
1311 if (server_credentials)
1313 if (close (server_socket) == -1)
1315 g_warning (
"%s: failed to close server socket: %s\n", __func__,
1319 gnutls_deinit (server_session);
1320 gnutls_certificate_free_credentials (server_credentials);
1324 gnutls_deinit (server_session);
1325 close (server_socket);
1328 gnutls_global_deinit ();
int gvm_get_host_type(const gchar *str_stripped)
Determines the host type in a buffer.
Definition hosts.c:814
Protos and data structures for Hosts collections and single hosts objects.
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:1083
int set_gnutls_dhparams(gnutls_certificate_credentials_t creds, const char *dhparams_file)
Set a gnutls session's Diffie-Hellman parameters.
Definition serverutils.c:1232
static const char * get_cert_pub_mem()
Get public certificate from cert_pub_mem.
Definition serverutils.c:244
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:1148
int gvm_connection_sendf(gvm_connection_t *connection, const char *format,...)
Format and send a string to the server.
Definition serverutils.c:827
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:465
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:942
static void set_cert_priv_mem(const char *data)
Save cert_priv_mem with private certificate.
Definition serverutils.c:220
int gvm_server_vsendf(gnutls_session_t *session, const char *fmt, va_list ap)
Send a string to the server.
Definition serverutils.c:731
static const char * get_cert_priv_mem()
Get private certificate from cert_priv_mem.
Definition serverutils.c:233
int gvm_server_close(int socket, gnutls_session_t session)
Close a server connection and its socket.
Definition serverutils.c:497
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:483
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:713
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:265
int gvm_connection_sendf_xml(gvm_connection_t *connection, const char *format,...)
Format and send an XML string to the server.
Definition serverutils.c:915
static char * cert_pub_mem
Definition serverutils.c:199
static int gvm_server_sendf_quiet(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
Definition serverutils.c:847
void gvm_connection_close(gvm_connection_t *connection)
Close a server connection and its socket.
Definition serverutils.c:508
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:525
static int server_new_gnutls_init(gnutls_certificate_credentials_t *server_credentials)
Initialize a server session.
Definition serverutils.c:992
int gvm_socket_vsendf(int socket, const char *fmt, va_list ap)
Send a string to the server.
Definition serverutils.c:746
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:165
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:1170
static char * cert_priv_mem
Definition serverutils.c:200
void gvm_connection_free(gvm_connection_t *client_connection)
Free connection.
Definition serverutils.c:92
int gvm_server_verify(gnutls_session_t session, const char *host)
Verify certificate.
Definition serverutils.c:111
int gvm_server_sendf_xml(gnutls_session_t *session, const char *format,...)
Format and send an XML string to the server.
Definition serverutils.c:890
static int gvm_connection_sendf_quiet(gvm_connection_t *connection, const char *format,...)
Format and send a string to the server.
Definition serverutils.c:867
static int unix_vsendf_internal(int socket, const char *fmt, va_list ap, int quiet)
Send a string to the server.
Definition serverutils.c:661
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 credentials.
Definition serverutils.c:1024
static int gvm_connection_vsendf(gvm_connection_t *connection, const char *fmt, va_list ap)
Send a string to the server.
Definition serverutils.c:761
void unload_gnutls_file(gnutls_datum_t *data)
Unloads a gnutls_datum_t struct's data.
Definition serverutils.c:193
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:792
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:593
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:777
int gvm_server_sendf(gnutls_session_t *session, const char *format,...)
Format and send a string to the server.
Definition serverutils.c:807
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:1275
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:573
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:317
static void set_cert_pub_mem(const char *data)
Save cert_pub_mem with public certificate.
Definition serverutils.c:208
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:969
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