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.

File:
1 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 )
Note: See TracChangeset for help on using the changeset viewer.