changeset 28694:c7aaad89a2f8

jabber: Re-arrange the code that detects legacy servers so that we don't stomp over "Host Unknown" errors. Legacy servers don't send <stream:features>, so we need to notice when we've finished the opening <stream:stream> tag and, if there was no version, start authentication right then. This was causingon other valid errors (like the server complaining it's not who we think it is) to be replaced by a complaint "You require encryption...". Closes #10450. This seems to work in all the cases I've tested (including with jabberd14).
author Paul Aurich <paul@darkrain42.org>
date Tue, 06 Oct 2009 03:25:26 +0000
parents 5c61429ea529
children c5280f5677b5
files libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/parser.c
diffstat 2 files changed, 23 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/jabber.c	Mon Oct 05 18:10:08 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Tue Oct 06 03:25:26 2009 +0000
@@ -68,8 +68,6 @@
 #include "jingle/jingle.h"
 #include "jingle/rtp.h"
 
-#define JABBER_CONNECT_STEPS (js->gsc ? 9 : 5)
-
 PurplePlugin *jabber_plugin = NULL;
 GList *jabber_features = NULL;
 GList *jabber_identities = NULL;
@@ -198,9 +196,10 @@
 void jabber_stream_features_parse(JabberStream *js, xmlnode *packet)
 {
 	if(xmlnode_get_child(packet, "starttls")) {
-		if(jabber_process_starttls(js, packet))
-
+		if(jabber_process_starttls(js, packet)) {
+			jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING_ENCRYPTION);
 			return;
+		}
 	} else if(purple_account_get_bool(js->gc->account, "require_tls", FALSE) && !jabber_stream_is_ssl(js)) {
 		purple_connection_error_reason(js->gc,
 			 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
@@ -211,6 +210,7 @@
 	if(js->registration) {
 		jabber_register_start(js);
 	} else if(xmlnode_get_child(packet, "mechanisms")) {
+		jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING);
 		jabber_auth_start(js, packet);
 	} else if(xmlnode_get_child(packet, "bind")) {
 		xmlnode *bind, *resource;
@@ -289,8 +289,10 @@
 		if(js->state == JABBER_STREAM_AUTHENTICATING)
 			jabber_auth_handle_failure(js, *packet);
 	} else if(!strcmp((*packet)->name, "proceed")) {
-		if(js->state == JABBER_STREAM_AUTHENTICATING && !js->gsc)
+		if (js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION && !js->gsc)
 			tls_init(js);
+		else
+			purple_debug_warning("jabber", "Ignoring spurious <proceed/>\n");
 	} else {
 		purple_debug(PURPLE_DEBUG_WARNING, "jabber", "Unknown packet: %s\n",
 				(*packet)->name);
@@ -1570,6 +1572,8 @@
 
 void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
 {
+#define JABBER_CONNECT_STEPS ((js->gsc || js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION) ? 9 : 5)
+
 	js->state = state;
 	switch(state) {
 		case JABBER_STREAM_OFFLINE:
@@ -1607,6 +1611,8 @@
 			purple_connection_set_state(js->gc, PURPLE_CONNECTED);
 			break;
 	}
+
+#undef JABBER_CONNECT_STEPS
 }
 
 char *jabber_get_next_id(JabberStream *js)
--- a/libpurple/protocols/jabber/parser.c	Mon Oct 05 18:10:08 2009 +0000
+++ b/libpurple/protocols/jabber/parser.c	Tue Oct 06 03:25:26 2009 +0000
@@ -62,11 +62,6 @@
 				g_free(attrib);
 			}
 		}
-		if(js->protocol_version == JABBER_PROTO_0_9)
-			js->auth_type = JABBER_AUTH_IQ_AUTH;
-
-		if(js->state == JABBER_STREAM_INITIALIZING || js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION)
-			jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING);
 	} else {
 
 		if(js->current)
@@ -256,5 +251,17 @@
 				break;
 		}
 	}
+
+	if (js->protocol_version == JABBER_PROTO_0_9 && !js->gc->disconnect_timeout &&
+			(js->state == JABBER_STREAM_INITIALIZING ||
+			 js->state == JABBER_STREAM_INITIALIZING_ENCRYPTION)) {
+		/*
+		 * Legacy servers don't advertise features, so if we've just gotten
+		 * the opening <stream:stream> and there was no version, we need to
+		 * immediately start legacy IQ auth.
+		 */
+		js->auth_type = JABBER_AUTH_IQ_AUTH;
+		jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING);
+	}
 }