Changeset 42127dc


Ignore:
Timestamp:
2006-09-24T11:57:45Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
e101506
Parents:
172a73f1
Message:

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).

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • lib/ssl_client.h

    r172a73f1 r42127dc  
    5252G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );
    5353
     54/* Start an SSL session on an existing fd. Useful for STARTTLS functionality,
     55   for example in Jabber. */
     56G_MODULE_EXPORT void *ssl_starttls( int fd, ssl_input_function func, gpointer data );
     57
    5458/* Obviously you need special read/write functions to read data. */
    5559G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
  • lib/ssl_gnutls.c

    r172a73f1 r42127dc  
    6363        {
    6464                g_free( conn );
    65                 return( NULL );
     65                return NULL;
     66        }
     67       
     68        return conn;
     69}
     70
     71/* FIXME: It can happen that the handshake fails even before ssl_connected()
     72   returns already. This function will then return an invalid pointer because
     73   these failures can't be detected properly yet. Maybe ssl_connected()
     74   shouldn't be called directly, but via a short timeout? */
     75void *ssl_starttls( int fd, ssl_input_function func, gpointer data )
     76{
     77        struct scd *conn = g_new0( struct scd, 1 );
     78       
     79        conn->fd = fd;
     80        conn->func = func;
     81        conn->data = data;
     82        conn->inpa = -1;
     83       
     84        ssl_connected( conn, fd, GAIM_INPUT_WRITE );
     85       
     86        return conn;
     87}
     88
     89static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
     90
     91static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
     92{
     93        struct scd *conn = data;
     94       
     95        if( source == -1 )
     96        {
     97                conn->func( conn->data, NULL, cond );
     98               
     99                g_free( conn );
     100               
     101                return FALSE;
    66102        }
    67103       
     
    77113        gnutls_set_default_priority( conn->session );
    78114        gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred );
    79        
    80         return( conn );
    81 }
    82 
    83 static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
    84 
    85 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
    86 {
    87         struct scd *conn = data;
    88        
    89         if( source == -1 )
    90         {
    91                 conn->func( conn->data, NULL, cond );
    92                
    93                 gnutls_deinit( conn->session );
    94                 gnutls_certificate_free_credentials( conn->xcred );
    95                
    96                 g_free( conn );
    97                
    98                 return FALSE;
    99         }
    100115       
    101116        sock_make_nonblocking( conn->fd );
  • protocols/jabber/io.c

    r172a73f1 r42127dc  
    2323
    2424#include "jabber.h"
     25#include "ssl_client.h"
    2526
    2627static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond );
     
    7677                return FALSE;
    7778       
    78         st = write( jd->fd, jd->txq, jd->tx_len );
     79        if( jd->ssl )
     80                st = ssl_write( jd->ssl, jd->txq, jd->tx_len );
     81        else
     82                st = write( jd->fd, jd->txq, jd->tx_len );
     83       
     84//      if( st > 0 ) write( 1, jd->txq, st );
    7985       
    8086        if( st == jd->tx_len )
     
    126132                return FALSE;
    127133       
    128         st = read( fd, buf, sizeof( buf ) );
     134        if( jd->ssl )
     135                st = ssl_read( jd->ssl, buf, sizeof( buf ) );
     136        else
     137                st = read( jd->fd, buf, sizeof( buf ) );
     138       
     139//      if( st > 0 ) write( 1, buf, st );
    129140       
    130141        if( st > 0 )
     
    210221}
    211222
     223gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond )
     224{
     225        struct gaim_connection *gc = data;
     226       
     227        if( source == NULL )
     228        {
     229                hide_login_progress( gc, "Could not connect to server" );
     230                signoff( gc );
     231                return FALSE;
     232        }
     233       
     234        set_login_progress( gc, 1, "Connected to server, logging in" );
     235       
     236        return jabber_start_stream( gc );
     237}
     238
    212239static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data )
    213240{
     
    222249       
    223250        c = xt_find_node( node->children, "starttls" );
    224         if( c )
    225         {
    226                 /*
    227                 jd->flags |= JFLAG_SUPPORTS_TLS;
    228                 if( xt_find_node( c->children, "required" ) )
    229                         jd->flags |= JFLAG_REQUIRES_TLS;
    230                 */
    231         }
     251        if( c && !jd->ssl )
     252        {
     253                /* If the server advertises the STARTTLS feature and if we're
     254                   not in a secure connection already: */
     255               
     256                int try;
     257               
     258                try = g_strcasecmp( set_getstr( &gc->acc->set, "tls" ), "try" ) == 0;
     259                c = xt_find_node( c->children, "required" );
     260               
     261                /* Only run this if the tls setting is set to true or try: */
     262                if( ( try | set_getbool( &gc->acc->set, "tls" ) ) )
     263                {
     264                        reply = xt_new_node( "starttls", NULL, NULL );
     265                        xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-tls" );
     266                        if( !jabber_write_packet( gc, reply ) )
     267                        {
     268                                xt_free_node( reply );
     269                                return XT_ABORT;
     270                        }
     271                        xt_free_node( reply );
     272                       
     273                        return XT_HANDLED;
     274                }
     275        }
     276        else
     277        {
     278                /* TODO: Abort if TLS is required by the user. */
     279        }
     280       
     281        /* This one used to be in jabber_handlers[], but it has to be done
     282           from here to make sure the TLS session will be initialized
     283           properly before we attempt SASL authentication. */
     284        if( ( c = xt_find_node( node->children, "mechanisms" ) ) )
     285                if( sasl_pkt_mechanisms( c, data ) == XT_ABORT )
     286                        return XT_ABORT;
    232287       
    233288        if( ( c = xt_find_node( node->children, "bind" ) ) )
     
    265320                        return XT_ABORT;
    266321        }
     322       
     323        return XT_HANDLED;
     324}
     325
     326static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data )
     327{
     328        struct gaim_connection *gc = data;
     329        struct jabber_data *jd = gc->proto_data;
     330        char *xmlns;
     331       
     332        xmlns = xt_find_attr( node, "xmlns" );
     333       
     334        /* Just ignore it when it doesn't seem to be TLS-related (is that at
     335           all possible??). */
     336        if( !xmlns || strcmp( xmlns, "urn:ietf:params:xml:ns:xmpp-tls" ) != 0 )
     337                return XT_HANDLED;
     338       
     339        /* We don't want event handlers to touch our TLS session while it's
     340           still initializing! */
     341        b_event_remove( jd->r_inpa );
     342        if( jd->tx_len > 0 )
     343        {
     344                /* Actually the write queue should be empty here, but just
     345                   to be sure... */
     346                b_event_remove( jd->w_inpa );
     347                g_free( jd->txq );
     348                jd->txq = NULL;
     349                jd->tx_len = 0;
     350        }
     351        jd->w_inpa = jd->r_inpa = 0;
     352       
     353        set_login_progress( gc, 1, "Converting stream to TLS" );
     354       
     355        jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, gc );
    267356       
    268357        return XT_HANDLED;
     
    283372        { "iq",                 "stream:stream",        jabber_pkt_iq },
    284373        { "stream:features",    "stream:stream",        jabber_pkt_features },
    285         { "mechanisms",         "stream:features",      sasl_pkt_mechanisms },
     374        { "proceed",            "stream:stream",        jabber_pkt_proceed_tls },
    286375        { "challenge",          "stream:stream",        sasl_pkt_challenge },
    287376        { "success",            "stream:stream",        sasl_pkt_result },
  • protocols/jabber/jabber.c

    r172a73f1 r42127dc  
    8080        if( set_getbool( &acc->set, "ssl" ) )
    8181        {
    82                 signoff( gc );
    83                 /* TODO! */
     82                jd->ssl = ssl_connect( jd->server, set_getint( &acc->set, "port" ), jabber_connected_ssl, gc );
     83                jd->fd = ssl_getfd( jd->ssl );
    8484        }
    8585        else
  • protocols/jabber/jabber.h

    r172a73f1 r42127dc  
    9595int jabber_write( struct gaim_connection *gc, char *buf, int len );
    9696gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond );
     97gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond );
    9798gboolean jabber_start_stream( struct gaim_connection *gc );
    9899void jabber_end_stream( struct gaim_connection *gc );
Note: See TracChangeset for help on using the changeset viewer.