# HG changeset patch # User Stu Tomlinson # Date 1208068667 0 # Node ID 23fe481afccf7dce7ad6f165fda6c8944217bff6 # Parent def8f39f542a23edc240ee99ee6e20cda8fd5b51 The next version of RFC 3920, the draft of which can be found at http://www.xmpp.org/internet-drafts/draft-saintandre-rfc3920bis-04.html, and subsequent email clarifications with Peter Saint-Andre and Alexey Melnikov indicate that we should be trying the next mechanism in line after one mechanism fails. We should also be ensuring that the mech list is sorted in order of descending security, which we don't do yet; however, servers are supposed to send us a sorted list, as well, so this isn't a major issue. committer: Evan Schoenberg diff -r def8f39f542a -r 23fe481afccf libpurple/protocols/jabber/auth.c --- a/libpurple/protocols/jabber/auth.c Sat Apr 12 23:34:27 2008 +0000 +++ b/libpurple/protocols/jabber/auth.c Sun Apr 13 06:37:47 2008 +0000 @@ -264,7 +264,7 @@ static void jabber_auth_start_cyrus(JabberStream *js) { - const char *clientout = NULL, *mech = NULL; + const char *clientout = NULL; char *enc_out; unsigned coutlen = 0; xmlnode *auth; @@ -297,7 +297,7 @@ if (js->sasl_state==SASL_OK) { sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops); purple_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str); - js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &mech); + js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &js->current_mech); } switch (js->sasl_state) { /* Success */ @@ -372,10 +372,10 @@ * due to mechanism specific issues, so we want to try one of the other * supported mechanisms. This code handles that case */ - if (mech && strlen(mech) > 0) { + if (js->current_mech && strlen(js->current_mech) > 0) { char *pos; - if ((pos = strstr(js->sasl_mechs->str, mech))) { - g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(mech)); + if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) { + g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(js->current_mech)); } again = TRUE; } @@ -387,7 +387,7 @@ if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) { auth = xmlnode_new("auth"); xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl"); - xmlnode_set_attrib(auth, "mechanism", mech); + xmlnode_set_attrib(auth, "mechanism", js->current_mech); if (clientout) { if (coutlen == 0) { xmlnode_insert_data(auth, "=", -1); @@ -1101,8 +1101,24 @@ void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet) { PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; - char *msg = jabber_parse_error(js, packet, &reason); + char *msg; +#ifdef HAVE_CYRUS_SASL + if(js->auth_fail_count++ < 5) { + if (js->current_mech && strlen(js->current_mech) > 0) { + char *pos; + if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) { + g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(js->current_mech)); + } + } + + sasl_dispose(&js->sasl); + + jabber_auth_start_cyrus(js); + return; + } +#endif + msg = jabber_parse_error(js, packet, &reason); if(!msg) { purple_connection_error_reason (js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, diff -r def8f39f542a -r 23fe481afccf libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Sat Apr 12 23:34:27 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.h Sun Apr 13 06:37:47 2008 +0000 @@ -158,6 +158,11 @@ void *sasl; void *sasl_cb; #endif + /* did someone say something about the end of the struct? */ +#ifdef HAVE_CYRUS_SASL + const char *current_mech; + int auth_fail_count; +#endif int sasl_state; int sasl_maxbuf;