/pidgin/main: 8f99c1dff72e: Fix jabber password dialog infinite ...

Jakub Adam jakub.adam at ktknet.cz
Mon Apr 18 22:55:49 EDT 2016


Changeset: 8f99c1dff72ebfb584c0e5d48a2e8bee6d05fed4
Author:	 Jakub Adam <jakub.adam at ktknet.cz>
Date:	 2015-09-03 14:32 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/8f99c1dff72e

Description:

Fix jabber password dialog infinite loop with SASL

When connecting a Jabber account that doesn't have any stored password,
Pidgin compiled with --enable-cyrus-sasl went into an infinite loop of
dialogs requesting user to enter the password.

This was happening because jabber_auth_start_cyrus() was calling
purple_connection_get_password() in order to check if the connection
has some password stored and when the returned value was NULL, it fired
purple_account_request_password(), let the user enter the password and
called itself again in a loop.

However, password once set (or left NULL) on PurpleConnection
construction can't be changed and auth_pass_cb() called by
purple_account_request_password() is storing the password into
PurpleAccount (purple_account_set_password()), not the connection.
Consequently, when jabber_auth_start_cyrus() got fired again, it still
read the old NULL value from purple_connection_get_password() and thus
kept popping up the password dialog over and over again.

As a fix, the SASL password is now kept in JabberStream structure. It is
initialized once by purple_connection_get_password() and auth_pass_cb()
updates both PurpleAccount password and the JabberStream value.

diffstat:

 libpurple/protocols/jabber/auth_cyrus.c |  14 +++++++-------
 libpurple/protocols/jabber/jabber.c     |   1 +
 libpurple/protocols/jabber/jabber.h     |   2 ++
 3 files changed, 10 insertions(+), 7 deletions(-)

diffs (87 lines):

diff --git a/libpurple/protocols/jabber/auth_cyrus.c b/libpurple/protocols/jabber/auth_cyrus.c
--- a/libpurple/protocols/jabber/auth_cyrus.c
+++ b/libpurple/protocols/jabber/auth_cyrus.c
@@ -91,15 +91,12 @@ static int jabber_sasl_cb_simple(void *c
 static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secret_t **secret)
 {
 	JabberStream *js = ctx;
-	const char *pw;
 	size_t len;
 
-	pw = purple_connection_get_password(js->gc);
-
 	if (!conn || !secret || id != SASL_CB_PASS)
 		return SASL_BADPARAM;
 
-	len = strlen(pw);
+	len = strlen(js->sasl_password);
 	/* Not an off-by-one because sasl_secret_t defines char data[1] */
 	/* TODO: This can probably be moved to glib's allocator */
 	js->sasl_secret = malloc(sizeof(sasl_secret_t) + len);
@@ -107,7 +104,7 @@ static int jabber_sasl_cb_secret(sasl_co
 		return SASL_NOMEM;
 
 	js->sasl_secret->len = len;
-	strcpy((char*)js->sasl_secret->data, pw);
+	strcpy((char*)js->sasl_secret->data, js->sasl_password);
 
 	*secret = js->sasl_secret;
 	return SASL_OK;
@@ -155,6 +152,8 @@ static void auth_pass_cb(PurpleConnectio
 
 	purple_account_set_password(account, entry, NULL, NULL);
 
+	js->sasl_password = g_strdup(entry);
+
 	/* Rebuild our callbacks as we now have a password to offer */
 	jabber_sasl_build_callbacks(js);
 
@@ -247,7 +246,7 @@ jabber_auth_start_cyrus(JabberStream *js
 				 * to get one
 				 */
 
-				if (!purple_connection_get_password(js->gc)) {
+				if (!js->sasl_password) {
 					purple_account_request_password(account, G_CALLBACK(auth_pass_cb), G_CALLBACK(auth_no_pass_cb), js->gc);
 					return JABBER_SASL_STATE_CONTINUE;
 
@@ -384,7 +383,7 @@ jabber_sasl_build_callbacks(JabberStream
 	js->sasl_cb[id].context = (void *)js;
 	id++;
 
-	if (purple_connection_get_password(js->gc) != NULL) {
+	if (js->sasl_password != NULL) {
 		js->sasl_cb[id].id = SASL_CB_PASS;
 		js->sasl_cb[id].proc = (void *)jabber_sasl_cb_secret;
 		js->sasl_cb[id].context = (void *)js;
@@ -407,6 +406,7 @@ jabber_cyrus_start(JabberStream *js, Pur
 	JabberSaslState ret;
 
 	js->sasl_mechs = g_string_new("");
+	js->sasl_password = g_strdup(purple_connection_get_password(js->gc));
 
 	for(mechnode = purple_xmlnode_get_child(mechanisms, "mechanism"); mechnode;
 			mechnode = purple_xmlnode_get_next_twin(mechnode))
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -1696,6 +1696,7 @@ void jabber_close(PurpleConnection *gc)
 	g_free(js->sasl_cb);
 	/* Note: _not_ g_free.  See auth_cyrus.c:jabber_sasl_cb_secret */
 	free(js->sasl_secret);
+	g_free(js->sasl_password);
 #endif
 	g_free(js->serverFQDN);
 	while(js->commands) {
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -233,6 +233,8 @@ struct _JabberStream
 	int sasl_state;
 	int sasl_maxbuf;
 	GString *sasl_mechs;
+
+	gchar *sasl_password;
 #endif
 
 	gboolean unregistration;



More information about the Commits mailing list