Changeset 0fd8559 for lib


Ignore:
Timestamp:
2007-02-18T17:48:04Z (17 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
0f4c1bb5
Parents:
8de63c3 (diff), c7d0f41 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging new Jabber module. See the massive changelog for all the cool
improvements. :-)

Location:
lib
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • lib/misc.c

    r8de63c3 r0fd8559  
    3939#include <glib.h>
    4040#include <time.h>
     41
     42#ifdef HAVE_RESOLV_A
     43#include <arpa/nameser.h>
     44#include <resolv.h>
     45#endif
    4146
    4247void strip_linefeed(gchar *text)
     
    488493        return 0;
    489494}
     495
     496struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain )
     497{       
     498        struct ns_srv_reply *reply = NULL;
     499#ifdef HAVE_RESOLV_A
     500        char name[1024];
     501        unsigned char querybuf[1024];
     502        const unsigned char *buf;
     503        ns_msg nsh;
     504        ns_rr rr;
     505        int i, len, size;
     506       
     507        g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
     508       
     509        if( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( querybuf ) ) ) <= 0 )
     510                return NULL;
     511       
     512        if( ns_initparse( querybuf, size, &nsh ) != 0 )
     513                return NULL;
     514       
     515        if( ns_parserr( &nsh, ns_s_an, 0, &rr ) != 0 )
     516                return NULL;
     517       
     518        size = ns_rr_rdlen( rr );
     519        buf = ns_rr_rdata( rr );
     520       
     521        len = 0;
     522        for( i = 6; i < size && buf[i]; i += buf[i] + 1 )
     523                len += buf[i] + 1;
     524       
     525        if( i > size )
     526                return NULL;
     527       
     528        reply = g_malloc( sizeof( struct ns_srv_reply ) + len );
     529        memcpy( reply->name, buf + 7, len );
     530       
     531        for( i = buf[6]; i < len && buf[7+i]; i += buf[7+i] + 1 )
     532                reply->name[i] = '.';
     533       
     534        if( i > len )
     535        {
     536                g_free( reply );
     537                return NULL;
     538        }
     539       
     540        reply->prio = ( buf[0] << 8 ) | buf[1];
     541        reply->weight = ( buf[2] << 8 ) | buf[3];
     542        reply->port = ( buf[4] << 8 ) | buf[5];
     543#endif
     544       
     545        return reply;
     546}
  • lib/misc.h

    r8de63c3 r0fd8559  
    3030#include <time.h>
    3131
     32struct ns_srv_reply
     33{
     34        int prio;
     35        int weight;
     36        int port;
     37        char name[];
     38};
     39
    3240G_MODULE_EXPORT void strip_linefeed( gchar *text );
    3341G_MODULE_EXPORT char *add_cr( char *text );
     
    5462G_MODULE_EXPORT int bool2int( char *value );
    5563
     64G_MODULE_EXPORT struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain );
     65
    5666#endif
  • lib/ssl_client.h

    r8de63c3 r0fd8559  
    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

    r8de63c3 r0fd8559  
    4949
    5050static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
     51static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
     52static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
    5153
    5254
     
    6365        {
    6466                g_free( conn );
    65                 return( NULL );
     67                return NULL;
     68        }
     69       
     70        return conn;
     71}
     72
     73void *ssl_starttls( int fd, ssl_input_function func, gpointer data )
     74{
     75        struct scd *conn = g_new0( struct scd, 1 );
     76       
     77        conn->fd = fd;
     78        conn->func = func;
     79        conn->data = data;
     80        conn->inpa = -1;
     81       
     82        /* This function should be called via a (short) timeout instead of
     83           directly from here, because these SSL calls are *supposed* to be
     84           *completely* asynchronous and not ready yet when this function
     85           (or *_connect, for examle) returns. Also, errors are reported via
     86           the callback function, not via this function's return value.
     87           
     88           In short, doing things like this makes the rest of the code a lot
     89           simpler. */
     90       
     91        b_timeout_add( 1, ssl_starttls_real, conn );
     92       
     93        return conn;
     94}
     95
     96static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
     97{
     98        struct scd *conn = data;
     99       
     100        return ssl_connected( conn, conn->fd, GAIM_INPUT_WRITE );
     101}
     102
     103static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
     104{
     105        struct scd *conn = data;
     106       
     107        if( source == -1 )
     108        {
     109                conn->func( conn->data, NULL, cond );
     110                g_free( conn );
     111                return FALSE;
    66112        }
    67113       
     
    77123        gnutls_set_default_priority( conn->session );
    78124        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         }
    100125       
    101126        sock_make_nonblocking( conn->fd );
  • lib/ssl_openssl.c

    r8de63c3 r0fd8559  
    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.