| 299 #ifdef CHANNEL_BINDING |
299 #ifdef CHANNEL_BINDING |
| 300 #error fix this |
300 #error fix this |
| 301 #endif |
301 #endif |
| 302 |
302 |
| 303 ret = jabber_scram_calc_proofs(data, salt, iterations); |
303 ret = jabber_scram_calc_proofs(data, salt, iterations); |
| 304 if (!ret) |
304 |
| |
305 g_string_free(salt, TRUE); |
| |
306 salt = NULL; |
| |
307 if (!ret) { |
| |
308 g_free(nonce); |
| 305 return FALSE; |
309 return FALSE; |
| |
310 } |
| 306 |
311 |
| 307 proof = purple_base64_encode((guchar *)data->client_proof->str, data->client_proof->len); |
312 proof = purple_base64_encode((guchar *)data->client_proof->str, data->client_proof->len); |
| 308 *out = g_strdup_printf("c=%s,r=%s,p=%s", "biws", nonce, proof); |
313 *out = g_strdup_printf("c=%s,r=%s,p=%s", "biws", nonce, proof); |
| |
314 g_free(nonce); |
| 309 g_free(proof); |
315 g_free(proof); |
| 310 } else if (data->step == 2) { |
316 } else if (data->step == 2) { |
| 311 gchar *server_sig, *enc_server_sig; |
317 gchar *server_sig, *enc_server_sig; |
| 312 gsize len; |
318 gsize len; |
| 313 |
319 |
| 417 static JabberSaslState |
423 static JabberSaslState |
| 418 scram_handle_challenge(JabberStream *js, xmlnode *challenge, xmlnode **out, char **error) |
424 scram_handle_challenge(JabberStream *js, xmlnode *challenge, xmlnode **out, char **error) |
| 419 { |
425 { |
| 420 JabberScramData *data = js->auth_mech_data; |
426 JabberScramData *data = js->auth_mech_data; |
| 421 xmlnode *reply; |
427 xmlnode *reply; |
| 422 gchar *enc_in, *dec_in; |
428 gchar *enc_in, *dec_in = NULL; |
| 423 gchar *enc_out = NULL, *dec_out = NULL; |
429 gchar *enc_out = NULL, *dec_out = NULL; |
| 424 gsize len; |
430 gsize len; |
| 425 JabberSaslState state = JABBER_SASL_STATE_FAIL; |
431 JabberSaslState state = JABBER_SASL_STATE_FAIL; |
| 426 |
432 |
| 427 enc_in = xmlnode_get_data(challenge); |
433 enc_in = xmlnode_get_data(challenge); |
| 432 *error = g_strdup(_("Invalid challenge from server")); |
438 *error = g_strdup(_("Invalid challenge from server")); |
| 433 goto out; |
439 goto out; |
| 434 } |
440 } |
| 435 |
441 |
| 436 dec_in = (gchar *)purple_base64_decode(enc_in, &len); |
442 dec_in = (gchar *)purple_base64_decode(enc_in, &len); |
| 437 g_free(enc_in); |
|
| 438 if (!dec_in || len != strlen(dec_in)) { |
443 if (!dec_in || len != strlen(dec_in)) { |
| 439 /* Danger afoot; SCRAM shouldn't contain NUL bytes */ |
444 /* Danger afoot; SCRAM shouldn't contain NUL bytes */ |
| 440 reply = xmlnode_new("abort"); |
445 reply = xmlnode_new("abort"); |
| 441 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
446 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 442 data->step = -1; |
447 data->step = -1; |
| 504 } |
511 } |
| 505 |
512 |
| 506 purple_debug_misc("jabber", "decoded success: %s\n", dec_in); |
513 purple_debug_misc("jabber", "decoded success: %s\n", dec_in); |
| 507 |
514 |
| 508 if (!jabber_scram_feed_parser(data, dec_in, &dec_out) || dec_out != NULL) { |
515 if (!jabber_scram_feed_parser(data, dec_in, &dec_out) || dec_out != NULL) { |
| |
516 g_free(dec_in); |
| 509 g_free(dec_out); |
517 g_free(dec_out); |
| 510 *error = g_strdup(_("Invalid challenge from server")); |
518 *error = g_strdup(_("Invalid challenge from server")); |
| 511 return JABBER_SASL_STATE_FAIL; |
519 return JABBER_SASL_STATE_FAIL; |
| 512 } |
520 } |
| 513 |
521 |
| |
522 g_free(dec_in); |
| 514 /* Hooray */ |
523 /* Hooray */ |
| 515 return JABBER_SASL_STATE_OK; |
524 return JABBER_SASL_STATE_OK; |
| 516 } |
525 } |
| 517 |
526 |
| 518 void jabber_scram_data_destroy(JabberScramData *data) |
527 void jabber_scram_data_destroy(JabberScramData *data) |