| 385 data->cnonce); |
385 data->cnonce); |
| 386 |
386 |
| 387 data->step = 1; |
387 data->step = 1; |
| 388 |
388 |
| 389 reply = xmlnode_new("auth"); |
389 reply = xmlnode_new("auth"); |
| 390 xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl"); |
390 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 391 xmlnode_set_attrib(reply, "mechanism", js->auth_mech->name); |
391 xmlnode_set_attrib(reply, "mechanism", js->auth_mech->name); |
| 392 |
392 |
| 393 /* TODO: Channel binding */ |
393 /* TODO: Channel binding */ |
| 394 dec_out = g_strdup_printf("%c,,%s", 'n', data->auth_message->str); |
394 dec_out = g_strdup_printf("%c,,%s", 'n', data->auth_message->str); |
| 395 enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out)); |
395 enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out)); |
| 412 gsize len; |
412 gsize len; |
| 413 |
413 |
| 414 enc_in = xmlnode_get_data(challenge); |
414 enc_in = xmlnode_get_data(challenge); |
| 415 if (!enc_in || *enc_in == '\0') { |
415 if (!enc_in || *enc_in == '\0') { |
| 416 reply = xmlnode_new("abort"); |
416 reply = xmlnode_new("abort"); |
| 417 xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl"); |
417 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 418 data->step = -1; |
418 data->step = -1; |
| 419 goto out; |
419 goto out; |
| 420 } |
420 } |
| 421 |
421 |
| 422 dec_in = (gchar *)purple_base64_decode(enc_in, &len); |
422 dec_in = (gchar *)purple_base64_decode(enc_in, &len); |
| 423 g_free(enc_in); |
423 g_free(enc_in); |
| 424 if (!dec_in || len != strlen(dec_in)) { |
424 if (!dec_in || len != strlen(dec_in)) { |
| 425 /* Danger afoot; SCRAM shouldn't contain NUL bytes */ |
425 /* Danger afoot; SCRAM shouldn't contain NUL bytes */ |
| 426 reply = xmlnode_new("abort"); |
426 reply = xmlnode_new("abort"); |
| 427 xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl"); |
427 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 428 data->step = -1; |
428 data->step = -1; |
| 429 goto out; |
429 goto out; |
| 430 } |
430 } |
| 431 |
431 |
| 432 purple_debug_misc("jabber", "decoded challenge: %s\n", dec_in); |
432 purple_debug_misc("jabber", "decoded challenge: %s\n", dec_in); |
| 433 |
433 |
| 434 if (!jabber_scram_feed_parser(data, dec_in, &dec_out)) { |
434 if (!jabber_scram_feed_parser(data, dec_in, &dec_out)) { |
| 435 reply = xmlnode_new("abort"); |
435 reply = xmlnode_new("abort"); |
| 436 xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl"); |
436 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 437 data->step = -1; |
437 data->step = -1; |
| 438 goto out; |
438 goto out; |
| 439 } |
439 } |
| 440 |
440 |
| 441 data->step += 1; |
441 data->step += 1; |
| 442 |
442 |
| 443 reply = xmlnode_new("response"); |
443 reply = xmlnode_new("response"); |
| 444 xmlnode_set_namespace(reply, "urn:ietf:params:xml:ns:xmpp-sasl"); |
444 xmlnode_set_namespace(reply, NS_XMPP_SASL); |
| 445 |
445 |
| 446 purple_debug_misc("jabber", "decoded response: %s\n", dec_out ? dec_out : "(null)"); |
446 purple_debug_misc("jabber", "decoded response: %s\n", dec_out ? dec_out : "(null)"); |
| 447 if (dec_out) { |
447 if (dec_out) { |
| 448 enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out)); |
448 enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out)); |
| 449 xmlnode_insert_data(reply, enc_out, -1); |
449 xmlnode_insert_data(reply, enc_out, -1); |