diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-09-24 13:57:45 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-09-24 13:57:45 +0200 |
commit | 42127dcd26be4f6746004237eac5333ffbb94f8e (patch) | |
tree | 61b1334e1d963cbb6383a9f5e5452605e6710ac4 /lib | |
parent | 172a73f1a4b37fa20d1d50496a3faccb8fe6c769 (diff) |
Added support for SSL- and TLS-connections. Checking of the "tls" user
setting has to be finished, plus an ssl_starttls() function for the other
SSL libraries (this code will only compile with GnuTLS for now).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ssl_client.h | 4 | ||||
-rw-r--r-- | lib/ssl_gnutls.c | 45 |
2 files changed, 34 insertions, 15 deletions
diff --git a/lib/ssl_client.h b/lib/ssl_client.h index 964caee4..dcbf9a01 100644 --- a/lib/ssl_client.h +++ b/lib/ssl_client.h @@ -51,6 +51,10 @@ typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition); blocking I/O! (Except for the DNS lookups, for now...) */ G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ); +/* Start an SSL session on an existing fd. Useful for STARTTLS functionality, + for example in Jabber. */ +G_MODULE_EXPORT void *ssl_starttls( int fd, ssl_input_function func, gpointer data ); + /* Obviously you need special read/write functions to read data. */ G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len ); G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); diff --git a/lib/ssl_gnutls.c b/lib/ssl_gnutls.c index 3ebe1756..fc848bb1 100644 --- a/lib/ssl_gnutls.c +++ b/lib/ssl_gnutls.c @@ -62,22 +62,28 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data if( conn->fd < 0 ) { g_free( conn ); - return( NULL ); + return NULL; } - if( !initialized ) - { - gnutls_global_init(); - initialized = TRUE; - atexit( gnutls_global_deinit ); - } + return conn; +} + +/* FIXME: It can happen that the handshake fails even before ssl_connected() + returns already. This function will then return an invalid pointer because + these failures can't be detected properly yet. Maybe ssl_connected() + shouldn't be called directly, but via a short timeout? */ +void *ssl_starttls( int fd, ssl_input_function func, gpointer data ) +{ + struct scd *conn = g_new0( struct scd, 1 ); - gnutls_certificate_allocate_credentials( &conn->xcred ); - gnutls_init( &conn->session, GNUTLS_CLIENT ); - gnutls_set_default_priority( conn->session ); - gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred ); + conn->fd = fd; + conn->func = func; + conn->data = data; + conn->inpa = -1; + + ssl_connected( conn, fd, GAIM_INPUT_WRITE ); - return( conn ); + return conn; } static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ); @@ -90,14 +96,23 @@ static gboolean ssl_connected( gpointer data, gint source, b_input_condition con { conn->func( conn->data, NULL, cond ); - gnutls_deinit( conn->session ); - gnutls_certificate_free_credentials( conn->xcred ); - g_free( conn ); return FALSE; } + if( !initialized ) + { + gnutls_global_init(); + initialized = TRUE; + atexit( gnutls_global_deinit ); + } + + gnutls_certificate_allocate_credentials( &conn->xcred ); + gnutls_init( &conn->session, GNUTLS_CLIENT ); + gnutls_set_default_priority( conn->session ); + gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred ); + sock_make_nonblocking( conn->fd ); gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd ); |