Changes in lib/ssl_gnutls.c [632f3d4:9b67285]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/ssl_gnutls.c
r632f3d4 r9b67285 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-201 1Wilmer van der Gaast and others *4 * Copyright 2002-2012 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 38 38 39 39 static gboolean initialized = FALSE; 40 gnutls_certificate_credentials xcred;40 gnutls_certificate_credentials_t xcred; 41 41 42 42 #include <limits.h> … … 60 60 gboolean verify; 61 61 62 gnutls_session session;62 gnutls_session_t session; 63 63 }; 64 65 static GHashTable *session_cache; 64 66 65 67 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); … … 85 87 gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM ); 86 88 87 /* Not needed in GnuTLS 2.11+ but we support older versions for now. */ 88 gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); 89 /* Not needed in GnuTLS 2.11+ (enabled by default there) so 90 don't do it (resets possible other defaults). */ 91 if( !gnutls_check_version( "2.11" ) ) 92 gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); 89 93 } 90 94 initialized = TRUE; … … 95 99 */ 96 100 101 session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); 102 97 103 atexit( ssl_deinit ); 98 104 } … … 102 108 gnutls_global_deinit(); 103 109 gnutls_certificate_free_credentials( xcred ); 110 g_hash_table_destroy( session_cache ); 111 session_cache = NULL; 104 112 } 105 113 … … 108 116 struct scd *conn = g_new0( struct scd, 1 ); 109 117 110 conn->fd = proxy_connect( host, port, ssl_connected, conn );111 118 conn->func = func; 112 119 conn->data = data; … … 114 121 conn->hostname = g_strdup( host ); 115 122 conn->verify = verify && global.conf->cafile; 123 conn->fd = proxy_connect( host, port, ssl_connected, conn ); 116 124 117 125 if( conn->fd < 0 ) … … 132 140 conn->data = data; 133 141 conn->inpa = -1; 134 conn->hostname = hostname;142 conn->hostname = g_strdup( hostname ); 135 143 136 144 /* For now, SSL verification is globally enabled by setting the cafile … … 169 177 int verifyret = 0; 170 178 gnutls_x509_crt_t cert; 171 const char *hostname;172 173 hostname= gnutls_session_get_ptr( session );179 struct scd *conn; 180 181 conn = gnutls_session_get_ptr( session ); 174 182 175 183 gnutlsret = gnutls_certificate_verify_peers2( session, &status ); … … 209 217 return VERIFY_CERT_ERROR; 210 218 211 if( !gnutls_x509_crt_check_hostname( cert, hostname ) )219 if( !gnutls_x509_crt_check_hostname( cert, conn->hostname ) ) 212 220 { 213 221 verifyret |= VERIFY_CERT_INVALID; … … 218 226 219 227 return verifyret; 228 } 229 230 struct ssl_session 231 { 232 size_t size; 233 char data[]; 234 }; 235 236 static void ssl_cache_add( struct scd *conn ) 237 { 238 size_t data_size; 239 struct ssl_session *data; 240 char *hostname; 241 242 if( !conn->hostname || 243 gnutls_session_get_data( conn->session, NULL, &data_size ) != 0 ) 244 return; 245 246 data = g_malloc( sizeof( struct ssl_session ) + data_size ); 247 if( gnutls_session_get_data( conn->session, data->data, &data->size ) != 0 ) 248 { 249 g_free( data ); 250 return; 251 } 252 253 hostname = g_strdup( conn->hostname ); 254 g_hash_table_insert( session_cache, hostname, data ); 255 } 256 257 static void ssl_cache_resume( struct scd *conn ) 258 { 259 struct ssl_session *data; 260 261 if( conn->hostname && 262 ( data = g_hash_table_lookup( session_cache, conn->hostname ) ) ) 263 { 264 gnutls_session_set_data( conn->session, data->data, data->size ); 265 g_hash_table_remove( session_cache, conn->hostname ); 266 } 220 267 } 221 268 … … 265 312 266 313 gnutls_init( &conn->session, GNUTLS_CLIENT ); 267 if( conn->verify ) 268 gnutls_session_set_ptr( conn->session, (void *) conn->hostname ); 314 gnutls_session_set_ptr( conn->session, (void *) conn ); 269 315 #if GNUTLS_VERSION_NUMBER < 0x020c00 270 316 gnutls_transport_set_lowat( conn->session, 0 ); … … 272 318 gnutls_set_default_priority( conn->session ); 273 319 gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred ); 320 if( conn->hostname && !isdigit( conn->hostname[0] ) ) 321 gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS, 322 conn->hostname, strlen( conn->hostname ) ); 274 323 275 324 sock_make_nonblocking( conn->fd ); 276 gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) GNUTLS_STUPID_CAST conn->fd ); 325 gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd ); 326 327 ssl_cache_resume( conn ); 277 328 278 329 return ssl_handshake( data, source, cond ); … … 316 367 /* For now we can't handle non-blocking perfectly everywhere... */ 317 368 sock_make_blocking( conn->fd ); 318 369 370 ssl_cache_add( conn ); 319 371 conn->established = TRUE; 320 372 conn->func( conn->data, 0, conn, cond ); … … 400 452 if( conn->session ) 401 453 gnutls_deinit( conn->session ); 454 g_free( conn->hostname ); 402 455 g_free( conn ); 403 456 }
Note: See TracChangeset
for help on using the changeset viewer.