32 #include "../base/hosts.h"
34 #include <arpa/inet.h>
39 #include <gnutls/x509.h>
44 #include <sys/socket.h>
45 #include <sys/types.h>
52 #define G_LOG_DOMAIN "lib serv"
63 const gchar *, gnutls_session_t *,
64 gnutls_certificate_credentials_t *);
79 if (fcntl (client_connection->
socket, F_SETFL, O_NONBLOCK) == -1)
81 g_warning (
"%s: failed to set server socket flag: %s\n", __FUNCTION__,
86 if (shutdown (client_connection->
socket, SHUT_RDWR) == -1)
88 if (errno == ENOTCONN)
90 g_warning (
"%s: failed to shutdown server socket: %s\n", __FUNCTION__,
95 if (close (client_connection->
socket) == -1)
97 g_warning (
"%s: failed to close server socket: %s\n", __FUNCTION__,
113 if (client_connection->
tls)
135 ret = gnutls_certificate_verify_peers2 (session, &status);
138 g_warning (
"%s: failed to verify peers: %s", __FUNCTION__,
139 gnutls_strerror (ret));
143 if (status & GNUTLS_CERT_INVALID)
144 g_warning (
"%s: the certificate is not trusted", __FUNCTION__);
146 if (status & GNUTLS_CERT_SIGNER_NOT_CA)
147 g_warning (
"%s: the certificate's issuer is not a CA", __FUNCTION__);
149 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
150 g_warning (
"%s: the certificate was signed using an insecure algorithm",
153 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
154 g_warning (
"%s: the certificate hasn't got a known issuer", __FUNCTION__);
156 if (status & GNUTLS_CERT_REVOKED)
157 g_warning (
"%s: the certificate has been revoked", __FUNCTION__);
159 if (status & GNUTLS_CERT_EXPIRED)
160 g_warning (
"%s: the certificate has expired", __FUNCTION__);
162 if (status & GNUTLS_CERT_NOT_ACTIVATED)
163 g_warning (
"%s: the certificate is not yet activated", __FUNCTION__);
186 if (!(f = fopen (file,
"r")) || fseek (f, 0, SEEK_END) != 0
187 || (filelen = ftell (f)) < 0 || fseek (f, 0, SEEK_SET) != 0
188 || !(ptr = g_malloc0 ((
size_t) filelen))
189 || fread (ptr, 1, (
size_t) filelen, f) < (
size_t) filelen)
196 loaded_file->data = ptr;
197 loaded_file->size = filelen;
276 const gnutls_datum_t *req_ca_rdn,
int nreqs,
277 const gnutls_pk_algorithm_t *sign_algos,
278 int sign_algos_length, gnutls_retr2_st *st)
282 static gnutls_x509_crt_t crt;
283 static gnutls_x509_privkey_t key;
289 (void) sign_algos_length;
292 gnutls_x509_crt_init (&crt);
293 ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
297 st->cert.x509 = &crt;
298 st->cert_type = GNUTLS_CRT_X509;
303 gnutls_x509_privkey_init (&key);
304 ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
309 st->key_type = GNUTLS_PRIVKEY_X509;
328 const char *ca_mem,
const char *pub_mem,
329 const char *priv_mem,
int verify)
333 struct addrinfo address_hints;
334 struct addrinfo *addresses, *
address;
338 gnutls_certificate_credentials_t credentials;
341 if (port < 1 || port > 65535)
343 g_warning (
"Failed to create client TLS session. "
352 g_warning (
"Failed to create client TLS session. Invalid host %s", host);
362 g_warning (
"Failed to create client TLS session.");
366 if (ca_mem && pub_mem && priv_mem)
371 gnutls_certificate_set_retrieve_function (credentials,
377 port_string = g_strdup_printf (
"%i", port);
381 memset (&address_hints, 0,
sizeof (address_hints));
382 address_hints.ai_family = AF_UNSPEC;
383 address_hints.ai_socktype = SOCK_STREAM;
384 address_hints.ai_protocol = 0;
386 if (getaddrinfo (host, port_string, &address_hints, &addresses))
388 g_free (port_string);
389 g_warning (
"Failed to get server addresses for %s: %s", host,
390 gai_strerror (errno));
391 gnutls_deinit (*session);
392 gnutls_certificate_free_credentials (credentials);
395 g_free (port_string);
403 if (
address->ai_family == AF_INET6)
404 server_socket = socket (PF_INET6, SOCK_STREAM, 0);
406 server_socket = socket (PF_INET, SOCK_STREAM, 0);
407 if (server_socket == -1)
409 g_warning (
"Failed to create server socket");
410 freeaddrinfo (addresses);
411 gnutls_deinit (*session);
412 gnutls_certificate_free_credentials (credentials);
418 if (connect (server_socket,
address->ai_addr,
address->ai_addrlen) == -1)
420 close (server_socket);
426 freeaddrinfo (addresses);
430 g_warning (
"Failed to connect to server");
431 gnutls_deinit (*session);
432 gnutls_certificate_free_credentials (credentials);
436 g_debug (
" Connected to server '%s' port %d.", host, port);
444 close (server_socket);
445 gnutls_deinit (*session);
446 gnutls_certificate_free_credentials (credentials);
448 close (server_socket);
453 close (server_socket);
457 return server_socket;
476 int port,
const char *ca_mem,
const char *pub_mem,
477 const char *priv_mem)
480 ca_mem && pub_mem && priv_mem);
540 unsigned int retries;
542 gnutls_transport_set_ptr (*session,
543 (gnutls_transport_ptr_t) GSIZE_TO_POINTER (socket));
548 int ret = gnutls_handshake (*session);
551 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
554 usleep (MIN ((retries - 10) * 10000, 5000000));
559 g_debug (
"Failed to shake hands with server '%s' port %d: %s", host,
560 port, gnutls_strerror (ret));
562 g_debug (
"Failed to shake hands with peer: %s", gnutls_strerror (ret));
563 if (shutdown (socket, SHUT_RDWR) == -1)
564 g_debug (
"Failed to shutdown server socket");
568 g_debug (
" Shook hands with server '%s' port %d.", host, port);
570 g_debug (
" Shook hands with peer.");
606 va_list ap,
int quiet)
611 left = vasprintf (&
string, fmt, ap);
621 g_debug (
" send %d from %.*s[...]", left, left < 30 ? left : 30,
623 count = gnutls_record_send (*session,
string, left);
626 if (count == GNUTLS_E_INTERRUPTED)
629 if (count == GNUTLS_E_REHANDSHAKE)
633 g_message (
" %s rehandshake", __FUNCTION__);
636 g_warning (
"Failed to write to server: %s", gnutls_strerror (count));
644 g_debug (
"= server closed");
649 g_debug (
"=> %.*s", (
int) count,
string);
675 char *string_start, *string;
678 left = vasprintf (&
string, fmt, ap);
682 string_start = string;
688 g_debug (
" send %d from %.*s[...]", left, left < 30 ? left : 30,
690 count = write (socket,
string, left);
693 if (errno == EINTR || errno == EAGAIN)
695 g_warning (
"Failed to write to server: %s", strerror (errno));
700 g_debug (
"=> %.*s", (
int) count,
string);
709 g_free (string_start);
726 va_list ap,
int quiet)
824 va_start (ap, format);
844 va_start (ap, format);
864 va_start (ap, format);
885 va_start (ap, format);
908 va_start (ap, format);
909 msg = g_markup_vprintf_escaped (format, ap);
933 va_start (ap, format);
934 msg = g_markup_vprintf_escaped (format, ap);
960 va_start (ap, format);
961 msg = g_markup_vprintf_escaped (format, ap);
982 const char *format, ...)
988 va_start (ap, format);
989 msg = g_markup_vprintf_escaped (format, ap);
1005 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1008 if (gnutls_global_init ())
1010 g_warning (
"Failed to initialize GNUTLS.");
1014 if (gnutls_certificate_allocate_credentials (server_credentials))
1016 g_warning (
"%s: failed to allocate server credentials\n", __FUNCTION__);
1033 gnutls_session_t *server_session,
1034 gnutls_certificate_credentials_t *server_credentials)
1038 if (gnutls_init (server_session, end_type))
1040 g_warning (
"%s: failed to initialise server session\n", __FUNCTION__);
1052 if ((err_gnutls = gnutls_priority_set_direct (
1053 *server_session, priority ? priority :
"NORMAL", NULL)))
1055 g_warning (
"%s: failed to set tls priorities: %s\n", __FUNCTION__,
1056 gnutls_strerror (err_gnutls));
1057 gnutls_deinit (*server_session);
1061 if (gnutls_credentials_set (*server_session, GNUTLS_CRD_CERTIFICATE,
1062 *server_credentials))
1064 g_warning (
"%s: failed to set server credentials\n", __FUNCTION__);
1065 gnutls_deinit (*server_session);
1069 if (end_type == GNUTLS_SERVER)
1070 gnutls_certificate_server_set_request (*server_session,
1071 GNUTLS_CERT_REQUEST);
1091 const gchar *ca_cert_file,
const gchar *cert_file,
1092 const gchar *key_file, gnutls_session_t *server_session,
1093 gnutls_certificate_credentials_t *server_credentials)
1098 if (cert_file && key_file)
1102 ret = gnutls_certificate_set_x509_key_file (
1103 *server_credentials, cert_file, key_file, GNUTLS_X509_FMT_PEM);
1106 g_warning (
"%s: failed to set credentials key file: %s\n",
1107 __FUNCTION__, gnutls_strerror (ret));
1108 g_warning (
"%s: cert file: %s\n", __FUNCTION__, cert_file);
1109 g_warning (
"%s: key file : %s\n", __FUNCTION__, key_file);
1110 gnutls_certificate_free_credentials (*server_credentials);
1119 ret = gnutls_certificate_set_x509_trust_file (
1120 *server_credentials, ca_cert_file, GNUTLS_X509_FMT_PEM);
1123 g_warning (
"%s: failed to set credentials trust file: %s\n",
1124 __FUNCTION__, gnutls_strerror (ret));
1125 g_warning (
"%s: trust file: %s\n", __FUNCTION__, ca_cert_file);
1126 gnutls_certificate_free_credentials (*server_credentials);
1132 server_credentials))
1134 gnutls_certificate_free_credentials (*server_credentials);
1156 gchar *key_file, gnutls_session_t *server_session,
1157 gnutls_certificate_credentials_t *server_credentials)
1160 server_session, server_credentials);
1178 const char *pub_key,
const char *priv_key,
1179 gnutls_session_t *session,
1180 gnutls_certificate_credentials_t *credentials)
1185 if (pub_key && priv_key)
1188 gnutls_datum_t pub, priv;
1190 pub.data = (
void *) pub_key;
1191 pub.size = strlen (pub_key);
1192 priv.data = (
void *) priv_key;
1193 priv.size = strlen (priv_key);
1195 ret = gnutls_certificate_set_x509_key_mem (*credentials, &pub, &priv,
1196 GNUTLS_X509_FMT_PEM);
1199 g_warning (
"%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1207 gnutls_datum_t data;
1209 data.data = (
void *) ca_cert;
1210 data.size = strlen (ca_cert);
1211 ret = gnutls_certificate_set_x509_trust_mem (*credentials, &data,
1212 GNUTLS_X509_FMT_PEM);
1215 g_warning (
"%s: %s\n", __FUNCTION__, gnutls_strerror (ret));
1216 gnutls_certificate_free_credentials (*credentials);
1223 gnutls_certificate_free_credentials (*credentials);
1240 const char *dhparams_file)
1243 gnutls_datum_t data;
1245 if (!creds || !dhparams_file)
1250 gnutls_dh_params_t params = g_malloc0 (
sizeof (gnutls_dh_params_t));
1251 ret = gnutls_dh_params_import_pkcs3 (params, &data, GNUTLS_X509_FMT_PEM);
1256 gnutls_certificate_set_dh_params (creds, params);
1274 gnutls_certificate_credentials_t server_credentials)
1278 if (fcntl (server_socket, F_SETFL, O_NONBLOCK) == -1)
1280 g_warning (
"%s: failed to set server socket flag: %s\n", __FUNCTION__,
1287 int ret = gnutls_bye (server_session, GNUTLS_SHUT_WR);
1288 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
1294 g_debug (
" Failed to gnutls_bye: %s\n",
1295 gnutls_strerror ((
int) ret));
1309 if (server_credentials)
1311 if (close (server_socket) == -1)
1313 g_warning (
"%s: failed to close server socket: %s\n", __FUNCTION__,
1317 gnutls_deinit (server_session);
1318 gnutls_certificate_free_credentials (server_credentials);
1322 gnutls_deinit (server_session);
1323 close (server_socket);
1326 gnutls_global_deinit ();