changeset 27039:9a79f8a99259

Set charset=utf-8 when cyrus sasl doesn't include it. Both deryni and my reading of the digest md5 cyrus plugin is that the response will never actually include the charset (digestmd5.c:make_client_response, look for IsUTF8). I future-proofed this code by checking for it anyway. To be polite for older servers, we might want to only send this if the server sent charset=utf-8 in the challenge (and encode everything to ISO-8859-1). However, the RFC doesn't say always sending it is wrong (and that's what the in-tree implementation does).
author Paul Aurich <paul@darkrain42.org>
date Fri, 05 Jun 2009 07:02:16 +0000
parents f3b0232ef1ea
children 1fd829110a6d
files ChangeLog libpurple/protocols/jabber/auth.c
diffstat 2 files changed, 17 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jun 05 05:44:44 2009 +0000
+++ b/ChangeLog	Fri Jun 05 07:02:16 2009 +0000
@@ -52,6 +52,9 @@
 	  chat to avoid getting too many fetch requests).
 	* Fix an issue with Jabber (pre-XMPP) servers and the user's preference
 	  to require SSL not being respected.
+	* Fix an issue where Cyrus SASL DIGEST MD5 authentication might fail if
+	  the username, password, or realm (the JID domain) contain characters
+	  not in ISO-8859-1.
 
 	Yahoo:
 	* P2P file transfers.  (Sulabh Mahajan)
--- a/libpurple/protocols/jabber/auth.c	Fri Jun 05 05:44:44 2009 +0000
+++ b/libpurple/protocols/jabber/auth.c	Fri Jun 05 07:02:16 2009 +0000
@@ -989,7 +989,20 @@
 			response = xmlnode_new("response");
 			xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl");
 			if (clen > 0) {
-				enc_out = purple_base64_encode((unsigned char*)c_out, clen);
+				/* Cyrus SASL 2.1.22 appears to contain code to add the charset
+				 * to the response but there is no possibility it will be executed.
+				 * My reading of the digestmd5 plugin indicates the username and
+				 * realm are always encoded in UTF-8 (they seem to be the values
+				 * we pass in), so we need to ensure charset=utf-8 is set.
+				 */
+				if (strstr(c_out, ",charset="))
+					enc_out = purple_base64_encode((unsigned char*)c_out, clen);
+				else {
+					char *tmp = g_strdup_printf("%s,charset=utf-8", c_out);
+					enc_out = purple_base64_encode((unsigned char*)c_out, clen + 14);
+					g_free(tmp);
+				}
+
 				xmlnode_insert_data(response, enc_out, -1);
 				g_free(enc_out);
 			}