Changeset 8d74291 for protocols/jabber


Ignore:
Timestamp:
2006-09-22T16:56:58Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
fe7a554
Parents:
5997488
Message:

Fixed return value on incomplete write()s in write handler, protection
against write()ing to sockets that are closed already, hopefully sane
detection for SASL support, and only sending type=unavailable presence
tag to logged in sessions.

Location:
protocols/jabber
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/io.c

    r5997488 r8d74291  
    7373        int st;
    7474       
     75        if( jd->fd == -1 )
     76                return FALSE;
     77       
    7578        st = write( jd->fd, jd->txq, jd->tx_len );
    7679       
     
    8689        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
    8790        {
     91                /* Set fd to -1 to make sure we won't write to it anymore. */
     92                closesocket( jd->fd );  /* Shouldn't be necessary after errors? */
     93                jd->fd = -1;
     94               
    8895                hide_login_progress_error( gc, "Short write() to server" );
    8996                signoff( gc );
     
    99106                jd->txq = s;
    100107               
    101                 return FALSE;
     108                return TRUE;
    102109        }
    103110        else
     
    115122        char buf[512];
    116123        int st;
     124       
     125        if( jd->fd == -1 )
     126                return FALSE;
    117127       
    118128        st = read( fd, buf, sizeof( buf ) );
     
    139149                {
    140150                        jd->flags &= ~JFLAG_STREAM_RESTART;
    141                         xt_reset( jd->xt );
    142151                        jabber_start_stream( gc );
    143152                }
     
    156165                        {
    157166                                jd->flags |= JFLAG_STREAM_STARTED;
    158                                 return jabber_start_auth( gc );
     167                               
     168                                /* If there's no version attribute, assume
     169                                   this is an old server that can't do SASL
     170                                   authentication. */
     171                                if( !sasl_supported( gc ) )
     172                                        return jabber_start_iq_auth( gc );
    159173                        }
    160174                        else
     
    168182        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
    169183        {
     184                closesocket( jd->fd );
     185                jd->fd = -1;
     186               
    170187                hide_login_progress_error( gc, "Error while reading from server" );
    171188                signoff( gc );
     
    198215}
    199216
     217static xt_status jabber_pkt_features( struct xt_node *node, gpointer data )
     218{
     219        struct gaim_connection *gc = data;
     220        struct jabber_data *jd = gc->proto_data;
     221        struct xt_node *c;
     222       
     223        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        }
     232       
     233        /* 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 )
     236        {
     237                if( !jabber_get_roster( gc ) )
     238                        return XT_ABORT;
     239        }
     240       
     241        return XT_HANDLED;
     242}
     243
    200244static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data )
    201245{
     
    208252static const struct xt_handler_entry jabber_handlers[] = {
    209253        { "stream:stream",      "<root>",               jabber_end_of_stream },
    210         { "iq",                 "stream:stream",        jabber_pkt_iq },
    211254        { "message",            "stream:stream",        jabber_pkt_message },
    212255        { "presence",           "stream:stream",        jabber_pkt_presence },
     256        { "iq",                 "stream:stream",        jabber_pkt_iq },
     257        { "stream:features",    "stream:stream",        jabber_pkt_features },
    213258        { "mechanisms",         "stream:features",      sasl_pkt_mechanisms },
    214259        { "challenge",          "stream:stream",        sasl_pkt_challenge },
     
    231276        jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers;
    232277       
    233         jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc );
     278        if( jd->r_inpa <= 0 )
     279                jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc );
    234280       
    235281        greet = g_strdup_printf( "<?xml version='1.0' ?>"
     
    254300                char eos[] = "</stream:stream>";
    255301                struct xt_node *node;
    256                 int st;
    257                
    258                 node = jabber_make_packet( "presence", "unavailable", NULL, NULL );
    259                 st = jabber_write_packet( gc, node );
    260                 xt_free_node( node );
     302                int st = 1;
     303               
     304                if( gc->flags & OPT_LOGGED_IN )
     305                {
     306                        node = jabber_make_packet( "presence", "unavailable", NULL, NULL );
     307                        st = jabber_write_packet( gc, node );
     308                        xt_free_node( node );
     309                }
    261310               
    262311                if( st )
  • protocols/jabber/iq.c

    r5997488 r8d74291  
    130130}
    131131
    132 int jabber_start_auth( struct gaim_connection *gc )
     132int jabber_start_iq_auth( struct gaim_connection *gc )
    133133{
    134134        struct jabber_data *jd = gc->proto_data;
  • protocols/jabber/jabber.h

    r5997488 r8d74291  
    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_SUPPORTS_TLS = 8,         /* Set when there's <starttls/> in <stream:features>. */
    3837} jabber_flags_t;
    3938
    4039/* iq.c */
    4140xt_status jabber_pkt_iq( struct xt_node *node, gpointer data );
    42 int jabber_start_auth( struct gaim_connection *gc );
     41int jabber_start_iq_auth( struct gaim_connection *gc );
    4342int jabber_get_roster( struct gaim_connection *gc );
    4443
     
    6665xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data );
    6766xt_status sasl_pkt_result( struct xt_node *node, gpointer data );
     67gboolean sasl_supported( struct gaim_connection *gc );
    6868
    6969struct jabber_data
  • protocols/jabber/sasl.c

    r5997488 r8d74291  
    3434        char *s;
    3535        int sup_plain = 0, sup_digest = 0;
     36       
     37        if( !sasl_supported( gc ) )
     38        {
     39                /* Should abort this now, since we should already be doing
     40                   IQ authentication. Strange things happen when you try
     41                   to do both... */
     42                serv_got_crap( gc, "XMPP 1.0 non-compliant server seems to support SASL, please report this as a BitlBee bug!" );
     43                return XT_HANDLED;
     44        }
    3645       
    3746        s = xt_find_attr( node, "xmlns" );
     
    94103xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data )
    95104{
     105        return XT_HANDLED;
    96106}
    97107
     
    123133        return XT_HANDLED;
    124134}
     135
     136/* This one is needed to judge if we'll do authentication using IQ or SASL.
     137   It's done by checking if the <stream:stream> from the server has a
     138   version attribute. I don't know if this is the right way though... */
     139gboolean sasl_supported( struct gaim_connection *gc )
     140{
     141        struct jabber_data *jd = gc->proto_data;
     142       
     143        return ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) != NULL;
     144}
Note: See TracChangeset for help on using the changeset viewer.