changeset 30004:22faf27397d2

merge of '8524850cd868993d8572075af80943765b232d45' and 'c0fb4b16f604abbca72e2d063be8d03653d5aac2'
author Paul Aurich <paul@darkrain42.org>
date Wed, 17 Mar 2010 02:06:54 +0000
parents bfaf039aed87 (current diff) 6e598ca344b3 (diff)
children 12ba4c648872
files
diffstat 4 files changed, 65 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- 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("<stream:stream to='%s' "
 				          "xmlns='" NS_XMPP_CLIENT "' "
 						  "xmlns:stream='" NS_XMPP_STREAMS "' "
@@ -261,6 +266,7 @@
 
 void jabber_process_packet(JabberStream *js, xmlnode **packet)
 {
+	const char *name;
 	const char *xmlns;
 
 	purple_signal_emit(purple_connection_get_prpl(js->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 <proceed/>\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 <failure/>, I guess? */
+		}
 	} else {
 		purple_debug_warning("jabber", "Unknown packet: %s\n", (*packet)->name);
 	}
--- 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 <stream/> 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;
 
--- 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"
--- 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 <stream:stream/> 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 <unsupported-version/> 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)