48 #include <arpa/inet.h> 53 #include <sys/types.h> 54 #include <sys/socket.h> 75 #define G_LOG_DOMAIN "lib serv" 84 static int server_attach_internal (
int, gnutls_session_t *,
86 static int server_new_internal (
unsigned int,
const char *,
88 const gchar *,
const gchar *,
90 gnutls_certificate_credentials_t *);
107 if (fcntl (client_connection->
socket, F_SETFL, O_NONBLOCK) == -1)
109 g_warning (
"%s: failed to set server socket flag: %s\n", __FUNCTION__,
114 if (shutdown (client_connection->
socket, SHUT_RDWR) == -1)
116 if (errno == ENOTCONN)
118 g_warning (
"%s: failed to shutdown server socket: %s\n", __FUNCTION__,
123 if (close (client_connection->
socket) == -1)
125 g_warning (
"%s: failed to close server socket: %s\n", __FUNCTION__,
141 if (client_connection->
tls)
146 close_unix (client_connection);
165 ret = gnutls_certificate_verify_peers2 (session, &status);
168 g_warning (
"%s: failed to verify peers: %s",
170 gnutls_strerror (ret));
174 if (status & GNUTLS_CERT_INVALID)
175 g_warning (
"%s: the certificate is not trusted", __FUNCTION__);
177 if (status & GNUTLS_CERT_SIGNER_NOT_CA)
178 g_warning (
"%s: the certificate's issuer is not a CA", __FUNCTION__);
180 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
181 g_warning (
"%s: the certificate was signed using an insecure algorithm",
184 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
185 g_warning (
"%s: the certificate hasn't got a known issuer", __FUNCTION__);
187 if (status & GNUTLS_CERT_REVOKED)
188 g_warning (
"%s: the certificate has been revoked", __FUNCTION__);
190 if (status & GNUTLS_CERT_EXPIRED)
191 g_warning (
"%s: the certificate has expired", __FUNCTION__);
193 if (status & GNUTLS_CERT_NOT_ACTIVATED)
194 g_warning (
"%s: the certificate is not yet activated", __FUNCTION__);
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)
229 loaded_file->data = ptr;
230 loaded_file->size = filelen;
247 static char *cert_pub_mem = NULL;
248 static char *cert_priv_mem = NULL;
251 set_cert_pub_mem (
const char *data)
254 g_free (cert_pub_mem);
255 cert_pub_mem = g_strdup (data);
259 set_cert_priv_mem (
const char *data)
262 g_free (cert_priv_mem);
263 cert_priv_mem = g_strdup (data);
269 return cert_priv_mem;
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)
286 static gnutls_x509_crt_t crt;
287 static gnutls_x509_privkey_t key;
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);
301 st->cert.x509 = &crt;
302 st->cert_type = GNUTLS_CRT_X509;
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);
313 st->key_type = GNUTLS_PRIVKEY_X509;
332 int port,
const char *ca_mem,
333 const char *pub_mem,
const char *priv_mem,
338 struct addrinfo address_hints;
339 struct addrinfo *addresses, *
address;
345 gnutls_certificate_credentials_t credentials;
357 g_warning (
"Failed to create client TLS session.");
361 if (ca_mem && pub_mem && priv_mem)
363 set_cert_pub_mem (pub_mem);
364 set_cert_priv_mem (priv_mem);
366 gnutls_certificate_set_retrieve_function (credentials,
367 client_cert_callback);
372 port_string = g_strdup_printf (
"%i", port);
376 if (WSAStartup (MAKEWORD (2, 2), &wsaData))
378 g_warning (
"WSAStartup failed");
379 gnutls_deinit (*session);
380 gnutls_certificate_free_credentials (credentials);
381 g_free (port_string);
388 memset (&address_hints, 0,
sizeof (address_hints));
389 address_hints.ai_family = AF_UNSPEC;
390 address_hints.ai_socktype = SOCK_STREAM;
392 address_hints.ai_flags = AI_NUMERICSERV;
394 address_hints.ai_protocol = 0;
396 if (getaddrinfo (host, port_string, &address_hints, &addresses))
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);
405 g_free (port_string);
413 if (
address->ai_family == AF_INET6)
414 server_socket = socket (PF_INET6, SOCK_STREAM, 0);
416 server_socket = socket (PF_INET, SOCK_STREAM, 0);
417 if (server_socket == -1)
419 g_warning (
"Failed to create server socket");
420 freeaddrinfo (addresses);
421 gnutls_deinit (*session);
422 gnutls_certificate_free_credentials (credentials);
430 if (connect (server_socket,
address->ai_addr,
address->ai_addrlen) == -1)
432 close (server_socket);
438 freeaddrinfo (addresses);
442 g_warning (
"Failed to connect to server");
443 gnutls_deinit (*session);
444 gnutls_certificate_free_credentials (credentials);
448 g_debug (
" Connected to server '%s' port %d.", host, port);
451 ret = server_attach_internal (server_socket, session, host, port);
456 close (server_socket);
457 gnutls_deinit (*session);
458 gnutls_certificate_free_credentials (credentials);
465 return server_socket;
484 int port,
const char *ca_mem,
485 const char *pub_mem,
const char *priv_mem)
488 priv_mem, ca_mem && pub_mem && priv_mem);
544 gnutls_session_t * server_session)
548 if (connect (server_socket, (
struct sockaddr *) server_address,
549 sizeof (
struct sockaddr_in)) == -1)
551 g_warning (
"%s: failed to connect to server: %s\n", __FUNCTION__,
555 g_debug (
" Connected to server on socket %i.\n", server_socket);
575 server_attach_internal (
int socket, gnutls_session_t * session,
576 const char *host,
int port)
578 unsigned int retries;
580 struct sigaction new_action, original_action;
583 gnutls_transport_set_ptr (*session,
584 (gnutls_transport_ptr_t) GSIZE_TO_POINTER (socket));
587 new_action.sa_flags = 0;
588 if (sigemptyset (&new_action.sa_mask))
590 new_action.sa_handler = SIG_IGN;
591 if (sigaction (SIGPIPE, &new_action, &original_action))
598 int ret = gnutls_handshake (*session);
601 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
604 usleep (MIN ((retries - 10) * 10000, 5000000));
609 g_debug (
"Failed to shake hands with server '%s' port %d: %s",
610 host, port, gnutls_strerror (ret));
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");
617 sigaction (SIGPIPE, &original_action, NULL);
622 g_debug (
" Shook hands with server '%s' port %d.", host, port);
624 g_debug (
" Shook hands with peer.");
627 if (sigaction (SIGPIPE, &original_action, NULL))
648 ret = server_attach_internal (socket, session, NULL, 0);
664 openvas_server_vsendf_internal (gnutls_session_t *session,
const char *fmt,
665 va_list ap,
int quiet)
668 struct sigaction new_action, original_action;
674 new_action.sa_flags = 0;
675 if (sigemptyset (&new_action.sa_mask))
677 new_action.sa_handler = SIG_IGN;
678 if (sigaction (SIGPIPE, &new_action, &original_action))
682 left = vasprintf (&
string, fmt, ap);
692 g_debug (
" send %d from %.*s[...]",
693 left, left < 30 ? left : 30,
string);
694 count = gnutls_record_send (*session,
string, left);
697 if (count == GNUTLS_E_INTERRUPTED)
700 if (count == GNUTLS_E_REHANDSHAKE)
704 g_message (
" %s rehandshake", __FUNCTION__);
707 g_warning (
"Failed to write to server: %s", gnutls_strerror (count));
710 sigaction (SIGPIPE, &original_action, NULL);
720 g_debug (
"= server closed");
723 sigaction (SIGPIPE, &original_action, NULL);
730 g_debug (
"=> %.*s", (
int) count,
string);
738 sigaction (SIGPIPE, &original_action, NULL);
758 unix_vsendf_internal (
int socket,
const char *fmt, va_list ap,
int quiet)
761 struct sigaction new_action, original_action;
763 char *string_start, *
string;
767 new_action.sa_flags = 0;
768 if (sigemptyset (&new_action.sa_mask))
771 new_action.sa_handler = SIG_IGN;
772 if (sigaction (SIGPIPE, &new_action, &original_action))
777 left = vasprintf (&
string, fmt, ap);
787 g_debug (
" send %d from %.*s[...]",
788 left, left < 30 ? left : 30,
string);
789 count = write (socket,
string, left);
792 if (errno == EINTR || errno == EAGAIN)
794 g_warning (
"Failed to write to server: %s", strerror (errno));
797 sigaction (SIGPIPE, &original_action, NULL);
804 g_debug (
"=> %.*s", (
int) count,
string);
813 sigaction (SIGPIPE, &original_action, NULL);
817 g_free (string_start);
834 const char *fmt, va_list ap,
int quiet)
837 return openvas_server_vsendf_internal (&connection->
session, fmt, ap, quiet);
838 return unix_vsendf_internal (connection->
socket, fmt, ap, quiet);
853 return openvas_server_vsendf_internal (session, fmt, ap, 0);
869 return openvas_connection_vsendf_internal (connection, fmt, ap, 0);
885 return openvas_server_vsendf_internal (session, fmt, ap, 1);
902 return openvas_connection_vsendf_internal (connection, fmt, ap, 1);
919 va_start (ap, format);
941 va_start (ap, format);
961 va_start (ap, format);
983 va_start (ap, format);
1006 va_start (ap, format);
1007 msg = g_markup_vprintf_escaped (format, ap);
1026 const char *format, ...)
1032 va_start (ap, format);
1033 msg = g_markup_vprintf_escaped (format, ap);
1054 const char *format, ...)
1060 va_start (ap, format);
1061 msg = g_markup_vprintf_escaped (format, ap);
1089 va_start (ap, format);
1090 msg = g_markup_vprintf_escaped (format, ap);
1098 server_new_gnutls_init (gnutls_certificate_credentials_t *server_credentials)
1101 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1104 if (gnutls_global_init ())
1106 g_warning (
"Failed to initialize GNUTLS.");
1110 if (gnutls_certificate_allocate_credentials (server_credentials))
1112 g_warning (
"%s: failed to allocate server credentials\n", __FUNCTION__);
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)
1125 if (gnutls_init (server_session, end_type))
1127 g_warning (
"%s: failed to initialise server session\n", __FUNCTION__);
1139 if ((err_gnutls = gnutls_priority_set_direct (*server_session,
1140 priority ? priority :
"NORMAL",
1143 g_warning (
"%s: failed to set tls priorities: %s\n", __FUNCTION__,
1144 gnutls_strerror (err_gnutls));
1145 gnutls_deinit (*server_session);
1149 if (gnutls_credentials_set
1150 (*server_session, GNUTLS_CRD_CERTIFICATE, *server_credentials))
1152 g_warning (
"%s: failed to set server credentials\n", __FUNCTION__);
1153 gnutls_deinit (*server_session);
1157 if (end_type == GNUTLS_SERVER)
1158 gnutls_certificate_server_set_request (*server_session,
1159 GNUTLS_CERT_REQUEST);
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)
1184 if (server_new_gnutls_init (server_credentials))
1187 if (cert_file && key_file
1189 (gnutls_certificate_set_x509_key_file
1190 (*server_credentials, cert_file, key_file, GNUTLS_X509_FMT_PEM) < 0))
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);
1201 (gnutls_certificate_set_x509_trust_file
1202 (*server_credentials, ca_cert_file, GNUTLS_X509_FMT_PEM) < 0))
1204 g_warning (
"%s: failed to set credentials trust file: %s\n", __FUNCTION__,
1206 gnutls_certificate_free_credentials (*server_credentials);
1210 if (server_new_gnutls_set (end_type, priority, server_session,
1211 server_credentials))
1213 gnutls_certificate_free_credentials (*server_credentials);
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)
1240 return server_new_internal (end_type, NULL,
1241 ca_cert_file, cert_file, key_file,
1242 server_session, server_credentials);
1260 const char *pub_key,
const char *priv_key,
1261 gnutls_session_t *session,
1262 gnutls_certificate_credentials_t *credentials)
1264 if (server_new_gnutls_init (credentials))
1267 if (pub_key && priv_key)
1270 gnutls_datum_t pub, priv;
1272 pub.data = (
void *) pub_key;
1273 pub.size = strlen (pub_key);
1274 priv.data = (
void *) priv_key;
1275 priv.size = strlen (priv_key);
1277 ret = gnutls_certificate_set_x509_key_mem (*credentials, &pub, &priv,
1278 GNUTLS_X509_FMT_PEM);
1281 g_warning (
"%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1289 gnutls_datum_t data;
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);
1297 g_warning (
"%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1298 gnutls_certificate_free_credentials (*credentials);
1303 if (server_new_gnutls_set (end_type, NULL, session, credentials))
1305 gnutls_certificate_free_credentials (*credentials);
1322 const char *dhparams_file)
1325 gnutls_datum_t data;
1327 if (!creds || !dhparams_file)
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);
1338 gnutls_certificate_set_dh_params (creds, params);
1356 gnutls_certificate_credentials_t server_credentials)
1359 struct sigaction new_action, original_action;
1365 if (fcntl (server_socket, F_SETFL, 0L) == -1)
1367 g_warning (
"%s: failed to set server socket flag: %s\n", __FUNCTION__,
1376 if (fcntl (server_socket, F_SETFL, O_NONBLOCK) == -1)
1378 g_warning (
"%s: failed to set server socket flag: %s\n", __FUNCTION__,
1386 new_action.sa_flags = 0;
1387 if (sigemptyset (&new_action.sa_mask))
1389 new_action.sa_handler = SIG_IGN;
1390 if (sigaction (SIGPIPE, &new_action, &original_action))
1396 int ret = gnutls_bye (server_session, GNUTLS_SHUT_WR);
1397 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
1403 g_debug (
" Failed to gnutls_bye: %s\n",
1404 gnutls_strerror ((
int) ret));
1418 if (server_credentials)
1421 if (sigaction (SIGPIPE, &original_action, NULL))
1424 if (shutdown (server_socket, SHUT_RDWR) == -1)
1426 if (errno == ENOTCONN)
1428 g_warning (
"%s: failed to shutdown server socket: %s\n", __FUNCTION__,
1434 if (close (server_socket) == -1)
1436 g_warning (
"%s: failed to close server socket: %s\n", __FUNCTION__,
1440 gnutls_deinit (server_session);
1441 gnutls_certificate_free_credentials (server_credentials);
1445 gnutls_deinit (server_session);
1447 if (sigaction (SIGPIPE, &original_action, NULL))
1450 close (server_socket);
1453 gnutls_global_deinit ();
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'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'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.
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'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.