Changeset fe7a554


Ignore:
Timestamp:
2006-09-22T18:39:31Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
d8e0484
Parents:
8d74291
Message:

Better detection of successful IQ authentication (using packet caching),
properly working SASL authentication (although only PLAIN so far).

Location:
protocols/jabber
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/io.c

    r8d74291 rfe7a554  
    219219        struct gaim_connection *gc = data;
    220220        struct jabber_data *jd = gc->proto_data;
    221         struct xt_node *c;
     221        struct xt_node *c, *reply;
    222222       
    223223        c = xt_find_node( node->children, "starttls" );
     
    231231        }
    232232       
     233        if( ( c = xt_find_node( node->children, "bind" ) ) )
     234        {
     235                reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) );
     236                xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" );
     237                reply = jabber_make_packet( "iq", "set", NULL, reply );
     238                jabber_cache_packet( gc, reply );
     239               
     240                if( !jabber_write_packet( gc, reply ) )
     241                        return XT_ABORT;
     242               
     243                jd->flags |= JFLAG_WAIT_BIND;
     244        }
     245       
     246        if( ( c = xt_find_node( node->children, "session" ) ) )
     247        {
     248                reply = xt_new_node( "session", NULL, NULL );
     249                xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" );
     250                reply = jabber_make_packet( "iq", "set", NULL, reply );
     251                jabber_cache_packet( gc, reply );
     252               
     253                if( !jabber_write_packet( gc, reply ) )
     254                        return XT_ABORT;
     255               
     256                jd->flags |= JFLAG_WAIT_SESSION;
     257        }
     258       
    233259        /* This flag is already set if we authenticated via SASL, so now
    234            we can resume the session in the new stream. */
    235         if( jd->flags & JFLAG_AUTHENTICATED )
     260           we can resume the session in the new stream, if we don't have
     261           to bind/initialize the session. */
     262        if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 )
    236263        {
    237264                if( !jabber_get_roster( gc ) )
  • protocols/jabber/iq.c

    r8d74291 rfe7a554  
    2828        struct gaim_connection *gc = data;
    2929        struct jabber_data *jd = gc->proto_data;
    30         struct xt_node *query, *reply = NULL;
     30        struct xt_node *query, *reply = NULL, *orig = NULL;
    3131        char *s, *type, *xmlns;
    3232        int st;
     
    3939       
    4040        xmlns = xt_find_attr( query, "xmlns" );
     41       
     42        if( ( s = xt_find_attr( node, "id" ) ) )
     43                orig = jabber_packet_from_cache( gc, s );
    4144       
    4245        if( strcmp( type, "result" ) == 0 && xmlns && strcmp( xmlns, "jabber:iq:auth" ) == 0 )
     
    8285               
    8386                reply = jabber_make_packet( "iq", "set", NULL, reply );
     87                jabber_cache_packet( gc, reply );
    8488                st = jabber_write_packet( gc, reply );
    85                 xt_free_node( reply );
    8689               
    8790                return st ? XT_HANDLED : XT_ABORT;
     
    106109                presence_announce( gc );
    107110        }
    108         else if( strcmp( type, "result" ) == 0 )
     111        else if( strcmp( type, "result" ) == 0 && orig )
    109112        {
    110                 /* If we weren't authenticated yet, let's assume we are now.
    111                    There are cleaner ways to do this, probably, but well.. */
    112                 if( !( jd->flags & JFLAG_AUTHENTICATED ) )
     113                struct xt_node *node;
     114               
     115                if( !( jd->flags & JFLAG_AUTHENTICATED ) &&
     116                    ( node = xt_find_node( orig->children, "query" ) ) &&
     117                    ( node = xt_find_node( node->children, "username" ) ) &&
     118                    node->text_len )
    113119                {
     120                        /* This happens when we just successfully authenticated
     121                           the old (non-SASL) way. */
    114122                        jd->flags |= JFLAG_AUTHENTICATED;
    115123                        if( !jabber_get_roster( gc ) )
    116124                                return XT_ABORT;
     125                }
     126                else if( ( node = xt_find_node( orig->children, "bind" ) ) ||
     127                         ( node = xt_find_node( orig->children, "session" ) ) )
     128                {
     129                        if( strcmp( node->name, "bind" ) == 0 )
     130                                jd->flags &= ~JFLAG_WAIT_BIND;
     131                        else if( strcmp( node->name, "session" ) == 0 )
     132                                jd->flags &= ~JFLAG_WAIT_SESSION;
     133                       
     134                        if( ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 )
     135                        {
     136                                if( !jabber_get_roster( gc ) )
     137                                        return XT_ABORT;
     138                        }
    117139                }
    118140        }
  • protocols/jabber/jabber.c

    r8d74291 rfe7a554  
    7676        jd->server ++;
    7777       
     78        jd->node_cache = xt_new_node( "cache", NULL, NULL );
     79       
    7880        if( set_getbool( &acc->set, "ssl" ) )
    7981        {
     
    103105                closesocket( jd->fd );
    104106       
     107        if( jd->tx_len )
     108                g_free( jd->txq );
     109       
     110        xt_free_node( jd->node_cache );
    105111        xt_free( jd->xt );
    106112       
  • protocols/jabber/jabber.h

    r8d74291 rfe7a554  
    3535        JFLAG_AUTHENTICATED = 2,        /* Set when we're successfully authenticatd. */
    3636        JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after SASL or TLS). */
     37        JFLAG_WAIT_SESSION = 8,         /* Set if we sent a <session> tag and need a reply before we continue. */
     38        JFLAG_WAIT_BIND = 16,           /* ... for <bind> tag. */
    3739} jabber_flags_t;
    3840
     
    5355char *set_eval_tls( set_t *set, char *value );
    5456struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children );
     57void jabber_cache_packet( struct gaim_connection *gc, struct xt_node *node );
     58struct xt_node *jabber_packet_from_cache( struct gaim_connection *gc, char *id );
    5559
    5660/* io.c */
     
    8286        char *username;         /* USERNAME@server */
    8387        char *server;           /* username@SERVER -=> server/domain, not hostname */
     88       
     89        struct xt_node *node_cache;
    8490};
    8591
  • protocols/jabber/jabber_util.c

    r8d74291 rfe7a554  
    5252struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children )
    5353{
    54         char *id = g_strdup_printf( "BeeX%04x", next_id++ );
    5554        struct xt_node *node;
    5655       
    5756        node = xt_new_node( name, NULL, children );
    5857       
    59         xt_add_attr( node, "id", id );
    6058        if( type )
    6159                xt_add_attr( node, "type", type );
     
    6361                xt_add_attr( node, "to", to );
    6462       
     63        return node;
     64}
     65
     66/* Cache a node/packet for later use. Mainly useful for IQ packets if you need
     67   them when you receive the response. Use this BEFORE sending the packet so
     68   it'll get an id= tag, and do NOT free() the packet after writing it! */
     69void jabber_cache_packet( struct gaim_connection *gc, struct xt_node *node )
     70{
     71        struct jabber_data *jd = gc->proto_data;
     72        char *id = g_strdup_printf( "BeeX%04x", next_id++ );
     73       
     74        /* FIXME: Maybe start using g_error() here if nodes still have a parent, for example? */
     75       
     76        xt_add_attr( node, "id", id );
     77        xt_add_child( jd->node_cache, node );
    6578        g_free( id );
     79}
     80
     81/* Emptying this cache is a BIG TODO! */
     82struct xt_node *jabber_packet_from_cache( struct gaim_connection *gc, char *id )
     83{
     84        struct jabber_data *jd = gc->proto_data;
     85        struct xt_node *node;
     86        char *s;
     87       
     88        for( node = jd->node_cache->children; node; node = node->next )
     89                if( ( s = xt_find_attr( node, "id" ) ) && strcmp( id, s ) == 0 )
     90                        break;
    6691       
    6792        return node;
  • protocols/jabber/sasl.c

    r8d74291 rfe7a554  
    7171        xt_add_attr( reply, "xmlns", SASL_NS );
    7272       
    73         if( sup_plain )
     73        if( sup_digest && 0 )
     74        {
     75                xt_add_attr( reply, "mechanism", "DIGEST-MD5" );
     76               
     77                /* The rest will be done later, when we receive a <challenge/>. */
     78        }
     79        else if( sup_plain )
    7480        {
    7581                int len;
     
    141147        struct jabber_data *jd = gc->proto_data;
    142148       
    143         return ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) != NULL;
     149        return ( (void*) ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) ) != NULL;
    144150}
Note: See TracChangeset for help on using the changeset viewer.