# HG changeset patch # User Paul Aurich # Date 1268791614 0 # Node ID 22faf27397d280705ea2c5de5ef00fc8656629d8 # Parent bfaf039aed87406490b060f90e72f7118470b06a# Parent 6e598ca344b3c2a2c0b2e7c05c224072f1ce2551 merge of '8524850cd868993d8572075af80943765b232d45' and 'c0fb4b16f604abbca72e2d063be8d03653d5aac2' diff -r bfaf039aed87 -r 22faf27397d2 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Tue Mar 16 06:20:05 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Mar 17 02:06:54 2010 +0000 @@ -86,6 +86,11 @@ { char *open_stream; + if (js->stream_id) { + g_free(js->stream_id); + js->stream_id = NULL; + } + open_stream = g_strdup_printf("gc), "jabber-receiving-xmlnode", js->gc, packet); @@ -269,6 +275,7 @@ if(NULL == *packet) return; + name = (*packet)->name; xmlns = xmlnode_get_namespace(*packet); if(!strcmp((*packet)->name, "iq")) { @@ -277,30 +284,30 @@ jabber_presence_parse(js, *packet); } else if(!strcmp((*packet)->name, "message")) { jabber_message_parse(js, *packet); - } else if(!strcmp((*packet)->name, "stream:features")) { - jabber_stream_features_parse(js, *packet); - } else if (!strcmp((*packet)->name, "features") && xmlns && - !strcmp(xmlns, NS_XMPP_STREAMS)) { - jabber_stream_features_parse(js, *packet); - } else if(!strcmp((*packet)->name, "stream:error") || - (!strcmp((*packet)->name, "error") && xmlns && - !strcmp(xmlns, NS_XMPP_STREAMS))) - { - jabber_stream_handle_error(js, *packet); - } else if(!strcmp((*packet)->name, "challenge")) { - if(js->state == JABBER_STREAM_AUTHENTICATING) - jabber_auth_handle_challenge(js, *packet); - } else if(!strcmp((*packet)->name, "success")) { - if(js->state == JABBER_STREAM_AUTHENTICATING) - jabber_auth_handle_success(js, *packet); - } else if(!strcmp((*packet)->name, "failure")) { - if(js->state == JABBER_STREAM_AUTHENTICATING) - jabber_auth_handle_failure(js, *packet); - } else if(!strcmp((*packet)->name, "proceed")) { - if (js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION && !js->gsc) - tls_init(js); - else - purple_debug_warning("jabber", "Ignoring spurious \n"); + } else if (purple_strequal(xmlns, NS_XMPP_STREAMS)) { + if (g_str_equal(name, "features")) + jabber_stream_features_parse(js, *packet); + else if (g_str_equal(name, "error")) + jabber_stream_handle_error(js, *packet); + } else if (purple_strequal(xmlns, NS_XMPP_SASL)) { + if (js->state != JABBER_STREAM_AUTHENTICATING) + purple_debug_warning("jabber", "Ignoring spurious SASL stanza %s\n", name); + else { + if (g_str_equal(name, "challenge")) + jabber_auth_handle_challenge(js, *packet); + else if (g_str_equal(name, "success")) + jabber_auth_handle_success(js, *packet); + else if (g_str_equal(name, "failure")) + jabber_auth_handle_failure(js, *packet); + } + } else if (purple_strequal(xmlns, NS_XMPP_TLS)) { + if (js->state != JABBER_STREAM_INITIALIZING_ENCRYPTION || js->gsc) + purple_debug_warning("jabber", "Ignoring spurious %s\n", name); + else { + if (g_str_equal(name, "proceed")) + tls_init(js); + /* TODO: Handle , I guess? */ + } } else { purple_debug_warning("jabber", "Unknown packet: %s\n", (*packet)->name); } diff -r bfaf039aed87 -r 22faf27397d2 libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Tue Mar 16 06:20:05 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.h Wed Mar 17 02:06:54 2010 +0000 @@ -112,6 +112,13 @@ JabberSaslMech *auth_mech; gpointer auth_mech_data; + + /** + * The header from the opening tag. This being NULL is treated + * as a special condition in the parsing code (signifying the next + * stanza started is an opening stream tag), and its being missing on + * the stream header is treated as a fatal error. + */ char *stream_id; JabberStreamState state; diff -r bfaf039aed87 -r 22faf27397d2 libpurple/protocols/jabber/namespaces.h --- a/libpurple/protocols/jabber/namespaces.h Tue Mar 16 06:20:05 2010 +0000 +++ b/libpurple/protocols/jabber/namespaces.h Wed Mar 17 02:06:54 2010 +0000 @@ -30,6 +30,7 @@ #define NS_XMPP_SESSION "urn:ietf:params:xml:ns:xmpp-session" #define NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas" #define NS_XMPP_STREAMS "http://etherx.jabber.org/streams" +#define NS_XMPP_TLS "urn:ietf:params:xml:ns:xmpp-tls" /* XEP-0012 Last Activity (and XEP-0256 Last Activity in Presence) */ #define NS_LAST_ACTIVITY "jabber:iq:last" diff -r bfaf039aed87 -r 22faf27397d2 libpurple/protocols/jabber/parser.c --- a/libpurple/protocols/jabber/parser.c Tue Mar 16 06:20:05 2010 +0000 +++ b/libpurple/protocols/jabber/parser.c Wed Mar 17 02:06:54 2010 +0000 @@ -43,10 +43,25 @@ if(!element_name) { return; - } else if(!xmlStrcmp(element_name, (xmlChar*) "stream")) { + } else if (js->stream_id == NULL) { + /* Sanity checking! */ + if (0 != xmlStrcmp(element_name, (xmlChar *) "stream") || + 0 != xmlStrcmp(namespace, (xmlChar *) NS_XMPP_STREAMS)) { + /* We were expecting a opening stanza, but + * didn't get it. Bad! + */ + purple_debug_error("jabber", "Expecting stream header, got %s with " + "xmlns %s\n", element_name, namespace); + purple_connection_error_reason(js->gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, + _("XMPP stream header missing")); + return; + } + js->protocol_version.major = 0; js->protocol_version.minor = 9; - for(i=0; i < nb_attributes * 5; i += 5) { + + for (i = 0; i < nb_attributes * 5; i += 5) { int attrib_len = attributes[i+4] - attributes[i+3]; char *attrib = g_strndup((gchar *)attributes[i+3], attrib_len); @@ -56,11 +71,14 @@ js->protocol_version.major = atoi(attrib); js->protocol_version.minor = dot ? atoi(dot + 1) : 0; - if (js->protocol_version.major > 1) + if (js->protocol_version.major > 1) { /* TODO: Send error */ purple_connection_error_reason(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("XMPP Version Mismatch")); + g_free(attrib); + return; + } if (js->protocol_version.major == 0 && js->protocol_version.minor != 9) { purple_debug_warning("jabber", "Treating version %s as 0.9 for backward " @@ -74,6 +92,11 @@ g_free(attrib); } } + + if (js->stream_id == NULL) + purple_connection_error_reason(js->gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, + _("XMPP stream missing ID")); } else { if(js->current)