changeset 28711:65a34cce02e3

jabber: Fix up the remaining issues and add a test case that interoperates with gsasl. Woot.
author Paul Aurich <paul@darkrain42.org>
date Tue, 17 Nov 2009 19:39:36 +0000
parents fed4286634e7
children 40a46992c728
files libpurple/protocols/jabber/auth_scram.c libpurple/protocols/jabber/auth_scram.h libpurple/tests/test_jabber_scram.c
diffstat 3 files changed, 56 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/auth_scram.c	Tue Nov 17 19:23:05 2009 +0000
+++ b/libpurple/protocols/jabber/auth_scram.c	Tue Nov 17 19:39:36 2009 +0000
@@ -226,7 +226,7 @@
 	/* Ensure that the first cnonce_len bytes of the nonce are the original
 	 * cnonce we sent to the server.
 	 */
-	if (!g_str_equal(data->cnonce, token + 2))
+	if (0 != strncmp(data->cnonce, token + 2, strlen(data->cnonce)))
 		goto err;
 
 	nonce = g_strdup(token + 2);
@@ -264,7 +264,8 @@
 
 err:
 	g_free(nonce);
-	g_string_free(salt, TRUE);
+	if (salt)
+		g_string_free(salt, TRUE);
 	g_strfreev(tokens);
 	return FALSE;
 }
@@ -290,8 +291,8 @@
 	return TRUE;
 }
 
-static gboolean
-feed_parser(JabberScramData *data, gchar *in, gchar **out)
+gboolean
+jabber_scram_feed_parser(JabberScramData *data, gchar *in, gchar **out)
 {
 	gboolean ret;
 
@@ -311,8 +312,8 @@
 
 		g_string_append_c(data->auth_message, ',');
 
-		/* "biwsCg==" is the base64 encoding of "n,,". I promise. */
-		g_string_append_printf(data->auth_message, "c=%s,r=%s", "biwsCg==", nonce);
+		/* "biws" is the base64 encoding of "n,,". I promise. */
+		g_string_append_printf(data->auth_message, "c=%s,r=%s", "biws", nonce);
 #ifdef CHANNEL_BINDING
 #error fix this
 #endif
@@ -322,7 +323,7 @@
 			return FALSE;
 
 		proof = purple_base64_encode((guchar *)data->client_proof->str, data->client_proof->len);
-		*out = g_strdup_printf("c=%s,r=%s,p=%s", "biwsCg==", nonce, proof);
+		*out = g_strdup_printf("c=%s,r=%s,p=%s", "biws", nonce, proof);
 		g_free(proof);
 	} else if (data->step == 2) {
 		gchar *server_sig, *enc_server_sig;
@@ -428,7 +429,7 @@
 
 	purple_debug_misc("jabber", "decoded challenge: %s\n", dec_in);
 
-	if (!feed_parser(data, dec_in, &dec_out)) {
+	if (!jabber_scram_feed_parser(data, dec_in, &dec_out)) {
 		reply = xmlnode_new("abort");
 		xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl");
 		data->step = -1;
@@ -479,7 +480,7 @@
 
 	purple_debug_misc("jabber", "decoded success: %s\n", dec_in);
 
-	if (!feed_parser(data, dec_in, &dec_out) || dec_out != NULL) {
+	if (!jabber_scram_feed_parser(data, dec_in, &dec_out) || dec_out != NULL) {
 		g_free(dec_out);
 		return FALSE;
 	}
@@ -488,19 +489,22 @@
 	return TRUE;
 }
 
+void jabber_scram_data_destroy(JabberScramData *data)
+{
+	g_free(data->cnonce);
+	if (data->auth_message)
+		g_string_free(data->auth_message, TRUE);
+	if (data->client_proof)
+		g_string_free(data->client_proof, TRUE);
+	if (data->server_signature)
+		g_string_free(data->server_signature, TRUE);
+	g_free(data);
+}
+
 static void scram_dispose(JabberStream *js)
 {
 	if (js->auth_mech_data) {
-		JabberScramData *data = js->auth_mech_data;
-
-		g_free(data->cnonce);
-		if (data->auth_message)
-			g_string_free(data->auth_message, TRUE);
-		if (data->client_proof)
-			g_string_free(data->client_proof, TRUE);
-		if (data->server_signature)
-			g_string_free(data->server_signature, TRUE);
-		g_free(data);
+		jabber_scram_data_destroy(js->auth_mech_data);
 		js->auth_mech_data = NULL;
 	}
 }
--- a/libpurple/protocols/jabber/auth_scram.h	Tue Nov 17 19:23:05 2009 +0000
+++ b/libpurple/protocols/jabber/auth_scram.h	Tue Nov 17 19:39:36 2009 +0000
@@ -81,4 +81,14 @@
 gboolean jabber_scram_calc_proofs(JabberScramData *data, GString *salt,
                                   guint iterations);
 
+/**
+ * Feed the algorithm with the data from the server.
+ */
+gboolean jabber_scram_feed_parser(JabberScramData *data, gchar *in, gchar **out);
+
+/**
+ * Clean up and destroy the data struct
+ */
+void jabber_scram_data_destroy(JabberScramData *data);
+
 #endif /* PURPLE_JABBER_AUTH_SCRAM_H_ */
--- a/libpurple/tests/test_jabber_scram.c	Tue Nov 17 19:23:05 2009 +0000
+++ b/libpurple/tests/test_jabber_scram.c	Tue Nov 17 19:39:36 2009 +0000
@@ -4,8 +4,6 @@
 #include "../util.h"
 #include "../protocols/jabber/auth_scram.h"
 
-static JabberSaslMech *scram_sha1_mech = NULL;
-
 #define assert_pbkdf2_equal(password, salt, count, expected) { \
 	GString *p = g_string_new(password); \
 	GString *s = g_string_new(salt); \
@@ -55,14 +53,31 @@
 }
 END_TEST
 
-#if 0
 START_TEST(test_mech)
 {
-	scram_sha1_mech = jabber_scram_get_sha1();
+	JabberScramData *data = g_new0(JabberScramData, 1);
+	gboolean ret;
+	gchar *out;
+
+	data->step = 1;
+	data->hash = "sha1";
+	data->password = "password";
+	data->cnonce = g_strdup("H7yDYKAWBCrM2Fa5SxGa4iez");
+	data->auth_message = g_string_new("n=paul,r=H7yDYKAWBCrM2Fa5SxGa4iez");
 
+	ret = jabber_scram_feed_parser(data, "r=H7yDYKAWBCrM2Fa5SxGa4iezFPVDPpDUcGxPkH3RzP,s=3rXeErP/os7jUNqU,i=4096", &out);
+	fail_unless(ret == TRUE);
+	fail_unless(g_str_equal(out, "c=biws,r=H7yDYKAWBCrM2Fa5SxGa4iezFPVDPpDUcGxPkH3RzP,p=pXkak78EuwwOEwk2/h/OzD7NkEI="), "Failed. Got %s instead", out);
+	g_free(out);
+
+	data->step = 2;
+	ret = jabber_scram_feed_parser(data, "v=ldX4EBNnOgDnNTOCmbSfBHAUCOs=", &out);
+	fail_unless(ret == TRUE);
+	fail_unless(out == NULL);
+
+	jabber_scram_data_destroy(data);
 }
 END_TEST
-#endif
 
 Suite *
 jabber_scram_suite(void)
@@ -77,5 +92,8 @@
 	tcase_add_test(tc, test_proofs);
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("SCRAM exchange");
+	tcase_add_test(tc, test_mech);
+	suite_add_tcase(s, tc);
 	return s;
 }