From 21167d2d14c333d67445546bb69dd52dd295287d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 20 Sep 2006 21:42:27 +0200 Subject: It can send a valid (pre-XMPP) login packet. Lots of work to do, still... --- protocols/jabber/io.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 protocols/jabber/io.c (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c new file mode 100644 index 00000000..db869714 --- /dev/null +++ b/protocols/jabber/io.c @@ -0,0 +1,237 @@ +/***************************************************************************\ +* * +* BitlBee - An IRC to IM gateway * +* Jabber module - I/O stuff (plain, SSL), queues, etc * +* * +* Copyright 2006 Wilmer van der Gaast * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, write to the Free Software Foundation, Inc., * +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +\***************************************************************************/ + +#include "jabber.h" + +static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ); + +int jabber_write_packet( struct gaim_connection *gc, struct xt_node *node ) +{ + char *buf; + int st; + + buf = xt_to_string( node ); + st = jabber_write( gc, buf, strlen( buf ) ); + g_free( buf ); + + return st; +} + +int jabber_write( struct gaim_connection *gc, char *buf, int len ) +{ + struct jabber_data *jd = gc->proto_data; + + if( jd->tx_len == 0 ) + { + /* If the queue is empty, allocate a new buffer. */ + jd->tx_len = len; + jd->txq = g_memdup( buf, len ); + + /* Try if we can write it immediately so we don't have to do + it via the event handler. If not, add the handler. (In + most cases it probably won't be necessary.) */ + if( jabber_write_callback( gc, jd->fd, GAIM_INPUT_WRITE ) ) + jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, gc ); + } + else + { + /* Just add it to the buffer if it's already filled. The + event handler is already set. */ + jd->txq = g_renew( char, jd->txq, jd->tx_len + len ); + memcpy( jd->txq + jd->tx_len, buf, len ); + jd->tx_len += len; + } + + /* FIXME: write_callback could've generated a real error! */ + return 1; +} + +static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ) +{ + struct gaim_connection *gc = data; + struct jabber_data *jd = gc->proto_data; + int st; + + st = write( jd->fd, jd->txq, jd->tx_len ); + + if( st == jd->tx_len ) + { + /* We wrote everything, clear the buffer. */ + g_free( jd->txq ); + jd->txq = NULL; + jd->tx_len = 0; + + return FALSE; + } + else if( st == 0 || ( st < 0 && !sockerr_again() ) ) + { + hide_login_progress_error( gc, "Short write() to server" ); + signoff( gc ); + return FALSE; + } + else if( st > 0 ) + { + char *s; + + s = g_memdup( jd->txq + st, jd->tx_len - st ); + jd->tx_len -= st; + g_free( jd->txq ); + jd->txq = s; + + return FALSE; + } + else + { + /* Just in case we had EINPROGRESS/EAGAIN: */ + + return TRUE; + } +} + +static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition cond ) +{ + struct gaim_connection *gc = data; + struct jabber_data *jd = gc->proto_data; + char buf[512]; + int st; + + st = read( fd, buf, sizeof( buf ) ); + + if( st > 0 ) + { + /* Parse. */ + if( !xt_feed( jd->xt, buf, st ) ) + { + hide_login_progress_error( gc, "XML stream error" ); + signoff( gc ); + return FALSE; + } + + /* Execute all handlers. */ + if( !xt_handle( jd->xt, NULL ) ) + { + /* Don't do anything, the handlers should have + aborted the connection already... Or not? FIXME */ + return FALSE; + } + + /* Garbage collection. */ + xt_cleanup( jd->xt, NULL ); + + /* This is a bit hackish, unfortunately. Although xmltree + has nifty event handler stuff, it only calls handlers + when nodes are complete. Since the server should only + send an opening tag, we have to check + this by hand. :-( */ + if( !( jd->flags & JFLAG_STREAM_STARTED ) && jd->xt && jd->xt->root ) + { + if( g_strcasecmp( jd->xt->root->name, "stream:stream" ) == 0 ) + { + jd->flags |= JFLAG_STREAM_STARTED; + return jabber_start_auth( gc ); + } + else + { + hide_login_progress_error( gc, "XML stream error" ); + signoff( gc ); + return FALSE; + } + } + } + else if( st == 0 || ( st < 0 && !sockerr_again() ) ) + { + hide_login_progress_error( gc, "Error while reading from server" ); + signoff( gc ); + return FALSE; + } + + /* EAGAIN/etc or a successful read. */ + return TRUE; +} + +static gboolean jabber_start_stream( struct gaim_connection *gc ); + +gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond ) +{ + struct gaim_connection *gc = data; + + if( source == -1 ) + { + hide_login_progress( gc, "Could not connect to server" ); + signoff( gc ); + return FALSE; + } + + set_login_progress( gc, 1, "Connected to server, logging in" ); + + return jabber_start_stream( gc ); +} + +static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) +{ + return XT_ABORT; +} + +static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) +{ + printf( "Received unknown packet:\n" ); + xt_print( node ); + + return XT_HANDLED; +} + +static const struct xt_handler_entry jabber_handlers[] = { + { "stream:stream", "", jabber_end_of_stream }, + { "iq", "stream:stream", jabber_pkt_iq }, + { "message", "stream:stream", jabber_pkt_message }, + { "presence", "stream:stream", jabber_pkt_presence }, + { NULL, "stream:stream", jabber_pkt_misc }, + { NULL, NULL, NULL } +}; + +static gboolean jabber_start_stream( struct gaim_connection *gc ) +{ + struct jabber_data *jd = gc->proto_data; + int st; + char *greet; + + /* We'll start our stream now, so prepare everything to receive one + from the server too. */ + xt_free( jd->xt ); /* In case we're RE-starting. */ + jd->xt = xt_new( gc ); + jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; + + jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc ); + + greet = g_strdup_printf( "" + "", jd->server ); + /* Add this when TLS and SASL are supported? */ + // version=\"1.0\">" + + st = jabber_write( gc, greet, strlen( greet ) ); + + g_free( greet ); + + return st; +} -- cgit v1.2.3 From 4a0614e65b45364d4d1f631aeaae047a92c752c5 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 21 Sep 2006 11:37:03 +0200 Subject: Added simple parsing of incoming tags, a nice at the end of sessions, support for sending messages, and restored the old (and leaking) xt_print(), which I'll only use for debugging. --- protocols/jabber/io.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index db869714..8c0b239e 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -169,8 +169,6 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition return TRUE; } -static gboolean jabber_start_stream( struct gaim_connection *gc ); - gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond ) { struct gaim_connection *gc = data; @@ -209,7 +207,7 @@ static const struct xt_handler_entry jabber_handlers[] = { { NULL, NULL, NULL } }; -static gboolean jabber_start_stream( struct gaim_connection *gc ) +gboolean jabber_start_stream( struct gaim_connection *gc ) { struct jabber_data *jd = gc->proto_data; int st; @@ -235,3 +233,16 @@ static gboolean jabber_start_stream( struct gaim_connection *gc ) return st; } + +gboolean jabber_end_stream( struct gaim_connection *gc ) +{ + struct jabber_data *jd = gc->proto_data; + char eos[] = ""; + + /* Let's only do this if the queue is currently empty, otherwise it'd + take too long anyway. */ + if( jd->tx_len > 0 ) + return TRUE; + else + return jabber_write( gc, eos, strlen( eos ) ); +} -- cgit v1.2.3 From 5bcf70a662244dc77af09d2fffbe913ec6f19393 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 21 Sep 2006 20:44:34 +0200 Subject: Now also sending tag on disconnect, as recommended by rfc3921/5.1.5. --- protocols/jabber/io.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 8c0b239e..b11ef17d 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -234,15 +234,23 @@ gboolean jabber_start_stream( struct gaim_connection *gc ) return st; } -gboolean jabber_end_stream( struct gaim_connection *gc ) +void jabber_end_stream( struct gaim_connection *gc ) { struct jabber_data *jd = gc->proto_data; - char eos[] = ""; /* Let's only do this if the queue is currently empty, otherwise it'd take too long anyway. */ - if( jd->tx_len > 0 ) - return TRUE; - else - return jabber_write( gc, eos, strlen( eos ) ); + if( jd->tx_len == 0 ) + { + char eos[] = ""; + struct xt_node *node; + int st; + + node = jabber_make_packet( "presence", "unavailable", NULL, NULL ); + st = jabber_write_packet( gc, node ); + xt_free_node( node ); + + if( st ) + jabber_write( gc, eos, strlen( eos ) ); + } } -- cgit v1.2.3 From 59974884ba72d6e8fa008d07ee93bd228d30a99c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 22 Sep 2006 14:04:35 +0200 Subject: Basic SASL (PLAIN only ATM) authentication code. Doesn't log in completely yet. --- protocols/jabber/io.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index b11ef17d..c7c1d8d9 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -135,6 +135,13 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition return FALSE; } + if( jd->flags & JFLAG_STREAM_RESTART ) + { + jd->flags &= ~JFLAG_STREAM_RESTART; + xt_reset( jd->xt ); + jabber_start_stream( gc ); + } + /* Garbage collection. */ xt_cleanup( jd->xt, NULL ); @@ -203,6 +210,10 @@ static const struct xt_handler_entry jabber_handlers[] = { { "iq", "stream:stream", jabber_pkt_iq }, { "message", "stream:stream", jabber_pkt_message }, { "presence", "stream:stream", jabber_pkt_presence }, + { "mechanisms", "stream:features", sasl_pkt_mechanisms }, + { "challenge", "stream:stream", sasl_pkt_challenge }, + { "success", "stream:stream", sasl_pkt_result }, + { "failure", "stream:stream", sasl_pkt_result }, { NULL, "stream:stream", jabber_pkt_misc }, { NULL, NULL, NULL } }; @@ -223,9 +234,7 @@ gboolean jabber_start_stream( struct gaim_connection *gc ) greet = g_strdup_printf( "" "", jd->server ); - /* Add this when TLS and SASL are supported? */ - // version=\"1.0\">" + "xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">", jd->server ); st = jabber_write( gc, greet, strlen( greet ) ); -- cgit v1.2.3 From 8d7429102adf8dce6844f2f3da2723d1f87c6442 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 22 Sep 2006 18:56:58 +0200 Subject: 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. --- protocols/jabber/io.c | 67 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index c7c1d8d9..8f2ce0f1 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -72,6 +72,9 @@ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition struct jabber_data *jd = gc->proto_data; int st; + if( jd->fd == -1 ) + return FALSE; + st = write( jd->fd, jd->txq, jd->tx_len ); if( st == jd->tx_len ) @@ -85,6 +88,10 @@ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition } else if( st == 0 || ( st < 0 && !sockerr_again() ) ) { + /* Set fd to -1 to make sure we won't write to it anymore. */ + closesocket( jd->fd ); /* Shouldn't be necessary after errors? */ + jd->fd = -1; + hide_login_progress_error( gc, "Short write() to server" ); signoff( gc ); return FALSE; @@ -98,7 +105,7 @@ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition g_free( jd->txq ); jd->txq = s; - return FALSE; + return TRUE; } else { @@ -115,6 +122,9 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition char buf[512]; int st; + if( jd->fd == -1 ) + return FALSE; + st = read( fd, buf, sizeof( buf ) ); if( st > 0 ) @@ -138,7 +148,6 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( jd->flags & JFLAG_STREAM_RESTART ) { jd->flags &= ~JFLAG_STREAM_RESTART; - xt_reset( jd->xt ); jabber_start_stream( gc ); } @@ -155,7 +164,12 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( g_strcasecmp( jd->xt->root->name, "stream:stream" ) == 0 ) { jd->flags |= JFLAG_STREAM_STARTED; - return jabber_start_auth( gc ); + + /* If there's no version attribute, assume + this is an old server that can't do SASL + authentication. */ + if( !sasl_supported( gc ) ) + return jabber_start_iq_auth( gc ); } else { @@ -167,6 +181,9 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } else if( st == 0 || ( st < 0 && !sockerr_again() ) ) { + closesocket( jd->fd ); + jd->fd = -1; + hide_login_progress_error( gc, "Error while reading from server" ); signoff( gc ); return FALSE; @@ -197,6 +214,33 @@ static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) return XT_ABORT; } +static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) +{ + struct gaim_connection *gc = data; + struct jabber_data *jd = gc->proto_data; + struct xt_node *c; + + c = xt_find_node( node->children, "starttls" ); + if( c ) + { + /* + jd->flags |= JFLAG_SUPPORTS_TLS; + if( xt_find_node( c->children, "required" ) ) + jd->flags |= JFLAG_REQUIRES_TLS; + */ + } + + /* This flag is already set if we authenticated via SASL, so now + we can resume the session in the new stream. */ + if( jd->flags & JFLAG_AUTHENTICATED ) + { + if( !jabber_get_roster( gc ) ) + return XT_ABORT; + } + + return XT_HANDLED; +} + static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) { printf( "Received unknown packet:\n" ); @@ -207,9 +251,10 @@ static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) static const struct xt_handler_entry jabber_handlers[] = { { "stream:stream", "", jabber_end_of_stream }, - { "iq", "stream:stream", jabber_pkt_iq }, { "message", "stream:stream", jabber_pkt_message }, { "presence", "stream:stream", jabber_pkt_presence }, + { "iq", "stream:stream", jabber_pkt_iq }, + { "stream:features", "stream:stream", jabber_pkt_features }, { "mechanisms", "stream:features", sasl_pkt_mechanisms }, { "challenge", "stream:stream", sasl_pkt_challenge }, { "success", "stream:stream", sasl_pkt_result }, @@ -230,7 +275,8 @@ gboolean jabber_start_stream( struct gaim_connection *gc ) jd->xt = xt_new( gc ); jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; - jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc ); + if( jd->r_inpa <= 0 ) + jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc ); greet = g_strdup_printf( "" "flags & OPT_LOGGED_IN ) + { + node = jabber_make_packet( "presence", "unavailable", NULL, NULL ); + st = jabber_write_packet( gc, node ); + xt_free_node( node ); + } if( st ) jabber_write( gc, eos, strlen( eos ) ); -- cgit v1.2.3 From fe7a55434385fd858453dffdbb425a21f41e3859 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 22 Sep 2006 20:39:31 +0200 Subject: Better detection of successful IQ authentication (using packet caching), properly working SASL authentication (although only PLAIN so far). --- protocols/jabber/io.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 8f2ce0f1..333e3123 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -218,7 +218,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) { struct gaim_connection *gc = data; struct jabber_data *jd = gc->proto_data; - struct xt_node *c; + struct xt_node *c, *reply; c = xt_find_node( node->children, "starttls" ); if( c ) @@ -230,9 +230,36 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) */ } + if( ( c = xt_find_node( node->children, "bind" ) ) ) + { + reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); + xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" ); + reply = jabber_make_packet( "iq", "set", NULL, reply ); + jabber_cache_packet( gc, reply ); + + if( !jabber_write_packet( gc, reply ) ) + return XT_ABORT; + + jd->flags |= JFLAG_WAIT_BIND; + } + + if( ( c = xt_find_node( node->children, "session" ) ) ) + { + reply = xt_new_node( "session", NULL, NULL ); + xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" ); + reply = jabber_make_packet( "iq", "set", NULL, reply ); + jabber_cache_packet( gc, reply ); + + if( !jabber_write_packet( gc, reply ) ) + return XT_ABORT; + + jd->flags |= JFLAG_WAIT_SESSION; + } + /* This flag is already set if we authenticated via SASL, so now - we can resume the session in the new stream. */ - if( jd->flags & JFLAG_AUTHENTICATED ) + we can resume the session in the new stream, if we don't have + to bind/initialize the session. */ + if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) { if( !jabber_get_roster( gc ) ) return XT_ABORT; -- cgit v1.2.3 From 42127dcd26be4f6746004237eac5333ffbb94f8e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Sep 2006 13:57:45 +0200 Subject: Added support for SSL- and TLS-connections. Checking of the "tls" user setting has to be finished, plus an ssl_starttls() function for the other SSL libraries (this code will only compile with GnuTLS for now). --- protocols/jabber/io.c | 107 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 9 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 333e3123..f1f62a48 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -22,6 +22,7 @@ \***************************************************************************/ #include "jabber.h" +#include "ssl_client.h" static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ); @@ -75,7 +76,12 @@ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition if( jd->fd == -1 ) return FALSE; - st = write( jd->fd, jd->txq, jd->tx_len ); + if( jd->ssl ) + st = ssl_write( jd->ssl, jd->txq, jd->tx_len ); + else + st = write( jd->fd, jd->txq, jd->tx_len ); + +// if( st > 0 ) write( 1, jd->txq, st ); if( st == jd->tx_len ) { @@ -125,7 +131,12 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( jd->fd == -1 ) return FALSE; - st = read( fd, buf, sizeof( buf ) ); + if( jd->ssl ) + st = ssl_read( jd->ssl, buf, sizeof( buf ) ); + else + st = read( jd->fd, buf, sizeof( buf ) ); + +// if( st > 0 ) write( 1, buf, st ); if( st > 0 ) { @@ -209,6 +220,22 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c return jabber_start_stream( gc ); } +gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond ) +{ + struct gaim_connection *gc = data; + + if( source == NULL ) + { + hide_login_progress( gc, "Could not connect to server" ); + signoff( gc ); + return FALSE; + } + + set_login_progress( gc, 1, "Connected to server, logging in" ); + + return jabber_start_stream( gc ); +} + static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) { return XT_ABORT; @@ -221,15 +248,43 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) struct xt_node *c, *reply; c = xt_find_node( node->children, "starttls" ); - if( c ) + if( c && !jd->ssl ) { - /* - jd->flags |= JFLAG_SUPPORTS_TLS; - if( xt_find_node( c->children, "required" ) ) - jd->flags |= JFLAG_REQUIRES_TLS; - */ + /* If the server advertises the STARTTLS feature and if we're + not in a secure connection already: */ + + int try; + + try = g_strcasecmp( set_getstr( &gc->acc->set, "tls" ), "try" ) == 0; + c = xt_find_node( c->children, "required" ); + + /* Only run this if the tls setting is set to true or try: */ + if( ( try | set_getbool( &gc->acc->set, "tls" ) ) ) + { + reply = xt_new_node( "starttls", NULL, NULL ); + xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-tls" ); + if( !jabber_write_packet( gc, reply ) ) + { + xt_free_node( reply ); + return XT_ABORT; + } + xt_free_node( reply ); + + return XT_HANDLED; + } + } + else + { + /* TODO: Abort if TLS is required by the user. */ } + /* This one used to be in jabber_handlers[], but it has to be done + from here to make sure the TLS session will be initialized + properly before we attempt SASL authentication. */ + if( ( c = xt_find_node( node->children, "mechanisms" ) ) ) + if( sasl_pkt_mechanisms( c, data ) == XT_ABORT ) + return XT_ABORT; + if( ( c = xt_find_node( node->children, "bind" ) ) ) { reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); @@ -268,6 +323,40 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) return XT_HANDLED; } +static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) +{ + struct gaim_connection *gc = data; + struct jabber_data *jd = gc->proto_data; + char *xmlns; + + xmlns = xt_find_attr( node, "xmlns" ); + + /* Just ignore it when it doesn't seem to be TLS-related (is that at + all possible??). */ + if( !xmlns || strcmp( xmlns, "urn:ietf:params:xml:ns:xmpp-tls" ) != 0 ) + return XT_HANDLED; + + /* We don't want event handlers to touch our TLS session while it's + still initializing! */ + b_event_remove( jd->r_inpa ); + if( jd->tx_len > 0 ) + { + /* Actually the write queue should be empty here, but just + to be sure... */ + b_event_remove( jd->w_inpa ); + g_free( jd->txq ); + jd->txq = NULL; + jd->tx_len = 0; + } + jd->w_inpa = jd->r_inpa = 0; + + set_login_progress( gc, 1, "Converting stream to TLS" ); + + jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, gc ); + + return XT_HANDLED; +} + static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) { printf( "Received unknown packet:\n" ); @@ -282,7 +371,7 @@ static const struct xt_handler_entry jabber_handlers[] = { { "presence", "stream:stream", jabber_pkt_presence }, { "iq", "stream:stream", jabber_pkt_iq }, { "stream:features", "stream:stream", jabber_pkt_features }, - { "mechanisms", "stream:features", sasl_pkt_mechanisms }, + { "proceed", "stream:stream", jabber_pkt_proceed_tls }, { "challenge", "stream:stream", sasl_pkt_challenge }, { "success", "stream:stream", sasl_pkt_result }, { "failure", "stream:stream", sasl_pkt_result }, -- cgit v1.2.3 From e101506a3e660d3165a89aab0898293b367e2b5b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Sep 2006 19:22:08 +0200 Subject: Better handling of user tls setting. --- protocols/jabber/io.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index f1f62a48..3bc967e0 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -246,20 +246,27 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) struct gaim_connection *gc = data; struct jabber_data *jd = gc->proto_data; struct xt_node *c, *reply; + int trytls; + trytls = g_strcasecmp( set_getstr( &gc->acc->set, "tls" ), "try" ) == 0; c = xt_find_node( node->children, "starttls" ); if( c && !jd->ssl ) { /* If the server advertises the STARTTLS feature and if we're not in a secure connection already: */ - int try; - - try = g_strcasecmp( set_getstr( &gc->acc->set, "tls" ), "try" ) == 0; c = xt_find_node( c->children, "required" ); + if( c && ( !trytls && !set_getbool( &gc->acc->set, "tls" ) ) ) + { + hide_login_progress( gc, "Server requires TLS connections, but TLS is turned off for this account" ); + signoff( gc ); + + return XT_ABORT; + } + /* Only run this if the tls setting is set to true or try: */ - if( ( try | set_getbool( &gc->acc->set, "tls" ) ) ) + if( ( trytls || set_getbool( &gc->acc->set, "tls" ) ) ) { reply = xt_new_node( "starttls", NULL, NULL ); xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-tls" ); @@ -273,9 +280,20 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) return XT_HANDLED; } } - else + else if( !c && !jd->ssl ) { - /* TODO: Abort if TLS is required by the user. */ + /* If the server does not advertise the STARTTLS feature and + we're not in a secure connection already: (Servers have a + habit of not advertising anymore when already + using SSL/TLS. */ + + if( !trytls && set_getbool( &gc->acc->set, "tls" ) ) + { + hide_login_progress( gc, "TLS is turned on for this account, but is not supported by this server" ); + signoff( gc ); + + return XT_ABORT; + } } /* This one used to be in jabber_handlers[], but it has to be done -- cgit v1.2.3 From 6baca2a2910d0b6663b54ef302820d9ffbbf5eee Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 1 Oct 2006 11:31:41 +0200 Subject: Some initial hooks/stuff for privacy lists, and fixed a crash bug on connecting to Google Talk. --- protocols/jabber/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 3bc967e0..f62e059a 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -334,7 +334,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) to bind/initialize the session. */ if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) { - if( !jabber_get_roster( gc ) ) + if( !jabber_get_roster( gc ) || !jabber_get_privacy( gc ) ) return XT_ABORT; } -- cgit v1.2.3 From 0e2d97f6b3bcffd5637eafa9a687e42a7c134f57 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 1 Oct 2006 11:40:55 +0200 Subject: Can now log in to the jabber.com server (which pretends to support XMPP 1.0 but does NOT (seem to) support SASL authentication). --- protocols/jabber/io.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index f62e059a..3dbc6faa 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -300,8 +300,20 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) from here to make sure the TLS session will be initialized properly before we attempt SASL authentication. */ if( ( c = xt_find_node( node->children, "mechanisms" ) ) ) + { if( sasl_pkt_mechanisms( c, data ) == XT_ABORT ) return XT_ABORT; + } + else + { + /* If the server *SEEMS* to support SASL authentication but + doesn't support it after all, we should try to do + authentication the other way. jabber.com doesn't seem to + do SASL while it pretends to be XMPP 1.0 compliant! */ + if( sasl_supported( gc ) ) + if( !jabber_start_iq_auth( gc ) ) + return XT_ABORT; + } if( ( c = xt_find_node( node->children, "bind" ) ) ) { -- cgit v1.2.3 From 88591fd3b95ab21ca016204b49fb80d6d6cdd541 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 1 Oct 2006 18:15:46 +0200 Subject: Better fix for servers that report to comply with XMPP 1.0 but don't offer SASL authentication options. Previous fix tried to do IQ authentication even after successful SASL authentications. --- protocols/jabber/io.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 3dbc6faa..189320d9 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -304,15 +304,14 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( sasl_pkt_mechanisms( c, data ) == XT_ABORT ) return XT_ABORT; } - else + /* If the server *SEEMS* to support SASL authentication but doesn't + support it after all, we should try to do authentication the + other way. jabber.com doesn't seem to do SASL while it pretends + to be XMPP 1.0 compliant! */ + else if( !( jd->flags & JFLAG_AUTHENTICATED ) && sasl_supported( gc ) ) { - /* If the server *SEEMS* to support SASL authentication but - doesn't support it after all, we should try to do - authentication the other way. jabber.com doesn't seem to - do SASL while it pretends to be XMPP 1.0 compliant! */ - if( sasl_supported( gc ) ) - if( !jabber_start_iq_auth( gc ) ) - return XT_ABORT; + if( !jabber_start_iq_auth( gc ) ) + return XT_ABORT; } if( ( c = xt_find_node( node->children, "bind" ) ) ) -- cgit v1.2.3 From c1ed6527576ac4c6ee1241f662e7db8e59327fd8 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 2 Oct 2006 15:19:13 +0200 Subject: No more double free()/crashes when trying to set up an SSL connection to a non-SSL server, and better handling of TLS connection setup by initializing the TLS session from a callback function (which guarantees a valid return value from ssl_starttls() before any error callback could be called). --- protocols/jabber/io.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 189320d9..8834c906 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -223,9 +223,14 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond ) { struct gaim_connection *gc = data; + struct jabber_data *jd = gc->proto_data; if( source == NULL ) { + /* The SSL connection will be cleaned up by the SSL lib + already, set it to NULL here to prevent a double cleanup: */ + jd->ssl = NULL; + hide_login_progress( gc, "Could not connect to server" ); signoff( gc ); return FALSE; -- cgit v1.2.3 From 501b4e06244dbd333ee207ceade37592482e0fe7 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 2 Oct 2006 18:42:32 +0200 Subject: Added a useful error message for SASL negotiation failures and turned off the little hack in jabber_write() for now because it breaks error handling. --- protocols/jabber/io.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 8834c906..634e5b99 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -51,7 +51,10 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) /* Try if we can write it immediately so we don't have to do it via the event handler. If not, add the handler. (In most cases it probably won't be necessary.) */ + /* Disabling this trick for now because there's really not + a good way to catch errors yet. :-( if( jabber_write_callback( gc, jd->fd, GAIM_INPUT_WRITE ) ) + */ jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, gc ); } else @@ -63,7 +66,10 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) jd->tx_len += len; } - /* FIXME: write_callback could've generated a real error! */ + /* FIXME: write_callback could've generated a real error! Have to + find a way to find out if we have to return 0 here. Looking for + ourselves in the linked list of connections is a possibility, + but it'd be too time-consuming... */ return 1; } -- cgit v1.2.3 From cc2cb2da3f1c0e2ad65708f4110e74e945ea9b66 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 4 Oct 2006 20:14:41 +0200 Subject: Lack of TLS support is also detected now if the server doesn't support XMPP 1.0 (properly), and restored immediate writes by splitting up the jabber_write_callback() function. --- protocols/jabber/io.c | 61 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 634e5b99..88ebf5d9 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -25,6 +25,7 @@ #include "ssl_client.h" static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ); +static gboolean jabber_write_queue( struct gaim_connection *gc ); int jabber_write_packet( struct gaim_connection *gc, struct xt_node *node ) { @@ -41,6 +42,7 @@ int jabber_write_packet( struct gaim_connection *gc, struct xt_node *node ) int jabber_write( struct gaim_connection *gc, char *buf, int len ) { struct jabber_data *jd = gc->proto_data; + gboolean ret; if( jd->tx_len == 0 ) { @@ -51,10 +53,7 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) /* Try if we can write it immediately so we don't have to do it via the event handler. If not, add the handler. (In most cases it probably won't be necessary.) */ - /* Disabling this trick for now because there's really not - a good way to catch errors yet. :-( - if( jabber_write_callback( gc, jd->fd, GAIM_INPUT_WRITE ) ) - */ + if( ( ret = jabber_write_queue( gc ) ) && jd->tx_len > 0 ) jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, gc ); } else @@ -64,24 +63,39 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) jd->txq = g_renew( char, jd->txq, jd->tx_len + len ); memcpy( jd->txq + jd->tx_len, buf, len ); jd->tx_len += len; + + /* The return value for write() doesn't necessarily mean + that everything got sent, it mainly means that the + connection (officially) still exists and can still + be accessed without hitting SIGSEGV. IOW: */ + ret = TRUE; } - /* FIXME: write_callback could've generated a real error! Have to - find a way to find out if we have to return 0 here. Looking for - ourselves in the linked list of connections is a possibility, - but it'd be too time-consuming... */ - return 1; + return ret; } +/* Splitting up in two separate functions: One to use as a callback and one + to use in the function above to escape from having to wait for the event + handler to call us, if possible. + + Two different functions are necessary because of the return values: The + callback should only return TRUE if the write was successful AND if the + buffer is not empty yet (ie. if the handler has to be called again when + the socket is ready for more data). */ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ) { - struct gaim_connection *gc = data; + struct jabber_data *jd = ((struct gaim_connection *)data)->proto_data; + + return jd->fd != -1 && + jabber_write_queue( data ) && + jd->tx_len > 0; +} + +static gboolean jabber_write_queue( struct gaim_connection *gc ) +{ struct jabber_data *jd = gc->proto_data; int st; - if( jd->fd == -1 ) - return FALSE; - if( jd->ssl ) st = ssl_write( jd->ssl, jd->txq, jd->tx_len ); else @@ -96,7 +110,7 @@ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition jd->txq = NULL; jd->tx_len = 0; - return FALSE; + return TRUE; } else if( st == 0 || ( st < 0 && !sockerr_again() ) ) { @@ -186,11 +200,26 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition this is an old server that can't do SASL authentication. */ if( !sasl_supported( gc ) ) - return jabber_start_iq_auth( gc ); + { + /* If there's no version= tag, we suppose + this server does NOT implement: XMPP 1.0, + SASL and TLS. */ + if( set_getbool( &gc->acc->set, "tls" ) ) + { + hide_login_progress( gc, "TLS is turned on for this " + "account, but is not supported by this server" ); + signoff( gc ); + return FALSE; + } + else + { + return jabber_start_iq_auth( gc ); + } + } } else { - hide_login_progress_error( gc, "XML stream error" ); + hide_login_progress( gc, "XML stream error" ); signoff( gc ); return FALSE; } -- cgit v1.2.3 From 101d84fe3018ba138a9cb5f0f030997e8ff7bdbe Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 6 Oct 2006 00:55:54 +0200 Subject: Added max. recursion depth arguments to xt_handle()/_cleanup() to make sure commands that still have to be handled don't get (partially) cleaned up already. --- protocols/jabber/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 88ebf5d9..04b98626 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -169,7 +169,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } /* Execute all handlers. */ - if( !xt_handle( jd->xt, NULL ) ) + if( !xt_handle( jd->xt, NULL, 1 ) ) { /* Don't do anything, the handlers should have aborted the connection already... Or not? FIXME */ @@ -183,7 +183,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } /* Garbage collection. */ - xt_cleanup( jd->xt, NULL ); + xt_cleanup( jd->xt, NULL, 1 ); /* This is a bit hackish, unfortunately. Although xmltree has nifty event handler stuff, it only calls handlers -- cgit v1.2.3 From 090f1cbe72373b31e753af4a1442ddd53b02791b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 7 Oct 2006 15:01:02 +0200 Subject: Never mind about those privacy lists, they're horrible and not supported by any client I know of. Also, they're already working on a (probably completely incompatible) standard: JEP-191. Maybe BitlBee will implement it too some day... --- protocols/jabber/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 04b98626..73173dbc 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -385,7 +385,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) to bind/initialize the session. */ if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) { - if( !jabber_get_roster( gc ) || !jabber_get_privacy( gc ) ) + if( !jabber_get_roster( gc ) ) return XT_ABORT; } -- cgit v1.2.3 From 038d17f834219505cbbdae469b2b150117467dd0 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 8 Oct 2006 18:11:16 +0200 Subject: Implemented a better node cache using a GLib hash, and preparing to add event handlers that can be set when sending a packet to handle the reply to this specific packet. This should allow me to make the iq handler a lot cleaner. --- protocols/jabber/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 73173dbc..c6ad68e0 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -359,7 +359,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_packet( gc, reply ); + jabber_cache_add( gc, reply ); if( !jabber_write_packet( gc, reply ) ) return XT_ABORT; @@ -372,7 +372,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) reply = xt_new_node( "session", NULL, NULL ); xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_packet( gc, reply ); + jabber_cache_add( gc, reply ); if( !jabber_write_packet( gc, reply ) ) return XT_ABORT; -- cgit v1.2.3 From 861c199fb60fecf5dab96e0ed9d4b0cf0c57822f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 8 Oct 2006 20:41:11 +0200 Subject: Moved handling of all IQ packets to event handlers. Cleaned up a LOT of mess in iq.c! --- protocols/jabber/io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index c6ad68e0..783d6d2c 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -213,7 +213,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } else { - return jabber_start_iq_auth( gc ); + return jabber_init_iq_auth( gc ); } } } @@ -350,7 +350,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) to be XMPP 1.0 compliant! */ else if( !( jd->flags & JFLAG_AUTHENTICATED ) && sasl_supported( gc ) ) { - if( !jabber_start_iq_auth( gc ) ) + if( !jabber_init_iq_auth( gc ) ) return XT_ABORT; } @@ -359,7 +359,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( gc, reply ); + jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); if( !jabber_write_packet( gc, reply ) ) return XT_ABORT; @@ -372,7 +372,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) reply = xt_new_node( "session", NULL, NULL ); xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( gc, reply ); + jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); if( !jabber_write_packet( gc, reply ) ) return XT_ABORT; -- cgit v1.2.3 From b56b220e4280a75577f79b9dbcaf6eb2d7336873 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 11 Oct 2006 20:29:56 +0200 Subject: Fixed issues in end-of-connection detection and added basic "handling" of stream errors. (They can't really be handled, but at least the user can be informed.) --- protocols/jabber/io.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 783d6d2c..aa43d04e 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -161,7 +161,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( st > 0 ) { /* Parse. */ - if( !xt_feed( jd->xt, buf, st ) ) + if( xt_feed( jd->xt, buf, st ) < 0 ) { hide_login_progress_error( gc, "XML stream error" ); signoff( gc ); @@ -278,6 +278,7 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) { + signoff( data ); return XT_ABORT; } @@ -426,6 +427,53 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) return XT_HANDLED; } +static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) +{ + struct gaim_connection *gc = data; + struct xt_node *c; + char *s, *type = NULL, *text = NULL; + + for( c = node->children; c; c = c->next ) + { + if( !( s = xt_find_attr( c, "xmlns" ) ) || + strcmp( s, "urn:ietf:params:xml:ns:xmpp-streams" ) != 0 ) + continue; + + if( strcmp( c->name, "text" ) != 0 ) + { + type = c->name; + } + /* Only use the text if it doesn't have an xml:lang attribute, + if it's empty or if it's set to something English. */ + else if( !( s = xt_find_attr( c, "xml:lang" ) ) || + !*s || strncmp( s, "en", 2 ) == 0 ) + { + text = c->text; + } + } + + /* Tssk... */ + if( type == NULL ) + { + hide_login_progress_error( gc, "Unknown stream error reported by server" ); + signoff( gc ); + return XT_ABORT; + } + + /* We know that this is a fatal error. If it's a "conflict" error, we + should turn off auto-reconnect to make sure we won't get some nasty + infinite loop! */ + if( strcmp( type, "conflict" ) == 0 ) + gc->wants_to_die = TRUE; + + s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); + hide_login_progress_error( gc, s ); + g_free( s ); + signoff( gc ); + + return XT_ABORT; +} + static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) { printf( "Received unknown packet:\n" ); @@ -440,6 +488,7 @@ static const struct xt_handler_entry jabber_handlers[] = { { "presence", "stream:stream", jabber_pkt_presence }, { "iq", "stream:stream", jabber_pkt_iq }, { "stream:features", "stream:stream", jabber_pkt_features }, + { "stream:error", "stream:stream", jabber_pkt_stream_error }, { "proceed", "stream:stream", jabber_pkt_proceed_tls }, { "challenge", "stream:stream", sasl_pkt_challenge }, { "success", "stream:stream", sasl_pkt_result }, -- cgit v1.2.3 From 259edd40f5e332791a44f7547346bf799f1f7327 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 12 Oct 2006 19:48:58 +0200 Subject: Special message when the XMPP session is ended because of a concurrent login, and now sending proper error responses to IQ packets we can't handle. --- protocols/jabber/io.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index aa43d04e..665f5322 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -464,11 +464,17 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) should turn off auto-reconnect to make sure we won't get some nasty infinite loop! */ if( strcmp( type, "conflict" ) == 0 ) + { + hide_login_progress( gc, "Account and resource used from a different location" ); gc->wants_to_die = TRUE; + } + else + { + s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); + hide_login_progress_error( gc, s ); + g_free( s ); + } - s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); - hide_login_progress_error( gc, s ); - g_free( s ); signoff( gc ); return XT_ABORT; -- cgit v1.2.3 From 35f6677c07770f0323872e4edddefb7b752e50bd Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 21 Oct 2006 22:48:44 +0200 Subject: Proper detections of errors from *_connect() and added a "Connecting" message in jabber_login(). --- protocols/jabber/io.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 665f5322..bc08a977 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -101,8 +101,6 @@ static gboolean jabber_write_queue( struct gaim_connection *gc ) else st = write( jd->fd, jd->txq, jd->tx_len ); -// if( st > 0 ) write( 1, jd->txq, st ); - if( st == jd->tx_len ) { /* We wrote everything, clear the buffer. */ @@ -156,8 +154,6 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition else st = read( jd->fd, buf, sizeof( buf ) ); -// if( st > 0 ) write( 1, buf, st ); - if( st > 0 ) { /* Parse. */ -- cgit v1.2.3 From 47d3ac46306965e9db66096eef8c60c8e7985950 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 31 Oct 2006 09:25:41 +0100 Subject: Added #defines for XML namespaces. --- protocols/jabber/io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index bc08a977..1039bb87 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -306,7 +306,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( ( trytls || set_getbool( &gc->acc->set, "tls" ) ) ) { reply = xt_new_node( "starttls", NULL, NULL ); - xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-tls" ); + xt_add_attr( reply, "xmlns", XMLNS_TLS ); if( !jabber_write_packet( gc, reply ) ) { xt_free_node( reply ); @@ -354,7 +354,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( ( c = xt_find_node( node->children, "bind" ) ) ) { reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); - xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" ); + xt_add_attr( reply, "xmlns", XMLNS_BIND ); reply = jabber_make_packet( "iq", "set", NULL, reply ); jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); @@ -367,7 +367,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( ( c = xt_find_node( node->children, "session" ) ) ) { reply = xt_new_node( "session", NULL, NULL ); - xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" ); + xt_add_attr( reply, "xmlns", XMLNS_SESSION ); reply = jabber_make_packet( "iq", "set", NULL, reply ); jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); @@ -399,7 +399,7 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) /* Just ignore it when it doesn't seem to be TLS-related (is that at all possible??). */ - if( !xmlns || strcmp( xmlns, "urn:ietf:params:xml:ns:xmpp-tls" ) != 0 ) + if( !xmlns || strcmp( xmlns, XMLNS_TLS ) != 0 ) return XT_HANDLED; /* We don't want event handlers to touch our TLS session while it's @@ -432,7 +432,7 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) for( c = node->children; c; c = c->next ) { if( !( s = xt_find_attr( c, "xmlns" ) ) || - strcmp( s, "urn:ietf:params:xml:ns:xmpp-streams" ) != 0 ) + strcmp( s, XMLNS_STREAM_ERROR ) != 0 ) continue; if( strcmp( c->name, "text" ) != 0 ) -- cgit v1.2.3 From 25984f203b18ce36aabae431797266e44e9a3ba0 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 23 Nov 2006 19:46:09 +0100 Subject: Fixed me. ;-) This seems to be correct already. --- protocols/jabber/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 1039bb87..f05cc93d 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -168,7 +168,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( !xt_handle( jd->xt, NULL, 1 ) ) { /* Don't do anything, the handlers should have - aborted the connection already... Or not? FIXME */ + aborted the connection already. */ return FALSE; } -- cgit v1.2.3 From 0da65d5fb37691ed4d31f7ab4058732f1440db6b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 30 Mar 2007 22:40:45 -0700 Subject: s/gaim_connection/im_connection/ and some other minor API changes. The rest will come tomorrow. It compiles, I'll leave the real testing up to someone else. ;-) --- protocols/jabber/io.c | 154 +++++++++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 77 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index f05cc93d..6e699301 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -25,23 +25,23 @@ #include "ssl_client.h" static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ); -static gboolean jabber_write_queue( struct gaim_connection *gc ); +static gboolean jabber_write_queue( struct im_connection *ic ); -int jabber_write_packet( struct gaim_connection *gc, struct xt_node *node ) +int jabber_write_packet( struct im_connection *ic, struct xt_node *node ) { char *buf; int st; buf = xt_to_string( node ); - st = jabber_write( gc, buf, strlen( buf ) ); + st = jabber_write( ic, buf, strlen( buf ) ); g_free( buf ); return st; } -int jabber_write( struct gaim_connection *gc, char *buf, int len ) +int jabber_write( struct im_connection *ic, char *buf, int len ) { - struct jabber_data *jd = gc->proto_data; + struct jabber_data *jd = ic->proto_data; gboolean ret; if( jd->tx_len == 0 ) @@ -53,8 +53,8 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) /* Try if we can write it immediately so we don't have to do it via the event handler. If not, add the handler. (In most cases it probably won't be necessary.) */ - if( ( ret = jabber_write_queue( gc ) ) && jd->tx_len > 0 ) - jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, gc ); + if( ( ret = jabber_write_queue( ic ) ) && jd->tx_len > 0 ) + jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, ic ); } else { @@ -84,16 +84,16 @@ int jabber_write( struct gaim_connection *gc, char *buf, int len ) the socket is ready for more data). */ static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond ) { - struct jabber_data *jd = ((struct gaim_connection *)data)->proto_data; + struct jabber_data *jd = ((struct im_connection *)data)->proto_data; return jd->fd != -1 && jabber_write_queue( data ) && jd->tx_len > 0; } -static gboolean jabber_write_queue( struct gaim_connection *gc ) +static gboolean jabber_write_queue( struct im_connection *ic ) { - struct jabber_data *jd = gc->proto_data; + struct jabber_data *jd = ic->proto_data; int st; if( jd->ssl ) @@ -116,8 +116,8 @@ static gboolean jabber_write_queue( struct gaim_connection *gc ) closesocket( jd->fd ); /* Shouldn't be necessary after errors? */ jd->fd = -1; - hide_login_progress_error( gc, "Short write() to server" ); - signoff( gc ); + hide_login_progress_error( ic, "Short write() to server" ); + signoff( ic ); return FALSE; } else if( st > 0 ) @@ -141,8 +141,8 @@ static gboolean jabber_write_queue( struct gaim_connection *gc ) static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition cond ) { - struct gaim_connection *gc = data; - struct jabber_data *jd = gc->proto_data; + struct im_connection *ic = data; + struct jabber_data *jd = ic->proto_data; char buf[512]; int st; @@ -159,8 +159,8 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition /* Parse. */ if( xt_feed( jd->xt, buf, st ) < 0 ) { - hide_login_progress_error( gc, "XML stream error" ); - signoff( gc ); + hide_login_progress_error( ic, "XML stream error" ); + signoff( ic ); return FALSE; } @@ -175,7 +175,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( jd->flags & JFLAG_STREAM_RESTART ) { jd->flags &= ~JFLAG_STREAM_RESTART; - jabber_start_stream( gc ); + jabber_start_stream( ic ); } /* Garbage collection. */ @@ -195,28 +195,28 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition /* If there's no version attribute, assume this is an old server that can't do SASL authentication. */ - if( !sasl_supported( gc ) ) + if( !sasl_supported( ic ) ) { /* If there's no version= tag, we suppose this server does NOT implement: XMPP 1.0, SASL and TLS. */ - if( set_getbool( &gc->acc->set, "tls" ) ) + if( set_getbool( &ic->acc->set, "tls" ) ) { - hide_login_progress( gc, "TLS is turned on for this " + hide_login_progress( ic, "TLS is turned on for this " "account, but is not supported by this server" ); - signoff( gc ); + signoff( ic ); return FALSE; } else { - return jabber_init_iq_auth( gc ); + return jabber_init_iq_auth( ic ); } } } else { - hide_login_progress( gc, "XML stream error" ); - signoff( gc ); + hide_login_progress( ic, "XML stream error" ); + signoff( ic ); return FALSE; } } @@ -226,8 +226,8 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition closesocket( jd->fd ); jd->fd = -1; - hide_login_progress_error( gc, "Error while reading from server" ); - signoff( gc ); + hide_login_progress_error( ic, "Error while reading from server" ); + signoff( ic ); return FALSE; } @@ -237,24 +237,24 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond ) { - struct gaim_connection *gc = data; + struct im_connection *ic = data; if( source == -1 ) { - hide_login_progress( gc, "Could not connect to server" ); - signoff( gc ); + hide_login_progress( ic, "Could not connect to server" ); + signoff( ic ); return FALSE; } - set_login_progress( gc, 1, "Connected to server, logging in" ); + set_login_progress( ic, 1, "Connected to server, logging in" ); - return jabber_start_stream( gc ); + return jabber_start_stream( ic ); } gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond ) { - struct gaim_connection *gc = data; - struct jabber_data *jd = gc->proto_data; + struct im_connection *ic = data; + struct jabber_data *jd = ic->proto_data; if( source == NULL ) { @@ -262,14 +262,14 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co already, set it to NULL here to prevent a double cleanup: */ jd->ssl = NULL; - hide_login_progress( gc, "Could not connect to server" ); - signoff( gc ); + hide_login_progress( ic, "Could not connect to server" ); + signoff( ic ); return FALSE; } - set_login_progress( gc, 1, "Connected to server, logging in" ); + set_login_progress( ic, 1, "Connected to server, logging in" ); - return jabber_start_stream( gc ); + return jabber_start_stream( ic ); } static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) @@ -280,12 +280,12 @@ static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) { - struct gaim_connection *gc = data; - struct jabber_data *jd = gc->proto_data; + struct im_connection *ic = data; + struct jabber_data *jd = ic->proto_data; struct xt_node *c, *reply; int trytls; - trytls = g_strcasecmp( set_getstr( &gc->acc->set, "tls" ), "try" ) == 0; + trytls = g_strcasecmp( set_getstr( &ic->acc->set, "tls" ), "try" ) == 0; c = xt_find_node( node->children, "starttls" ); if( c && !jd->ssl ) { @@ -294,20 +294,20 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) c = xt_find_node( c->children, "required" ); - if( c && ( !trytls && !set_getbool( &gc->acc->set, "tls" ) ) ) + if( c && ( !trytls && !set_getbool( &ic->acc->set, "tls" ) ) ) { - hide_login_progress( gc, "Server requires TLS connections, but TLS is turned off for this account" ); - signoff( gc ); + hide_login_progress( ic, "Server requires TLS connections, but TLS is turned off for this account" ); + signoff( ic ); return XT_ABORT; } /* Only run this if the tls setting is set to true or try: */ - if( ( trytls || set_getbool( &gc->acc->set, "tls" ) ) ) + if( ( trytls || set_getbool( &ic->acc->set, "tls" ) ) ) { reply = xt_new_node( "starttls", NULL, NULL ); xt_add_attr( reply, "xmlns", XMLNS_TLS ); - if( !jabber_write_packet( gc, reply ) ) + if( !jabber_write_packet( ic, reply ) ) { xt_free_node( reply ); return XT_ABORT; @@ -324,10 +324,10 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) habit of not advertising anymore when already using SSL/TLS. */ - if( !trytls && set_getbool( &gc->acc->set, "tls" ) ) + if( !trytls && set_getbool( &ic->acc->set, "tls" ) ) { - hide_login_progress( gc, "TLS is turned on for this account, but is not supported by this server" ); - signoff( gc ); + hide_login_progress( ic, "TLS is turned on for this account, but is not supported by this server" ); + signoff( ic ); return XT_ABORT; } @@ -345,20 +345,20 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) support it after all, we should try to do authentication the other way. jabber.com doesn't seem to do SASL while it pretends to be XMPP 1.0 compliant! */ - else if( !( jd->flags & JFLAG_AUTHENTICATED ) && sasl_supported( gc ) ) + else if( !( jd->flags & JFLAG_AUTHENTICATED ) && sasl_supported( ic ) ) { - if( !jabber_init_iq_auth( gc ) ) + if( !jabber_init_iq_auth( ic ) ) return XT_ABORT; } if( ( c = xt_find_node( node->children, "bind" ) ) ) { - reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &gc->acc->set, "resource" ), NULL ) ); + reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) ); xt_add_attr( reply, "xmlns", XMLNS_BIND ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); + jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); - if( !jabber_write_packet( gc, reply ) ) + if( !jabber_write_packet( ic, reply ) ) return XT_ABORT; jd->flags |= JFLAG_WAIT_BIND; @@ -369,9 +369,9 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) reply = xt_new_node( "session", NULL, NULL ); xt_add_attr( reply, "xmlns", XMLNS_SESSION ); reply = jabber_make_packet( "iq", "set", NULL, reply ); - jabber_cache_add( gc, reply, jabber_pkt_bind_sess ); + jabber_cache_add( ic, reply, jabber_pkt_bind_sess ); - if( !jabber_write_packet( gc, reply ) ) + if( !jabber_write_packet( ic, reply ) ) return XT_ABORT; jd->flags |= JFLAG_WAIT_SESSION; @@ -382,7 +382,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) to bind/initialize the session. */ if( jd->flags & JFLAG_AUTHENTICATED && ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) { - if( !jabber_get_roster( gc ) ) + if( !jabber_get_roster( ic ) ) return XT_ABORT; } @@ -391,8 +391,8 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) { - struct gaim_connection *gc = data; - struct jabber_data *jd = gc->proto_data; + struct im_connection *ic = data; + struct jabber_data *jd = ic->proto_data; char *xmlns; xmlns = xt_find_attr( node, "xmlns" ); @@ -416,16 +416,16 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) } jd->w_inpa = jd->r_inpa = 0; - set_login_progress( gc, 1, "Converting stream to TLS" ); + set_login_progress( ic, 1, "Converting stream to TLS" ); - jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, gc ); + jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, ic ); return XT_HANDLED; } static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) { - struct gaim_connection *gc = data; + struct im_connection *ic = data; struct xt_node *c; char *s, *type = NULL, *text = NULL; @@ -451,8 +451,8 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) /* Tssk... */ if( type == NULL ) { - hide_login_progress_error( gc, "Unknown stream error reported by server" ); - signoff( gc ); + hide_login_progress_error( ic, "Unknown stream error reported by server" ); + signoff( ic ); return XT_ABORT; } @@ -461,17 +461,17 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) infinite loop! */ if( strcmp( type, "conflict" ) == 0 ) { - hide_login_progress( gc, "Account and resource used from a different location" ); - gc->wants_to_die = TRUE; + hide_login_progress( ic, "Account and resource used from a different location" ); + ic->wants_to_die = TRUE; } else { s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); - hide_login_progress_error( gc, s ); + hide_login_progress_error( ic, s ); g_free( s ); } - signoff( gc ); + signoff( ic ); return XT_ABORT; } @@ -499,35 +499,35 @@ static const struct xt_handler_entry jabber_handlers[] = { { NULL, NULL, NULL } }; -gboolean jabber_start_stream( struct gaim_connection *gc ) +gboolean jabber_start_stream( struct im_connection *ic ) { - struct jabber_data *jd = gc->proto_data; + struct jabber_data *jd = ic->proto_data; int st; char *greet; /* We'll start our stream now, so prepare everything to receive one from the server too. */ xt_free( jd->xt ); /* In case we're RE-starting. */ - jd->xt = xt_new( gc ); + jd->xt = xt_new( ic ); jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; if( jd->r_inpa <= 0 ) - jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, gc ); + jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, ic ); greet = g_strdup_printf( "" "", jd->server ); - st = jabber_write( gc, greet, strlen( greet ) ); + st = jabber_write( ic, greet, strlen( greet ) ); g_free( greet ); return st; } -void jabber_end_stream( struct gaim_connection *gc ) +void jabber_end_stream( struct im_connection *ic ) { - struct jabber_data *jd = gc->proto_data; + struct jabber_data *jd = ic->proto_data; /* Let's only do this if the queue is currently empty, otherwise it'd take too long anyway. */ @@ -537,14 +537,14 @@ void jabber_end_stream( struct gaim_connection *gc ) struct xt_node *node; int st = 1; - if( gc->flags & OPT_LOGGED_IN ) + if( ic->flags & OPT_LOGGED_IN ) { node = jabber_make_packet( "presence", "unavailable", NULL, NULL ); - st = jabber_write_packet( gc, node ); + st = jabber_write_packet( ic, node ); xt_free_node( node ); } if( st ) - jabber_write( gc, eos, strlen( eos ) ); + jabber_write( ic, eos, strlen( eos ) ); } } -- cgit v1.2.3 From aef4828a1dc51de10a43bb7dd5d023de9971295b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 5 Apr 2007 22:20:31 -0700 Subject: More cleanups, mainly in the callbacks. Replaced things like do_error_dialog() and (set|hide)_login_progress(_error)?() with things that hopefully make more sense. Although it's still not really great... --- protocols/jabber/io.c | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 6e699301..699c7019 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -116,8 +116,8 @@ static gboolean jabber_write_queue( struct im_connection *ic ) closesocket( jd->fd ); /* Shouldn't be necessary after errors? */ jd->fd = -1; - hide_login_progress_error( ic, "Short write() to server" ); - signoff( ic ); + imc_error( ic, "Short write() to server" ); + imc_logout( ic ); return FALSE; } else if( st > 0 ) @@ -159,8 +159,8 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition /* Parse. */ if( xt_feed( jd->xt, buf, st ) < 0 ) { - hide_login_progress_error( ic, "XML stream error" ); - signoff( ic ); + imc_error( ic, "XML stream error" ); + imc_logout( ic ); return FALSE; } @@ -202,9 +202,9 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition SASL and TLS. */ if( set_getbool( &ic->acc->set, "tls" ) ) { - hide_login_progress( ic, "TLS is turned on for this " + imc_error( ic, "TLS is turned on for this " "account, but is not supported by this server" ); - signoff( ic ); + imc_logout( ic ); return FALSE; } else @@ -215,8 +215,8 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } else { - hide_login_progress( ic, "XML stream error" ); - signoff( ic ); + imc_error( ic, "XML stream error" ); + imc_logout( ic ); return FALSE; } } @@ -226,8 +226,8 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition closesocket( jd->fd ); jd->fd = -1; - hide_login_progress_error( ic, "Error while reading from server" ); - signoff( ic ); + imc_error( ic, "Error while reading from server" ); + imc_logout( ic ); return FALSE; } @@ -241,12 +241,12 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c if( source == -1 ) { - hide_login_progress( ic, "Could not connect to server" ); - signoff( ic ); + imc_error( ic, "Could not connect to server" ); + imc_logout( ic ); return FALSE; } - set_login_progress( ic, 1, "Connected to server, logging in" ); + imc_log( ic, "Connected to server, logging in" ); return jabber_start_stream( ic ); } @@ -262,19 +262,19 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co already, set it to NULL here to prevent a double cleanup: */ jd->ssl = NULL; - hide_login_progress( ic, "Could not connect to server" ); - signoff( ic ); + imc_error( ic, "Could not connect to server" ); + imc_logout( ic ); return FALSE; } - set_login_progress( ic, 1, "Connected to server, logging in" ); + imc_log( ic, "Connected to server, logging in" ); return jabber_start_stream( ic ); } static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) { - signoff( data ); + imc_logout( data ); return XT_ABORT; } @@ -296,8 +296,8 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( c && ( !trytls && !set_getbool( &ic->acc->set, "tls" ) ) ) { - hide_login_progress( ic, "Server requires TLS connections, but TLS is turned off for this account" ); - signoff( ic ); + imc_error( ic, "Server requires TLS connections, but TLS is turned off for this account" ); + imc_logout( ic ); return XT_ABORT; } @@ -326,8 +326,8 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( !trytls && set_getbool( &ic->acc->set, "tls" ) ) { - hide_login_progress( ic, "TLS is turned on for this account, but is not supported by this server" ); - signoff( ic ); + imc_error( ic, "TLS is turned on for this account, but is not supported by this server" ); + imc_logout( ic ); return XT_ABORT; } @@ -416,7 +416,7 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) } jd->w_inpa = jd->r_inpa = 0; - set_login_progress( ic, 1, "Converting stream to TLS" ); + imc_log( ic, "Converting stream to TLS" ); jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, ic ); @@ -451,8 +451,8 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) /* Tssk... */ if( type == NULL ) { - hide_login_progress_error( ic, "Unknown stream error reported by server" ); - signoff( ic ); + imc_error( ic, "Unknown stream error reported by server" ); + imc_logout( ic ); return XT_ABORT; } @@ -461,17 +461,17 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) infinite loop! */ if( strcmp( type, "conflict" ) == 0 ) { - hide_login_progress( ic, "Account and resource used from a different location" ); + imc_error( ic, "Account and resource used from a different location" ); ic->wants_to_die = TRUE; } else { s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); - hide_login_progress_error( ic, s ); + imc_error( ic, s ); g_free( s ); } - signoff( ic ); + imc_logout( ic ); return XT_ABORT; } -- cgit v1.2.3 From 552e641194147078c7858059df9916d5d548b7a1 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 5 Apr 2007 22:34:23 -0700 Subject: Now that all these functions take format strings, I have to make sure I use that and don't introduce vulnerabilities. :-) --- protocols/jabber/io.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 699c7019..bf52fb4e 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -466,9 +466,7 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) } else { - s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); - imc_error( ic, s ); - g_free( s ); + imc_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); } imc_logout( ic ); -- cgit v1.2.3 From c2fb38096ea4e75a680e57e103d4a4986aa84c75 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 15 Apr 2007 15:39:35 -0700 Subject: Cleaned up struct im_connection. No more username/password stuff since it's in acc too. wants_to_die is now an argument to imc_logout(). --- protocols/jabber/io.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index bf52fb4e..c64901f7 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -117,7 +117,7 @@ static gboolean jabber_write_queue( struct im_connection *ic ) jd->fd = -1; imc_error( ic, "Short write() to server" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } else if( st > 0 ) @@ -160,7 +160,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition if( xt_feed( jd->xt, buf, st ) < 0 ) { imc_error( ic, "XML stream error" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } @@ -204,7 +204,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition { imc_error( ic, "TLS is turned on for this " "account, but is not supported by this server" ); - imc_logout( ic ); + imc_logout( ic, FALSE ); return FALSE; } else @@ -216,7 +216,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition else { imc_error( ic, "XML stream error" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } } @@ -227,7 +227,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition jd->fd = -1; imc_error( ic, "Error while reading from server" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } @@ -242,7 +242,7 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c if( source == -1 ) { imc_error( ic, "Could not connect to server" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } @@ -263,7 +263,7 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co jd->ssl = NULL; imc_error( ic, "Could not connect to server" ); - imc_logout( ic ); + imc_logout( ic, TRUE ); return FALSE; } @@ -274,7 +274,7 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data ) { - imc_logout( data ); + imc_logout( data, TRUE ); return XT_ABORT; } @@ -297,7 +297,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( c && ( !trytls && !set_getbool( &ic->acc->set, "tls" ) ) ) { imc_error( ic, "Server requires TLS connections, but TLS is turned off for this account" ); - imc_logout( ic ); + imc_logout( ic, FALSE ); return XT_ABORT; } @@ -327,7 +327,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( !trytls && set_getbool( &ic->acc->set, "tls" ) ) { imc_error( ic, "TLS is turned on for this account, but is not supported by this server" ); - imc_logout( ic ); + imc_logout( ic, FALSE ); return XT_ABORT; } @@ -428,6 +428,7 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) struct im_connection *ic = data; struct xt_node *c; char *s, *type = NULL, *text = NULL; + int allow_reconnect = TRUE; for( c = node->children; c; c = c->next ) { @@ -452,7 +453,7 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) if( type == NULL ) { imc_error( ic, "Unknown stream error reported by server" ); - imc_logout( ic ); + imc_logout( ic, allow_reconnect ); return XT_ABORT; } @@ -462,14 +463,14 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) if( strcmp( type, "conflict" ) == 0 ) { imc_error( ic, "Account and resource used from a different location" ); - ic->wants_to_die = TRUE; + allow_reconnect = FALSE; } else { imc_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); } - imc_logout( ic ); + imc_logout( ic, allow_reconnect ); return XT_ABORT; } -- cgit v1.2.3 From 84b045d409f1e8da6d8bf379c6fef7236dcd9bcd Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 15 Apr 2007 18:03:08 -0700 Subject: s/imc/imcb/ for callback functions. Moved things aroundin nogaim.h a little bit, grouping things by category instead of original Gaim 0.58 filename. --- protocols/jabber/io.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index c64901f7..67deb3a6 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -116,7 +116,7 @@ static gboolean jabber_write_queue( struct im_connection *ic ) closesocket( jd->fd ); /* Shouldn't be necessary after errors? */ jd->fd = -1; - imc_error( ic, "Short write() to server" ); + imcb_error( ic, "Short write() to server" ); imc_logout( ic, TRUE ); return FALSE; } @@ -159,7 +159,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition /* Parse. */ if( xt_feed( jd->xt, buf, st ) < 0 ) { - imc_error( ic, "XML stream error" ); + imcb_error( ic, "XML stream error" ); imc_logout( ic, TRUE ); return FALSE; } @@ -202,7 +202,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition SASL and TLS. */ if( set_getbool( &ic->acc->set, "tls" ) ) { - imc_error( ic, "TLS is turned on for this " + imcb_error( ic, "TLS is turned on for this " "account, but is not supported by this server" ); imc_logout( ic, FALSE ); return FALSE; @@ -215,7 +215,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } else { - imc_error( ic, "XML stream error" ); + imcb_error( ic, "XML stream error" ); imc_logout( ic, TRUE ); return FALSE; } @@ -226,7 +226,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition closesocket( jd->fd ); jd->fd = -1; - imc_error( ic, "Error while reading from server" ); + imcb_error( ic, "Error while reading from server" ); imc_logout( ic, TRUE ); return FALSE; } @@ -241,12 +241,12 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c if( source == -1 ) { - imc_error( ic, "Could not connect to server" ); + imcb_error( ic, "Could not connect to server" ); imc_logout( ic, TRUE ); return FALSE; } - imc_log( ic, "Connected to server, logging in" ); + imcb_log( ic, "Connected to server, logging in" ); return jabber_start_stream( ic ); } @@ -262,12 +262,12 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co already, set it to NULL here to prevent a double cleanup: */ jd->ssl = NULL; - imc_error( ic, "Could not connect to server" ); + imcb_error( ic, "Could not connect to server" ); imc_logout( ic, TRUE ); return FALSE; } - imc_log( ic, "Connected to server, logging in" ); + imcb_log( ic, "Connected to server, logging in" ); return jabber_start_stream( ic ); } @@ -296,7 +296,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( c && ( !trytls && !set_getbool( &ic->acc->set, "tls" ) ) ) { - imc_error( ic, "Server requires TLS connections, but TLS is turned off for this account" ); + imcb_error( ic, "Server requires TLS connections, but TLS is turned off for this account" ); imc_logout( ic, FALSE ); return XT_ABORT; @@ -326,7 +326,7 @@ static xt_status jabber_pkt_features( struct xt_node *node, gpointer data ) if( !trytls && set_getbool( &ic->acc->set, "tls" ) ) { - imc_error( ic, "TLS is turned on for this account, but is not supported by this server" ); + imcb_error( ic, "TLS is turned on for this account, but is not supported by this server" ); imc_logout( ic, FALSE ); return XT_ABORT; @@ -416,7 +416,7 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) } jd->w_inpa = jd->r_inpa = 0; - imc_log( ic, "Converting stream to TLS" ); + imcb_log( ic, "Converting stream to TLS" ); jd->ssl = ssl_starttls( jd->fd, jabber_connected_ssl, ic ); @@ -452,7 +452,7 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) /* Tssk... */ if( type == NULL ) { - imc_error( ic, "Unknown stream error reported by server" ); + imcb_error( ic, "Unknown stream error reported by server" ); imc_logout( ic, allow_reconnect ); return XT_ABORT; } @@ -462,12 +462,12 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) infinite loop! */ if( strcmp( type, "conflict" ) == 0 ) { - imc_error( ic, "Account and resource used from a different location" ); + imcb_error( ic, "Account and resource used from a different location" ); allow_reconnect = FALSE; } else { - imc_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); + imcb_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); } imc_logout( ic, allow_reconnect ); -- cgit v1.2.3 From bb95d43e263530805224005ca246addb6bb199fa Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 4 Jun 2007 12:32:37 +0100 Subject: Added a real XML-console to the Jabber module! Add the handle "xmlconsole" (without any @server part) to your contact list and you'll see all XMPP traffic going in and out, and messages sent to the buddy will be sent as packets to the server. --- protocols/jabber/io.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 67deb3a6..edde5a8d 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -44,6 +44,15 @@ int jabber_write( struct im_connection *ic, char *buf, int len ) struct jabber_data *jd = ic->proto_data; gboolean ret; + if( jd->flags & JFLAG_XMLCONSOLE ) + { + char *msg; + + msg = g_strdup_printf( "TX: %s", buf ); + imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 ); + g_free( msg ); + } + if( jd->tx_len == 0 ) { /* If the queue is empty, allocate a new buffer. */ @@ -483,7 +492,27 @@ static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) return XT_HANDLED; } +static xt_status jabber_xmlconsole( struct xt_node *node, gpointer data ) +{ + struct im_connection *ic = data; + struct jabber_data *jd = ic->proto_data; + + if( jd->flags & JFLAG_XMLCONSOLE ) + { + char *msg, *pkt; + + pkt = xt_to_string( node ); + msg = g_strdup_printf( "RX: %s", pkt ); + imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 ); + g_free( msg ); + g_free( pkt ); + } + + return XT_NEXT; +} + static const struct xt_handler_entry jabber_handlers[] = { + { NULL, "stream:stream", jabber_xmlconsole }, { "stream:stream", "", jabber_end_of_stream }, { "message", "stream:stream", jabber_pkt_message }, { "presence", "stream:stream", jabber_pkt_presence }, -- cgit v1.2.3 From 1baaef858136cd3a4799b3ccf1d9961534e0017c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 30 Jul 2007 20:12:06 +0100 Subject: Added jabber_error_parse() and using it for both stream- and stanza (only presence so far) errors. --- protocols/jabber/io.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index edde5a8d..cf71ff87 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -435,50 +435,35 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data ) static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) { struct im_connection *ic = data; - struct xt_node *c; - char *s, *type = NULL, *text = NULL; int allow_reconnect = TRUE; + struct jabber_error *err; - for( c = node->children; c; c = c->next ) - { - if( !( s = xt_find_attr( c, "xmlns" ) ) || - strcmp( s, XMLNS_STREAM_ERROR ) != 0 ) - continue; - - if( strcmp( c->name, "text" ) != 0 ) - { - type = c->name; - } - /* Only use the text if it doesn't have an xml:lang attribute, - if it's empty or if it's set to something English. */ - else if( !( s = xt_find_attr( c, "xml:lang" ) ) || - !*s || strncmp( s, "en", 2 ) == 0 ) - { - text = c->text; - } - } + err = jabber_error_parse( node, XMLNS_STREAM_ERROR ); /* Tssk... */ - if( type == NULL ) + if( err->code == NULL ) { imcb_error( ic, "Unknown stream error reported by server" ); imc_logout( ic, allow_reconnect ); + jabber_error_free( err ); return XT_ABORT; } /* We know that this is a fatal error. If it's a "conflict" error, we should turn off auto-reconnect to make sure we won't get some nasty infinite loop! */ - if( strcmp( type, "conflict" ) == 0 ) + if( strcmp( err->code, "conflict" ) == 0 ) { imcb_error( ic, "Account and resource used from a different location" ); allow_reconnect = FALSE; } else { - imcb_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); + imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "", + err->text ? err->text : "" ); } + jabber_error_free( err ); imc_logout( ic, allow_reconnect ); return XT_ABORT; -- cgit v1.2.3 From 1bf1ae6f25ff56894d67999791802aa864eaa02b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 14 Nov 2007 23:09:22 +0000 Subject: Removed some debugging stuff that shouldn't have been here for a long time already. --- protocols/jabber/io.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 67deb3a6..925463a4 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -475,14 +475,6 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) return XT_ABORT; } -static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data ) -{ - printf( "Received unknown packet:\n" ); - xt_print( node ); - - return XT_HANDLED; -} - static const struct xt_handler_entry jabber_handlers[] = { { "stream:stream", "", jabber_end_of_stream }, { "message", "stream:stream", jabber_pkt_message }, @@ -494,7 +486,6 @@ static const struct xt_handler_entry jabber_handlers[] = { { "challenge", "stream:stream", sasl_pkt_challenge }, { "success", "stream:stream", sasl_pkt_result }, { "failure", "stream:stream", sasl_pkt_result }, - { NULL, "stream:stream", jabber_pkt_misc }, { NULL, NULL, NULL } }; -- cgit v1.2.3 From d52111a7b05657e4a4fa8417e6655389a50769cf Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 12 Dec 2007 21:36:33 +0000 Subject: Fixed sockerr_again() usage in Jabber module to (hopefully) fix a 100% CPU usage bug. --- protocols/jabber/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 61cd142e..29561b86 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -119,7 +119,7 @@ static gboolean jabber_write_queue( struct im_connection *ic ) return TRUE; } - else if( st == 0 || ( st < 0 && !sockerr_again() ) ) + else if( st == 0 || ( st < 0 && !ssl_sockerr_again( jd->ssl ) ) ) { /* Set fd to -1 to make sure we won't write to it anymore. */ closesocket( jd->fd ); /* Shouldn't be necessary after errors? */ @@ -230,7 +230,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition } } } - else if( st == 0 || ( st < 0 && !sockerr_again() ) ) + else if( st == 0 || ( st < 0 && !ssl_sockerr_again( jd->ssl ) ) ) { closesocket( jd->fd ); jd->fd = -1; -- cgit v1.2.3 From b5c8a34aeff244ffe7a9f4bd5edf827495d0deea Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 24 Jan 2008 22:49:47 +0000 Subject: Keeping track of valid Jabber connections so _connected() events will be ignored if the connection's dead already. Necessary if using GLib for event handling for now. :-/ --- protocols/jabber/io.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 29561b86..86c216ef 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -248,6 +248,9 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c { struct im_connection *ic = data; + if( g_slist_find( jabber_connections, ic ) == NULL ) + return FALSE; + if( source == -1 ) { imcb_error( ic, "Could not connect to server" ); @@ -263,7 +266,12 @@ gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition c gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition cond ) { struct im_connection *ic = data; - struct jabber_data *jd = ic->proto_data; + struct jabber_data *jd; + + if( g_slist_find( jabber_connections, ic ) == NULL ) + return FALSE; + + jd = ic->proto_data; if( source == NULL ) { -- cgit v1.2.3 From 4bbcba32aca2948f66c484ab074264fdb67609ae Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 16 Feb 2008 22:40:38 +0000 Subject: Moved xmltree handlers initialization to xt_new(). --- protocols/jabber/io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 86c216ef..9980dc8e 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -520,8 +520,7 @@ gboolean jabber_start_stream( struct im_connection *ic ) /* We'll start our stream now, so prepare everything to receive one from the server too. */ xt_free( jd->xt ); /* In case we're RE-starting. */ - jd->xt = xt_new( ic ); - jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; + jd->xt = xt_new( jabber_handlers, ic ); if( jd->r_inpa <= 0 ) jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, ic ); -- cgit v1.2.3 From 8a2221a79b177a5c6d0b55dafebd39414d7fe10a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 23 Mar 2008 14:29:19 +0000 Subject: Fixed stalling issue with OpenSSL and Jabber (#368). --- protocols/jabber/io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'protocols/jabber/io.c') diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index 9980dc8e..10efad37 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -240,8 +240,13 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition return FALSE; } - /* EAGAIN/etc or a successful read. */ - return TRUE; + if( ssl_pending( jd->ssl ) ) + /* OpenSSL empties the TCP buffers completely but may keep some + data in its internap buffers. select() won't see that, but + ssl_pending() does. */ + return jabber_read_callback( data, fd, cond ); + else + return TRUE; } gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond ) -- cgit v1.2.3