changeset 29602:6e598ca344b3

jabber: Clear the stream header when restarting a stream, and be much stricter about the first tag in a stream.
author Paul Aurich <paul@darkrain42.org>
date Fri, 12 Mar 2010 06:25:15 +0000
parents f5f3c5134eb7
children 22faf27397d2
files libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h libpurple/protocols/jabber/parser.c
diffstat 3 files changed, 38 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/jabber.c	Fri Mar 12 06:16:43 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Fri Mar 12 06:25:15 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 "' "
--- a/libpurple/protocols/jabber/jabber.h	Fri Mar 12 06:16:43 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Fri Mar 12 06:25:15 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/parser.c	Fri Mar 12 06:16:43 2010 +0000
+++ b/libpurple/protocols/jabber/parser.c	Fri Mar 12 06:25:15 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)