# HG changeset patch # User Paul Aurich # Date 1258486776 0 # Node ID 65a34cce02e3051c5e858f80ae7e067d5faeeff7 # Parent fed4286634e7157c55b588ab35dd6e388cc5e55a jabber: Fix up the remaining issues and add a test case that interoperates with gsasl. Woot. diff -r fed4286634e7 -r 65a34cce02e3 libpurple/protocols/jabber/auth_scram.c --- 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; } } diff -r fed4286634e7 -r 65a34cce02e3 libpurple/protocols/jabber/auth_scram.h --- 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_ */ diff -r fed4286634e7 -r 65a34cce02e3 libpurple/tests/test_jabber_scram.c --- 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; }