/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