cpw.darkrain42.xmpp.scram: 3820a806: jabber: Fix up the cyrus auth code (alth...

darkrain42 at pidgin.im darkrain42 at pidgin.im
Fri Dec 4 01:32:04 EST 2009


-----------------------------------------------------------------
Revision: 3820a806a169960c1c5eed606d6ce431bb92a000
Ancestor: f1af8fe229e16f1aa75efa63193aa7e166d25ed9
Author: darkrain42 at pidgin.im
Date: 2009-12-04T06:04:18
Branch: im.pidgin.cpw.darkrain42.xmpp.scram
URL: http://d.pidgin.im/viewmtn/revision/info/3820a806a169960c1c5eed606d6ce431bb92a000

Modified files:
        libpurple/protocols/jabber/auth_cyrus.c po/POTFILES.in

ChangeLog: 

jabber: Fix up the cyrus auth code (although there's a leak currently)

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/auth_cyrus.c	d240f2cadfc446736a57e55eeeba97e8051d036e
+++ libpurple/protocols/jabber/auth_cyrus.c	640fdbe1b43ed6869fbab7f15a6353eccc8cdf67
@@ -28,7 +28,8 @@
 #include "auth.h"
 #include "jabber.h"
 
-static xmlnode *jabber_auth_start_cyrus(JabberStream *);
+static JabberSaslState jabber_auth_start_cyrus(JabberStream *js, xmlnode **reply,
+                                               const char **error);
 static void jabber_sasl_build_callbacks(JabberStream *);
 
 static void disallow_plaintext_auth(PurpleAccount *account)
@@ -38,6 +39,23 @@ static void disallow_plaintext_auth(Purp
 		_("Server requires plaintext authentication over an unencrypted stream"));
 }
 
+static void start_cyrus_wrapper(JabberStream *js)
+{
+	const char *error;
+	xmlnode *response;
+	JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error);
+
+	if (state == JABBER_SASL_STATE_FAIL) {
+		purple_connection_error_reason(js->gc,
+				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
+				error);
+	} else if (response) {
+		jabber_send(js, response);
+		xmlnode_free(response);
+	}
+}
+
+
 /* Callbacks for Cyrus SASL */
 
 static int jabber_sasl_cb_realm(void *ctx, int id, const char **avail, const char **result)
@@ -100,25 +118,19 @@ static void allow_cyrus_plaintext_auth(P
 {
 	PurpleConnection *gc;
 	JabberStream *js;
-	xmlnode *response;
 
 	gc = purple_account_get_connection(account);
 	js = purple_connection_get_protocol_data(gc);
 
 	purple_account_set_bool(account, "auth_plain_in_clear", TRUE);
 
-	response = jabber_auth_start_cyrus(js);
-	if (response) {
-		jabber_send(js, response);
-		xmlnode_free(response);
-	}
+	start_cyrus_wrapper(js);
 }
 
 static void auth_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields)
 {
 	PurpleAccount *account;
 	JabberStream *js;
-	xmlnode *response;
 	const char *entry;
 	gboolean remember;
 
@@ -146,12 +158,8 @@ static void auth_pass_cb(PurpleConnectio
 	/* Rebuild our callbacks as we now have a password to offer */
 	jabber_sasl_build_callbacks(js);
 
-	/* Restart our connection */
-	response = jabber_auth_start_cyrus(js);
-	if (response) {
-		jabber_send(js, response);
-		xmlnode_free(response);
-	}
+	/* Restart our negotiation */
+	start_cyrus_wrapper(js);
 }
 
 static void
@@ -171,13 +179,13 @@ auth_no_pass_cb(PurpleConnection *gc, Pu
 	purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
 }
 
-static xmlnode *jabber_auth_start_cyrus(JabberStream *js)
+static JabberSaslState
+jabber_auth_start_cyrus(JabberStream *js, xmlnode **reply, const char **error)
 {
 	PurpleAccount *account;
 	const char *clientout = NULL;
 	char *enc_out;
 	unsigned coutlen = 0;
-	xmlnode *auth;
 	sasl_security_properties_t secprops;
 	gboolean again;
 	gboolean plaintext = TRUE;
@@ -225,7 +233,7 @@ static xmlnode *jabber_auth_start_cyrus(
 
 				if (!purple_account_get_password(account)) {
 					purple_account_request_password(account, G_CALLBACK(auth_pass_cb), G_CALLBACK(auth_no_pass_cb), js->gc);
-					return NULL;
+					return JABBER_SASL_STATE_CONTINUE;
 
 				/* If we've got a password, but aren't sending
 				 * it in plaintext, see if we can turn on
@@ -241,7 +249,7 @@ static xmlnode *jabber_auth_start_cyrus(
 							allow_cyrus_plaintext_auth,
 							disallow_plaintext_auth);
 					g_free(msg);
-					return NULL;
+					return JABBER_SASL_STATE_CONTINUE;
 
 				} else {
 					/* We have no mechs which can work.
@@ -258,7 +266,7 @@ static xmlnode *jabber_auth_start_cyrus(
 					 */
 					js->auth_mech = NULL;
 					jabber_auth_start_old(js);
-					return NULL;
+					return JABBER_SASL_STATE_CONTINUE;
 				}
 				/* not reached */
 				break;
@@ -301,7 +309,7 @@ static xmlnode *jabber_auth_start_cyrus(
 	} while (again);
 
 	if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) {
-		auth = xmlnode_new("auth");
+		xmlnode *auth = xmlnode_new("auth");
 		xmlnode_set_namespace(auth, NS_XMPP_SASL);
 		xmlnode_set_attrib(auth, "mechanism", js->current_mech);
 
@@ -318,13 +326,11 @@ static xmlnode *jabber_auth_start_cyrus(
 			}
 		}
 
-		return auth;
+		*reply = auth;
+		return JABBER_SASL_STATE_CONTINUE;
 	} else {
-		purple_connection_error_reason(js->gc,
-			PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
-			_("SASL authentication failed"));
-
-		return NULL;
+		*error = _("SASL authentication failed");
+		return JABBER_SASL_STATE_FAIL;
 	}
 }
 
@@ -379,7 +385,9 @@ jabber_sasl_build_callbacks(JabberStream
 	js->sasl_cb[id].id = SASL_CB_LIST_END;
 }
 
-static xmlnode *jabber_cyrus_start(JabberStream *js, xmlnode *mechanisms)
+static JabberSaslState
+jabber_cyrus_start(JabberStream *js, xmlnode *mechanisms,
+                   xmlnode **reply, const char **error)
 {
 	xmlnode *mechnode;
 
@@ -410,10 +418,12 @@ static xmlnode *jabber_cyrus_start(Jabbe
 	}
 
 	jabber_sasl_build_callbacks(js);
-	return jabber_auth_start_cyrus(js);
+	return jabber_auth_start_cyrus(js, reply, error);
 }
 
-static xmlnode *jabber_cyrus_handle_challenge(JabberStream *js, xmlnode *packet)
+static JabberSaslState
+jabber_cyrus_handle_challenge(JabberStream *js, xmlnode *packet,
+                              xmlnode **reply, const char **error)
 {
 	char *enc_in = xmlnode_get_data(packet);
 	unsigned char *dec_in;
@@ -421,7 +431,6 @@ static xmlnode *jabber_cyrus_handle_chal
 	const char *c_out;
 	unsigned int clen;
 	gsize declen;
-	xmlnode *response = NULL;
 
 	dec_in = purple_base64_decode(enc_in, &declen);
 
@@ -434,11 +443,10 @@ static xmlnode *jabber_cyrus_handle_chal
 				sasl_errdetail(js->sasl));
 		purple_debug_error("jabber", "Error is %d : %s\n",
 				js->sasl_state, sasl_errdetail(js->sasl));
-		purple_connection_error_reason(js->gc,
-			PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
-		g_free(tmp);
+		*error = tmp;
+		return JABBER_SASL_STATE_FAIL;
 	} else {
-		response = xmlnode_new("response");
+		xmlnode *response = xmlnode_new("response");
 		xmlnode_set_namespace(response, NS_XMPP_SASL);
 		if (clen > 0) {
 			/* Cyrus SASL 2.1.22 appears to contain code to add the charset
@@ -462,12 +470,15 @@ static xmlnode *jabber_cyrus_handle_chal
 			xmlnode_insert_data(response, enc_out, -1);
 			g_free(enc_out);
 		}
+
+		*reply = response;
+		return JABBER_SASL_STATE_CONTINUE;
 	}
-
-	return response;
 }
 
-static gboolean jabber_cyrus_handle_success(JabberStream *js, xmlnode *packet)
+static JabberSaslState
+jabber_cyrus_handle_success(JabberStream *js, xmlnode *packet,
+                            const char **error)
 {
 	const void *x;
 
@@ -491,10 +502,8 @@ static gboolean jabber_cyrus_handle_succ
 
 		if (js->sasl_state != SASL_OK) {
 			/* This should never happen! */
-			purple_connection_error_reason(js->gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Invalid response from server"));
-			g_return_val_if_reached(FALSE);
+			*error = _("Invalid response from server");
+			g_return_val_if_reached(JABBER_SASL_STATE_FAIL);
 		}
 	}
 
@@ -507,10 +516,12 @@ static gboolean jabber_cyrus_handle_succ
 		}
 	}
 
-	return TRUE;
+	return JABBER_SASL_STATE_OK;
 }
 
-static xmlnode *jabber_cyrus_handle_failure(JabberStream *js, xmlnode *packet)
+static JabberSaslState
+jabber_cyrus_handle_failure(JabberStream *js, xmlnode *packet,
+                            xmlnode **reply, const char **error)
 {
 	if (js->auth_fail_count++ < 5) {
 		if (js->current_mech && *js->current_mech) {
@@ -527,12 +538,12 @@ static xmlnode *jabber_cyrus_handle_fail
 			/* If we have remaining mechs to try, do so */
 			sasl_dispose(&js->sasl);
 
-			return jabber_auth_start_cyrus(js);
+			return jabber_auth_start_cyrus(js, reply, error);
 		}
 	}
 
 	/* Nothing to send */
-	return NULL;
+	return JABBER_SASL_STATE_FAIL;
 }
 
 static JabberSaslMech cyrus_mech = {
============================================================
--- po/POTFILES.in	f73e15f236c02f19e1e8f88707de76d495069d2b
+++ po/POTFILES.in	3d91aa25a94b170e69a73a92909e0503fef602e9
@@ -91,6 +91,7 @@ libpurple/protocols/jabber/auth_plain.c
 libpurple/protocols/jabber/auth_cyrus.c
 libpurple/protocols/jabber/auth_digest_md5.c
 libpurple/protocols/jabber/auth_plain.c
+libpurple/protocols/jabber/auth_scram.c
 libpurple/protocols/jabber/bosh.c
 libpurple/protocols/jabber/buddy.c
 libpurple/protocols/jabber/chat.c


More information about the Commits mailing list