Last active
December 11, 2015 02:08
-
-
Save nullren/4527919 to your computer and use it in GitHub Desktop.
Revisions
-
renning bruns revised this gist
Feb 10, 2013 . 1 changed file with 79 additions and 52 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ === modified file 'lib/ssl_client.h' --- lib/ssl_client.h 2011-12-23 22:40:17 +0000 +++ lib/ssl_client.h 2013-01-20 19:00:01 +0000 @@ -49,19 +49,39 @@ #define VERIFY_CERT_EXPIRED 256 #define VERIFY_CERT_WRONG_HOSTNAME 512 @@ -15,16 +15,16 @@ + +struct scd +{ + ssl_input_function func; + ssl_credentials_func cred_func; + gpointer data; + int fd; + gboolean established; + int inpa; + char *hostname; + gboolean verify; + gnutls_session_t session; + gnutls_certificate_credentials_t xcred; +}; + @@ -44,8 +44,20 @@ === modified file 'lib/ssl_gnutls.c' --- lib/ssl_gnutls.c 2012-12-24 19:17:37 +0000 +++ lib/ssl_gnutls.c 2013-02-03 02:00:21 +0000 @@ -36,8 +36,11 @@ int ssl_errno = 0; +static int connect_counter = 0; static gboolean initialized = FALSE; +static gboolean creds_initialized = FALSE; gnutls_certificate_credentials_t xcred; +gnutls_certificate_credentials_t creds_user; #include <limits.h> @@ -49,19 +52,7 @@ #define SSLDEBUG 0 @@ -66,32 +78,24 @@ static GHashTable *session_cache; static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); @@ -72,7 +63,7 @@ static void ssl_log( int level, const char *line ) { - printf( "%d %s", level, line ); + //fprintf(stderr, "%d %s", level, line ); } void ssl_init( void ) @@ -82,6 +73,7 @@ gnutls_global_init(); gnutls_certificate_allocate_credentials( &xcred ); + if( global.conf->cafile ) { gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM ); @@ -94,29 +86,75 @@ initialized = TRUE; gnutls_global_set_log_function( ssl_log ); @@ -103,7 +107,7 @@ - - atexit( ssl_deinit ); -} + gnutls_global_set_log_level( 9 ); + + session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); + @@ -112,31 +116,22 @@ + +void ssl_init_with(gpointer data) +{ + struct scd *conn = data; + + if( creds_initialized ) + return; + + gnutls_global_init(); + gnutls_certificate_allocate_credentials( &(conn->xcred) ); + + creds_user = conn->xcred; + + conn->cred_func(conn); + + creds_initialized = TRUE; + + gnutls_global_set_log_function( ssl_log ); + gnutls_global_set_log_level( 9 ); + + session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); + @@ -146,7 +141,29 @@ static void ssl_deinit( void ) { + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s:ssl_deinit: called!\n", TAG); + } + gnutls_global_deinit(); - gnutls_certificate_free_credentials( xcred ); - g_hash_table_destroy( session_cache ); + + if(xcred != NULL) + gnutls_certificate_free_credentials( xcred ); + xcred = NULL; + + if(creds_user != NULL) + gnutls_certificate_free_credentials( creds_user ); + creds_user = NULL; + + if( session_cache != NULL) + g_hash_table_destroy( session_cache ); session_cache = NULL; + + initialized = FALSE; + creds_initialized = FALSE; } void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data ) { @@ -160,19 +177,30 @@ conn->func = func; + conn->cred_func = cred_func; conn->data = data; + conn->xcred = creds_user; conn->inpa = -1; conn->hostname = g_strdup( host ); conn->verify = verify && global.conf->cafile; @@ -125,12 +163,18 @@ if( conn->fd < 0 ) { g_free( conn ); + if( connect_counter++ < 3 ){ + ssl_deinit(); + return ssl_connect_with_creds(host, port, verify, func, cred_func, data); + } else + connect_counter = 0; return NULL; } return conn; } + void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) { struct scd *conn = g_new0( struct scd, 1 ); @@ -308,15 +352,18 @@ return FALSE; } @@ -194,7 +222,7 @@ if( conn->hostname && !isdigit( conn->hostname[0] ) ) gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS, conn->hostname, strlen( conn->hostname ) ); @@ -343,7 +390,7 @@ } else { @@ -203,7 +231,7 @@ gnutls_deinit( conn->session ); closesocket( conn->fd ); @@ -369,7 +416,7 @@ ssl_cache_add( conn ); conn->established = TRUE; @@ -212,4 +240,3 @@ } } -
renning bruns created this gist
Jan 14, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,215 @@ === modified file 'lib/ssl_client.h' --- lib/ssl_client.h212011-12-23 22:40:17 +0000 +++ lib/ssl_client.h 2013-01-13 21:14:56 +0000 @@ -49,19 +49,39 @@ #define VERIFY_CERT_EXPIRED 256 #define VERIFY_CERT_WRONG_HOSTNAME 512 +#include <gnutls/gnutls.h> + extern int ssl_errno; /* This is what your callback function should look like. */ typedef gboolean (*ssl_input_function)(gpointer, int, void*, b_input_condition); +typedef void (*ssl_credentials_func)(gpointer); + +struct scd +{ + ssl_input_function func; + ssl_credentials_func cred_func; + gpointer data; + int fd; + gboolean established; + int inpa; + char *hostname; + gboolean verify; + gnutls_session_t session; + gnutls_certificate_credentials_t xcred; +}; + /* Perform any global initialization the SSL library might need. */ G_MODULE_EXPORT void ssl_init( void ); +G_MODULE_EXPORT void ssl_init_with( gpointer ); /* Connect to host:port, call the given function when the connection is ready to be used for SSL traffic. This is all done asynchronously, no blocking I/O! (Except for the DNS lookups, for now...) */ G_MODULE_EXPORT void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data ); +G_MODULE_EXPORT void *ssl_connect_with_creds( char *host, int port, gboolean verify, ssl_input_function func, ssl_credentials_func cred_func, gpointer data ); /* Start an SSL session on an existing fd. Useful for STARTTLS functionality, for example in Jabber. */ === modified file 'lib/ssl_gnutls.c' --- lib/ssl_gnutls.c 2012-12-24 19:17:37 +0000 +++ lib/ssl_gnutls.c 2013-01-14 04:17:47 +0000 @@ -49,19 +49,7 @@ #define SSLDEBUG 0 -struct scd -{ - ssl_input_function func; - gpointer data; - int fd; - gboolean established; - int inpa; - char *hostname; - gboolean verify; - - gnutls_session_t session; -}; - +static char *TAG = "SSL_GNUTLS"; static GHashTable *session_cache; static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); @@ -72,16 +60,23 @@ static void ssl_log( int level, const char *line ) { - printf( "%d %s", level, line ); + fprintf(stderr, "%d %s", level, line ); } void ssl_init( void ) { + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s: ssl_init called!\n", TAG); + } if( initialized ) return; gnutls_global_init(); gnutls_certificate_allocate_credentials( &xcred ); + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s: ssl_init: address of xcred %p, %p\n", TAG, xcred, &xcred); + } + if( global.conf->cafile ) { gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM ); @@ -94,14 +89,46 @@ initialized = TRUE; gnutls_global_set_log_function( ssl_log ); - /* - gnutls_global_set_log_level( 3 ); - */ - - session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); - - atexit( ssl_deinit ); -} + //gnutls_global_set_log_level( 9 ); + + session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); + + atexit( ssl_deinit ); +} + +void ssl_init_with(gpointer data) +{ + struct scd *conn = data; + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s ssl_init_with called!\n", TAG); + } + + if( initialized ) + ssl_deinit(); + + gnutls_global_init(); + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s: ssl_init_with: xcred address %p %p\n", TAG, xcred, &xcred); + } + gnutls_certificate_allocate_credentials( &(conn->xcred) ); + xcred = conn->xcred; + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s: ssl_init_with: xcred address %p %p\n", TAG, xcred, &xcred); + } + conn->cred_func(conn); + initialized = TRUE; + if( getenv("BITLBEE_DEBUG") ){ + fprintf(stderr, "%s: ssl_init_with: conn->xcred address %p %p\b", TAG, conn->xcred, &conn->xcred); + } + + gnutls_global_set_log_function( ssl_log ); + //gnutls_global_set_log_level( 9 ); + + session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free ); + + atexit( ssl_deinit ); +} + static void ssl_deinit( void ) { @@ -113,10 +140,17 @@ void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data ) { + return ssl_connect_with_creds(host, port, verify, func, NULL, data); +} + +void *ssl_connect_with_creds( char *host, int port, gboolean verify, ssl_input_function func, ssl_credentials_func cred_func, gpointer data ) +{ struct scd *conn = g_new0( struct scd, 1 ); conn->func = func; + conn->cred_func = cred_func; conn->data = data; + conn->xcred = xcred; conn->inpa = -1; conn->hostname = g_strdup( host ); conn->verify = verify && global.conf->cafile; @@ -131,6 +165,7 @@ return conn; } + void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data ) { struct scd *conn = g_new0( struct scd, 1 ); @@ -308,15 +343,18 @@ return FALSE; } - ssl_init(); + if( conn->cred_func != NULL ) + ssl_init_with(conn); + else + ssl_init(); - gnutls_init( &conn->session, GNUTLS_CLIENT ); + gnutls_init( &(conn->session), GNUTLS_CLIENT ); gnutls_session_set_ptr( conn->session, (void *) conn ); #if GNUTLS_VERSION_NUMBER < 0x020c00 gnutls_transport_set_lowat( conn->session, 0 ); #endif gnutls_set_default_priority( conn->session ); - gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred ); + gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred ); if( conn->hostname && !isdigit( conn->hostname[0] ) ) gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS, conn->hostname, strlen( conn->hostname ) ); @@ -343,7 +381,7 @@ } else { - conn->func( conn->data, 0, NULL, cond ); + conn->func( conn->data, st, NULL, cond ); gnutls_deinit( conn->session ); closesocket( conn->fd ); @@ -369,7 +407,7 @@ ssl_cache_add( conn ); conn->established = TRUE; - conn->func( conn->data, 0, conn, cond ); + conn->func( conn->data, st, conn, cond ); } }