Changeset f920d9e for lib/ssl_openssl.c


Ignore:
Timestamp:
2006-10-19T07:51:35Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
dfa41a4
Parents:
1991be6
Message:

Added starttls code to ssl_openssl.c so GnuTLS isn't the only supported
SSL module in this branch anymore.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/ssl_openssl.c

    r1991be6 rf920d9e  
    5353
    5454static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
     55static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
     56static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
    5557
    5658
     
    5860{
    5961        struct scd *conn = g_new0( struct scd, 1 );
    60         SSL_METHOD *meth;
    6162       
    6263        conn->fd = proxy_connect( host, port, ssl_connected, conn );
    6364        conn->func = func;
    6465        conn->data = data;
     66        conn->inpa = -1;
    6567       
    6668        if( conn->fd < 0 )
    6769        {
    6870                g_free( conn );
    69                 return( NULL );
    70         }
     71                return NULL;
     72        }
     73       
     74        return conn;
     75}
     76
     77void *ssl_starttls( int fd, ssl_input_function func, gpointer data )
     78{
     79        struct scd *conn = g_new0( struct scd, 1 );
     80       
     81        conn->fd = fd;
     82        conn->func = func;
     83        conn->data = data;
     84        conn->inpa = -1;
     85       
     86        /* This function should be called via a (short) timeout instead of
     87           directly from here, because these SSL calls are *supposed* to be
     88           *completely* asynchronous and not ready yet when this function
     89           (or *_connect, for examle) returns. Also, errors are reported via
     90           the callback function, not via this function's return value.
     91           
     92           In short, doing things like this makes the rest of the code a lot
     93           simpler. */
     94       
     95        b_timeout_add( 1, ssl_starttls_real, conn );
     96       
     97        return conn;
     98}
     99
     100static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
     101{
     102        struct scd *conn = data;
     103       
     104        return ssl_connected( conn, conn->fd, GAIM_INPUT_WRITE );
     105}
     106
     107static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
     108{
     109        struct scd *conn = data;
     110        SSL_METHOD *meth;
     111       
     112        if( source == -1 )
     113                goto ssl_connected_failure;
    71114       
    72115        if( !initialized )
     
    79122        conn->ssl_ctx = SSL_CTX_new( meth );
    80123        if( conn->ssl_ctx == NULL )
    81         {
    82                 conn->fd = -1;
    83                 return( NULL );
    84         }
     124                goto ssl_connected_failure;
    85125       
    86126        conn->ssl = SSL_new( conn->ssl_ctx );
    87127        if( conn->ssl == NULL )
    88         {
    89                 conn->fd = -1;
    90                 return( NULL );
    91         }
    92        
    93         return( conn );
    94 }
    95 
    96 static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
    97 
    98 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
    99 {
    100         struct scd *conn = data;
    101        
    102         if( source == -1 )
    103                 return ssl_handshake( data, -1, cond );
     128                goto ssl_connected_failure;
    104129       
    105130        /* We can do at least the handshake with non-blocking I/O */
     
    108133       
    109134        return ssl_handshake( data, source, cond );
     135
     136ssl_connected_failure:
     137        conn->func( conn->data, NULL, cond );
     138       
     139        if( conn->ssl )
     140        {
     141                SSL_shutdown( conn->ssl );
     142                SSL_free( conn->ssl );
     143        }
     144        if( conn->ssl_ctx )
     145        {
     146                SSL_CTX_free( conn->ssl_ctx );
     147        }
     148        if( source >= 0 ) closesocket( source );
     149        g_free( conn );
     150       
     151        return FALSE;
     152
    110153}       
    111154
     
    119162                conn->lasterr = SSL_get_error( conn->ssl, st );
    120163                if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE )
    121                         goto ssl_connected_failure;
     164                {
     165                        conn->func( conn->data, NULL, cond );
     166                       
     167                        SSL_shutdown( conn->ssl );
     168                        SSL_free( conn->ssl );
     169                        SSL_CTX_free( conn->ssl_ctx );
     170                       
     171                        if( source >= 0 ) closesocket( source );
     172                        g_free( conn );
     173                       
     174                        return FALSE;
     175                }
    122176               
    123177                conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data );
     
    129183        conn->func( conn->data, conn, cond );
    130184        return FALSE;
    131        
    132 ssl_connected_failure:
    133         conn->func( conn->data, NULL, cond );
    134        
    135         if( conn->ssl )
    136         {
    137                 SSL_shutdown( conn->ssl );
    138                 SSL_free( conn->ssl );
    139         }
    140         if( conn->ssl_ctx )
    141         {
    142                 SSL_CTX_free( conn->ssl_ctx );
    143         }
    144         if( source >= 0 ) closesocket( source );
    145         g_free( conn );
    146        
    147         return FALSE;
    148185}
    149186
Note: See TracChangeset for help on using the changeset viewer.