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

Jakub Adam <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 8f99c1dff72ebfb584c0e5d48a2e8bee6d05fed4
Author:	 Jakub Adam <[email protected]>
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;

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.