comparison libpurple/protocols/jabber/auth.c @ 15823:32c366eeeb99

sed -ie 's/gaim/purple/g'
author Sean Egan <seanegan@gmail.com>
date Mon, 19 Mar 2007 07:01:17 +0000
parents 51dd9ae01585
children 87ea711b9781
comparison
equal deleted inserted replaced
15822:84b0f9b23ede 15823:32c366eeeb99
1 /* 1 /*
2 * gaim - Jabber Protocol Plugin 2 * purple - Jabber Protocol Plugin
3 * 3 *
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> 4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
39 jabber_process_starttls(JabberStream *js, xmlnode *packet) 39 jabber_process_starttls(JabberStream *js, xmlnode *packet)
40 { 40 {
41 xmlnode *starttls; 41 xmlnode *starttls;
42 42
43 if((starttls = xmlnode_get_child(packet, "starttls"))) { 43 if((starttls = xmlnode_get_child(packet, "starttls"))) {
44 if(gaim_ssl_is_supported()) { 44 if(purple_ssl_is_supported()) {
45 jabber_send_raw(js, 45 jabber_send_raw(js,
46 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); 46 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1);
47 return TRUE; 47 return TRUE;
48 } else if(xmlnode_get_child(starttls, "required")) { 48 } else if(xmlnode_get_child(starttls, "required")) {
49 gaim_connection_error(js->gc, _("Server requires TLS/SSL for login. No TLS/SSL support found.")); 49 purple_connection_error(js->gc, _("Server requires TLS/SSL for login. No TLS/SSL support found."));
50 return TRUE; 50 return TRUE;
51 } 51 }
52 } 52 }
53 53
54 return FALSE; 54 return FALSE;
70 response = g_string_new(""); 70 response = g_string_new("");
71 response = g_string_append_len(response, "\0", 1); 71 response = g_string_append_len(response, "\0", 1);
72 response = g_string_append(response, js->user->node); 72 response = g_string_append(response, js->user->node);
73 response = g_string_append_len(response, "\0", 1); 73 response = g_string_append_len(response, "\0", 1);
74 response = g_string_append(response, 74 response = g_string_append(response,
75 gaim_connection_get_password(js->gc)); 75 purple_connection_get_password(js->gc));
76 76
77 enc_out = gaim_base64_encode((guchar *)response->str, response->len); 77 enc_out = purple_base64_encode((guchar *)response->str, response->len);
78 78
79 xmlnode_set_attrib(auth, "mechanism", "PLAIN"); 79 xmlnode_set_attrib(auth, "mechanism", "PLAIN");
80 xmlnode_insert_data(auth, enc_out, -1); 80 xmlnode_insert_data(auth, enc_out, -1);
81 g_free(enc_out); 81 g_free(enc_out);
82 g_string_free(response, TRUE); 82 g_string_free(response, TRUE);
92 x = xmlnode_new_child(query, "username"); 92 x = xmlnode_new_child(query, "username");
93 xmlnode_insert_data(x, js->user->node, -1); 93 xmlnode_insert_data(x, js->user->node, -1);
94 x = xmlnode_new_child(query, "resource"); 94 x = xmlnode_new_child(query, "resource");
95 xmlnode_insert_data(x, js->user->resource, -1); 95 xmlnode_insert_data(x, js->user->resource, -1);
96 x = xmlnode_new_child(query, "password"); 96 x = xmlnode_new_child(query, "password");
97 xmlnode_insert_data(x, gaim_connection_get_password(js->gc), -1); 97 xmlnode_insert_data(x, purple_connection_get_password(js->gc), -1);
98 jabber_iq_set_callback(iq, auth_old_result_cb, NULL); 98 jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
99 jabber_iq_send(iq); 99 jabber_iq_send(iq);
100 } 100 }
101 } 101 }
102 102
103 static void allow_plaintext_auth(GaimAccount *account) 103 static void allow_plaintext_auth(PurpleAccount *account)
104 { 104 {
105 gaim_account_set_bool(account, "auth_plain_in_clear", TRUE); 105 purple_account_set_bool(account, "auth_plain_in_clear", TRUE);
106 106
107 finish_plaintext_authentication(account->gc->proto_data); 107 finish_plaintext_authentication(account->gc->proto_data);
108 } 108 }
109 109
110 static void disallow_plaintext_auth(GaimAccount *account) 110 static void disallow_plaintext_auth(PurpleAccount *account)
111 { 111 {
112 gaim_connection_error(account->gc, _("Server requires plaintext authentication over an unencrypted stream")); 112 purple_connection_error(account->gc, _("Server requires plaintext authentication over an unencrypted stream"));
113 } 113 }
114 114
115 #ifdef HAVE_CYRUS_SASL 115 #ifdef HAVE_CYRUS_SASL
116 116
117 static void jabber_auth_start_cyrus(JabberStream *); 117 static void jabber_auth_start_cyrus(JabberStream *);
148 } 148 }
149 149
150 static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secret_t **secret) 150 static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secret_t **secret)
151 { 151 {
152 JabberStream *js = (JabberStream *)ctx; 152 JabberStream *js = (JabberStream *)ctx;
153 const char *pw = gaim_account_get_password(js->gc->account); 153 const char *pw = purple_account_get_password(js->gc->account);
154 size_t len; 154 size_t len;
155 static sasl_secret_t *x = NULL; 155 static sasl_secret_t *x = NULL;
156 156
157 if (!conn || !secret || id != SASL_CB_PASS) 157 if (!conn || !secret || id != SASL_CB_PASS)
158 return SASL_BADPARAM; 158 return SASL_BADPARAM;
168 168
169 *secret = x; 169 *secret = x;
170 return SASL_OK; 170 return SASL_OK;
171 } 171 }
172 172
173 static void allow_cyrus_plaintext_auth(GaimAccount *account) 173 static void allow_cyrus_plaintext_auth(PurpleAccount *account)
174 { 174 {
175 gaim_account_set_bool(account, "auth_plain_in_clear", TRUE); 175 purple_account_set_bool(account, "auth_plain_in_clear", TRUE);
176 176
177 jabber_auth_start_cyrus(account->gc->proto_data); 177 jabber_auth_start_cyrus(account->gc->proto_data);
178 } 178 }
179 179
180 static void jabber_auth_start_cyrus(JabberStream *js) 180 static void jabber_auth_start_cyrus(JabberStream *js)
192 secprops.security_flags = SASL_SEC_NOANONYMOUS; 192 secprops.security_flags = SASL_SEC_NOANONYMOUS;
193 193
194 if (!js->gsc) { 194 if (!js->gsc) {
195 secprops.max_ssf = -1; 195 secprops.max_ssf = -1;
196 secprops.maxbufsize = 4096; 196 secprops.maxbufsize = 4096;
197 plaintext = gaim_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE); 197 plaintext = purple_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE);
198 if (!plaintext) 198 if (!plaintext)
199 secprops.security_flags |= SASL_SEC_NOPLAINTEXT; 199 secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
200 } else { 200 } else {
201 secprops.max_ssf = 0; 201 secprops.max_ssf = 0;
202 secprops.maxbufsize = 0; 202 secprops.maxbufsize = 0;
209 again = FALSE; 209 again = FALSE;
210 210
211 js->sasl_state = sasl_client_new("xmpp", js->serverFQDN, NULL, NULL, js->sasl_cb, 0, &js->sasl); 211 js->sasl_state = sasl_client_new("xmpp", js->serverFQDN, NULL, NULL, js->sasl_cb, 0, &js->sasl);
212 if (js->sasl_state==SASL_OK) { 212 if (js->sasl_state==SASL_OK) {
213 sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops); 213 sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops);
214 gaim_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str); 214 purple_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str);
215 js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &mech); 215 js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &mech);
216 } 216 }
217 switch (js->sasl_state) { 217 switch (js->sasl_state) {
218 /* Success */ 218 /* Success */
219 case SASL_OK: 219 case SASL_OK:
221 break; 221 break;
222 case SASL_NOMECH: 222 case SASL_NOMECH:
223 /* No mechanisms do what we want. See if we can add 223 /* No mechanisms do what we want. See if we can add
224 * plaintext ones to the list. */ 224 * plaintext ones to the list. */
225 225
226 if (!gaim_account_get_password(js->gc->account)) { 226 if (!purple_account_get_password(js->gc->account)) {
227 gaim_connection_error(js->gc, _("Server couldn't authenticate you without a password")); 227 purple_connection_error(js->gc, _("Server couldn't authenticate you without a password"));
228 return; 228 return;
229 } else if (!plaintext) { 229 } else if (!plaintext) {
230 gaim_request_yes_no(js->gc, _("Plaintext Authentication"), 230 purple_request_yes_no(js->gc, _("Plaintext Authentication"),
231 _("Plaintext Authentication"), 231 _("Plaintext Authentication"),
232 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), 232 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
233 2, js->gc->account, 233 2, js->gc->account,
234 allow_cyrus_plaintext_auth, 234 allow_cyrus_plaintext_auth,
235 disallow_plaintext_auth); 235 disallow_plaintext_auth);
236 return; 236 return;
237 } else { 237 } else {
238 gaim_connection_error(js->gc, _("Server does not use any supported authentication method")); 238 purple_connection_error(js->gc, _("Server does not use any supported authentication method"));
239 return; 239 return;
240 } 240 }
241 /* not reached */ 241 /* not reached */
242 break; 242 break;
243 243
246 case SASL_NOMEM: 246 case SASL_NOMEM:
247 break; 247 break;
248 248
249 /* For everything else, fail the mechanism and try again */ 249 /* For everything else, fail the mechanism and try again */
250 default: 250 default:
251 gaim_debug_info("sasl", "sasl_state is %d, failing the mech and trying again\n", js->sasl_state); 251 purple_debug_info("sasl", "sasl_state is %d, failing the mech and trying again\n", js->sasl_state);
252 252
253 /* 253 /*
254 * DAA: is this right? 254 * DAA: is this right?
255 * The manpage says that "mech" will contain the chosen mechanism on success. 255 * The manpage says that "mech" will contain the chosen mechanism on success.
256 * Presumably, if we get here that isn't the case and we shouldn't try again? 256 * Presumably, if we get here that isn't the case and we shouldn't try again?
280 xmlnode_set_attrib(auth, "mechanism", mech); 280 xmlnode_set_attrib(auth, "mechanism", mech);
281 if (clientout) { 281 if (clientout) {
282 if (coutlen == 0) { 282 if (coutlen == 0) {
283 xmlnode_insert_data(auth, "=", -1); 283 xmlnode_insert_data(auth, "=", -1);
284 } else { 284 } else {
285 enc_out = gaim_base64_encode((unsigned char*)clientout, coutlen); 285 enc_out = purple_base64_encode((unsigned char*)clientout, coutlen);
286 xmlnode_insert_data(auth, enc_out, -1); 286 xmlnode_insert_data(auth, enc_out, -1);
287 g_free(enc_out); 287 g_free(enc_out);
288 } 288 }
289 } 289 }
290 jabber_send(js, auth); 290 jabber_send(js, auth);
291 xmlnode_free(auth); 291 xmlnode_free(auth);
292 } else { 292 } else {
293 gaim_connection_error(js->gc, "SASL authentication failed\n"); 293 purple_connection_error(js->gc, "SASL authentication failed\n");
294 } 294 }
295 } 295 }
296 296
297 static int 297 static int
298 jabber_sasl_cb_log(void *context, int level, const char *message) 298 jabber_sasl_cb_log(void *context, int level, const char *message)
299 { 299 {
300 if(level <= SASL_LOG_TRACE) 300 if(level <= SASL_LOG_TRACE)
301 gaim_debug_info("sasl", "%s\n", message); 301 purple_debug_info("sasl", "%s\n", message);
302 302
303 return SASL_OK; 303 return SASL_OK;
304 } 304 }
305 305
306 #endif 306 #endif
323 } 323 }
324 324
325 mechs = xmlnode_get_child(packet, "mechanisms"); 325 mechs = xmlnode_get_child(packet, "mechanisms");
326 326
327 if(!mechs) { 327 if(!mechs) {
328 gaim_connection_error(js->gc, _("Invalid response from server.")); 328 purple_connection_error(js->gc, _("Invalid response from server."));
329 return; 329 return;
330 } 330 }
331 331
332 #ifdef HAVE_CYRUS_SASL 332 #ifdef HAVE_CYRUS_SASL
333 js->sasl_mechs = g_string_new(""); 333 js->sasl_mechs = g_string_new("");
369 js->sasl_cb[id].id = SASL_CB_USER; 369 js->sasl_cb[id].id = SASL_CB_USER;
370 js->sasl_cb[id].proc = jabber_sasl_cb_simple; 370 js->sasl_cb[id].proc = jabber_sasl_cb_simple;
371 js->sasl_cb[id].context = (void *)js; 371 js->sasl_cb[id].context = (void *)js;
372 id++; 372 id++;
373 373
374 if (gaim_account_get_password(js->gc->account)) { 374 if (purple_account_get_password(js->gc->account)) {
375 js->sasl_cb[id].id = SASL_CB_PASS; 375 js->sasl_cb[id].id = SASL_CB_PASS;
376 js->sasl_cb[id].proc = jabber_sasl_cb_secret; 376 js->sasl_cb[id].proc = jabber_sasl_cb_secret;
377 js->sasl_cb[id].context = (void *)js; 377 js->sasl_cb[id].context = (void *)js;
378 id++; 378 id++;
379 } 379 }
399 jabber_send(js, auth); 399 jabber_send(js, auth);
400 xmlnode_free(auth); 400 xmlnode_free(auth);
401 } else if(plain) { 401 } else if(plain) {
402 js->auth_type = JABBER_AUTH_PLAIN; 402 js->auth_type = JABBER_AUTH_PLAIN;
403 403
404 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE)) { 404 if(js->gsc == NULL && !purple_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE)) {
405 gaim_request_yes_no(js->gc, _("Plaintext Authentication"), 405 purple_request_yes_no(js->gc, _("Plaintext Authentication"),
406 _("Plaintext Authentication"), 406 _("Plaintext Authentication"),
407 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), 407 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
408 2, js->gc->account, allow_plaintext_auth, 408 2, js->gc->account, allow_plaintext_auth,
409 disallow_plaintext_auth); 409 disallow_plaintext_auth);
410 return; 410 return;
411 } 411 }
412 finish_plaintext_authentication(js); 412 finish_plaintext_authentication(js);
413 } else { 413 } else {
414 gaim_connection_error(js->gc, 414 purple_connection_error(js->gc,
415 _("Server does not use any supported authentication method")); 415 _("Server does not use any supported authentication method"));
416 } 416 }
417 #endif 417 #endif
418 } 418 }
419 419
432 (err_code = xmlnode_get_attrib(error, "code")) && 432 (err_code = xmlnode_get_attrib(error, "code")) &&
433 !strcmp(err_code, "401")) { 433 !strcmp(err_code, "401")) {
434 js->gc->wants_to_die = TRUE; 434 js->gc->wants_to_die = TRUE;
435 } 435 }
436 436
437 gaim_connection_error(js->gc, msg); 437 purple_connection_error(js->gc, msg);
438 g_free(msg); 438 g_free(msg);
439 } 439 }
440 } 440 }
441 441
442 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data) 442 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data)
443 { 443 {
444 JabberIq *iq; 444 JabberIq *iq;
445 xmlnode *query, *x; 445 xmlnode *query, *x;
446 const char *type = xmlnode_get_attrib(packet, "type"); 446 const char *type = xmlnode_get_attrib(packet, "type");
447 const char *pw = gaim_connection_get_password(js->gc); 447 const char *pw = purple_connection_get_password(js->gc);
448 448
449 if(!type) { 449 if(!type) {
450 gaim_connection_error(js->gc, _("Invalid response from server.")); 450 purple_connection_error(js->gc, _("Invalid response from server."));
451 return; 451 return;
452 } else if(!strcmp(type, "error")) { 452 } else if(!strcmp(type, "error")) {
453 char *msg = jabber_parse_error(js, packet); 453 char *msg = jabber_parse_error(js, packet);
454 gaim_connection_error(js->gc, msg); 454 purple_connection_error(js->gc, msg);
455 g_free(msg); 455 g_free(msg);
456 } else if(!strcmp(type, "result")) { 456 } else if(!strcmp(type, "result")) {
457 query = xmlnode_get_child(packet, "query"); 457 query = xmlnode_get_child(packet, "query");
458 if(js->stream_id && xmlnode_get_child(query, "digest")) { 458 if(js->stream_id && xmlnode_get_child(query, "digest")) {
459 unsigned char hashval[20]; 459 unsigned char hashval[20];
468 xmlnode_insert_data(x, js->user->resource, -1); 468 xmlnode_insert_data(x, js->user->resource, -1);
469 469
470 x = xmlnode_new_child(query, "digest"); 470 x = xmlnode_new_child(query, "digest");
471 s = g_strdup_printf("%s%s", js->stream_id, pw); 471 s = g_strdup_printf("%s%s", js->stream_id, pw);
472 472
473 gaim_cipher_digest_region("sha1", (guchar *)s, strlen(s), 473 purple_cipher_digest_region("sha1", (guchar *)s, strlen(s),
474 sizeof(hashval), hashval, NULL); 474 sizeof(hashval), hashval, NULL);
475 475
476 p = h; 476 p = h;
477 for(i=0; i<20; i++, p+=2) 477 for(i=0; i<20; i++, p+=2)
478 snprintf(p, 3, "%02x", hashval[i]); 478 snprintf(p, 3, "%02x", hashval[i]);
480 g_free(s); 480 g_free(s);
481 jabber_iq_set_callback(iq, auth_old_result_cb, NULL); 481 jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
482 jabber_iq_send(iq); 482 jabber_iq_send(iq);
483 483
484 } else if(xmlnode_get_child(query, "password")) { 484 } else if(xmlnode_get_child(query, "password")) {
485 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, 485 if(js->gsc == NULL && !purple_account_get_bool(js->gc->account,
486 "auth_plain_in_clear", FALSE)) { 486 "auth_plain_in_clear", FALSE)) {
487 gaim_request_yes_no(js->gc, _("Plaintext Authentication"), 487 purple_request_yes_no(js->gc, _("Plaintext Authentication"),
488 _("Plaintext Authentication"), 488 _("Plaintext Authentication"),
489 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), 489 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
490 2, js->gc->account, allow_plaintext_auth, 490 2, js->gc->account, allow_plaintext_auth,
491 disallow_plaintext_auth); 491 disallow_plaintext_auth);
492 return; 492 return;
493 } 493 }
494 finish_plaintext_authentication(js); 494 finish_plaintext_authentication(js);
495 } else { 495 } else {
496 gaim_connection_error(js->gc, 496 purple_connection_error(js->gc,
497 _("Server does not use any supported authentication method")); 497 _("Server does not use any supported authentication method"));
498 return; 498 return;
499 } 499 }
500 } 500 }
501 } 501 }
543 543
544 static char * 544 static char *
545 generate_response_value(JabberID *jid, const char *passwd, const char *nonce, 545 generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
546 const char *cnonce, const char *a2, const char *realm) 546 const char *cnonce, const char *a2, const char *realm)
547 { 547 {
548 GaimCipher *cipher; 548 PurpleCipher *cipher;
549 GaimCipherContext *context; 549 PurpleCipherContext *context;
550 guchar result[16]; 550 guchar result[16];
551 size_t a1len; 551 size_t a1len;
552 552
553 gchar *a1, *convnode=NULL, *convpasswd = NULL, *ha1, *ha2, *kd, *x, *z; 553 gchar *a1, *convnode=NULL, *convpasswd = NULL, *ha1, *ha2, *kd, *x, *z;
554 554
559 if(passwd && ((convpasswd = g_convert(passwd, strlen(passwd), "iso-8859-1", 559 if(passwd && ((convpasswd = g_convert(passwd, strlen(passwd), "iso-8859-1",
560 "utf-8", NULL, NULL, NULL)) == NULL)) { 560 "utf-8", NULL, NULL, NULL)) == NULL)) {
561 convpasswd = g_strdup(passwd); 561 convpasswd = g_strdup(passwd);
562 } 562 }
563 563
564 cipher = gaim_ciphers_find_cipher("md5"); 564 cipher = purple_ciphers_find_cipher("md5");
565 context = gaim_cipher_context_new(cipher, NULL); 565 context = purple_cipher_context_new(cipher, NULL);
566 566
567 x = g_strdup_printf("%s:%s:%s", convnode, realm, convpasswd ? convpasswd : ""); 567 x = g_strdup_printf("%s:%s:%s", convnode, realm, convpasswd ? convpasswd : "");
568 gaim_cipher_context_append(context, (const guchar *)x, strlen(x)); 568 purple_cipher_context_append(context, (const guchar *)x, strlen(x));
569 gaim_cipher_context_digest(context, sizeof(result), result, NULL); 569 purple_cipher_context_digest(context, sizeof(result), result, NULL);
570 570
571 a1 = g_strdup_printf("xxxxxxxxxxxxxxxx:%s:%s", nonce, cnonce); 571 a1 = g_strdup_printf("xxxxxxxxxxxxxxxx:%s:%s", nonce, cnonce);
572 a1len = strlen(a1); 572 a1len = strlen(a1);
573 g_memmove(a1, result, 16); 573 g_memmove(a1, result, 16);
574 574
575 gaim_cipher_context_reset(context, NULL); 575 purple_cipher_context_reset(context, NULL);
576 gaim_cipher_context_append(context, (const guchar *)a1, a1len); 576 purple_cipher_context_append(context, (const guchar *)a1, a1len);
577 gaim_cipher_context_digest(context, sizeof(result), result, NULL); 577 purple_cipher_context_digest(context, sizeof(result), result, NULL);
578 578
579 ha1 = gaim_base16_encode(result, 16); 579 ha1 = purple_base16_encode(result, 16);
580 580
581 gaim_cipher_context_reset(context, NULL); 581 purple_cipher_context_reset(context, NULL);
582 gaim_cipher_context_append(context, (const guchar *)a2, strlen(a2)); 582 purple_cipher_context_append(context, (const guchar *)a2, strlen(a2));
583 gaim_cipher_context_digest(context, sizeof(result), result, NULL); 583 purple_cipher_context_digest(context, sizeof(result), result, NULL);
584 584
585 ha2 = gaim_base16_encode(result, 16); 585 ha2 = purple_base16_encode(result, 16);
586 586
587 kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2); 587 kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2);
588 588
589 gaim_cipher_context_reset(context, NULL); 589 purple_cipher_context_reset(context, NULL);
590 gaim_cipher_context_append(context, (const guchar *)kd, strlen(kd)); 590 purple_cipher_context_append(context, (const guchar *)kd, strlen(kd));
591 gaim_cipher_context_digest(context, sizeof(result), result, NULL); 591 purple_cipher_context_digest(context, sizeof(result), result, NULL);
592 gaim_cipher_context_destroy(context); 592 purple_cipher_context_destroy(context);
593 593
594 z = gaim_base16_encode(result, 16); 594 z = purple_base16_encode(result, 16);
595 595
596 g_free(convnode); 596 g_free(convnode);
597 g_free(convpasswd); 597 g_free(convpasswd);
598 g_free(x); 598 g_free(x);
599 g_free(a1); 599 g_free(a1);
613 char *dec_in; 613 char *dec_in;
614 char *enc_out; 614 char *enc_out;
615 GHashTable *parts; 615 GHashTable *parts;
616 616
617 if(!enc_in) { 617 if(!enc_in) {
618 gaim_connection_error(js->gc, _("Invalid response from server.")); 618 purple_connection_error(js->gc, _("Invalid response from server."));
619 return; 619 return;
620 } 620 }
621 621
622 dec_in = (char *)gaim_base64_decode(enc_in, NULL); 622 dec_in = (char *)purple_base64_decode(enc_in, NULL);
623 gaim_debug(GAIM_DEBUG_MISC, "jabber", "decoded challenge (%d): %s\n", 623 purple_debug(PURPLE_DEBUG_MISC, "jabber", "decoded challenge (%d): %s\n",
624 strlen(dec_in), dec_in); 624 strlen(dec_in), dec_in);
625 625
626 parts = parse_challenge(dec_in); 626 parts = parse_challenge(dec_in);
627 627
628 628
634 !strcmp(rspauth, js->expected_rspauth)) { 634 !strcmp(rspauth, js->expected_rspauth)) {
635 jabber_send_raw(js, 635 jabber_send_raw(js,
636 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />", 636 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />",
637 -1); 637 -1);
638 } else { 638 } else {
639 gaim_connection_error(js->gc, _("Invalid challenge from server")); 639 purple_connection_error(js->gc, _("Invalid challenge from server"));
640 } 640 }
641 g_free(js->expected_rspauth); 641 g_free(js->expected_rspauth);
642 } else { 642 } else {
643 /* assemble a response, and send it */ 643 /* assemble a response, and send it */
644 /* see RFC 2831 */ 644 /* see RFC 2831 */
663 nonce = g_hash_table_lookup(parts, "nonce"); 663 nonce = g_hash_table_lookup(parts, "nonce");
664 664
665 665
666 a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm); 666 a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm);
667 auth_resp = generate_response_value(js->user, 667 auth_resp = generate_response_value(js->user,
668 gaim_connection_get_password(js->gc), nonce, cnonce, a2, realm); 668 purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
669 g_free(a2); 669 g_free(a2);
670 670
671 a2 = g_strdup_printf(":xmpp/%s", realm); 671 a2 = g_strdup_printf(":xmpp/%s", realm);
672 js->expected_rspauth = generate_response_value(js->user, 672 js->expected_rspauth = generate_response_value(js->user,
673 gaim_connection_get_password(js->gc), nonce, cnonce, a2, realm); 673 purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
674 g_free(a2); 674 g_free(a2);
675 675
676 676
677 g_string_append_printf(response, "username=\"%s\"", js->user->node); 677 g_string_append_printf(response, "username=\"%s\"", js->user->node);
678 g_string_append_printf(response, ",realm=\"%s\"", realm); 678 g_string_append_printf(response, ",realm=\"%s\"", realm);
685 g_string_append_printf(response, ",charset=utf-8"); 685 g_string_append_printf(response, ",charset=utf-8");
686 686
687 g_free(auth_resp); 687 g_free(auth_resp);
688 g_free(cnonce); 688 g_free(cnonce);
689 689
690 enc_out = gaim_base64_encode((guchar *)response->str, response->len); 690 enc_out = purple_base64_encode((guchar *)response->str, response->len);
691 691
692 gaim_debug(GAIM_DEBUG_MISC, "jabber", "decoded response (%d): %s\n", response->len, response->str); 692 purple_debug(PURPLE_DEBUG_MISC, "jabber", "decoded response (%d): %s\n", response->len, response->str);
693 693
694 buf = g_strdup_printf("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>", enc_out); 694 buf = g_strdup_printf("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>", enc_out);
695 695
696 jabber_send_raw(js, buf, -1); 696 jabber_send_raw(js, buf, -1);
697 697
714 const char *c_out; 714 const char *c_out;
715 unsigned int clen; 715 unsigned int clen;
716 gsize declen; 716 gsize declen;
717 xmlnode *response; 717 xmlnode *response;
718 718
719 dec_in = gaim_base64_decode(enc_in, &declen); 719 dec_in = purple_base64_decode(enc_in, &declen);
720 720
721 js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen, 721 js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen,
722 NULL, &c_out, &clen); 722 NULL, &c_out, &clen);
723 g_free(enc_in); 723 g_free(enc_in);
724 g_free(dec_in); 724 g_free(dec_in);
725 if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) { 725 if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) {
726 gaim_debug_error("jabber", "Error is %d : %s\n",js->sasl_state,sasl_errdetail(js->sasl)); 726 purple_debug_error("jabber", "Error is %d : %s\n",js->sasl_state,sasl_errdetail(js->sasl));
727 gaim_connection_error(js->gc, _("SASL error")); 727 purple_connection_error(js->gc, _("SASL error"));
728 return; 728 return;
729 } else { 729 } else {
730 response = xmlnode_new("response"); 730 response = xmlnode_new("response");
731 xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl"); 731 xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl");
732 if (c_out) { 732 if (c_out) {
733 enc_out = gaim_base64_encode((unsigned char*)c_out, clen); 733 enc_out = purple_base64_encode((unsigned char*)c_out, clen);
734 xmlnode_insert_data(response, enc_out, -1); 734 xmlnode_insert_data(response, enc_out, -1);
735 g_free(enc_out); 735 g_free(enc_out);
736 } 736 }
737 jabber_send(js, response); 737 jabber_send(js, response);
738 xmlnode_free(response); 738 xmlnode_free(response);
747 #ifdef HAVE_CYRUS_SASL 747 #ifdef HAVE_CYRUS_SASL
748 const int *x; 748 const int *x;
749 #endif 749 #endif
750 750
751 if(!ns || strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) { 751 if(!ns || strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) {
752 gaim_connection_error(js->gc, _("Invalid response from server.")); 752 purple_connection_error(js->gc, _("Invalid response from server."));
753 return; 753 return;
754 } 754 }
755 755
756 #ifdef HAVE_CYRUS_SASL 756 #ifdef HAVE_CYRUS_SASL
757 /* The SASL docs say that if the client hasn't returned OK yet, we 757 /* The SASL docs say that if the client hasn't returned OK yet, we
763 const char *c_out; 763 const char *c_out;
764 unsigned int clen; 764 unsigned int clen;
765 gsize declen = 0; 765 gsize declen = 0;
766 766
767 if(enc_in != NULL) 767 if(enc_in != NULL)
768 dec_in = gaim_base64_decode(enc_in, &declen); 768 dec_in = purple_base64_decode(enc_in, &declen);
769 769
770 js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen, NULL, &c_out, &clen); 770 js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen, NULL, &c_out, &clen);
771 771
772 g_free(enc_in); 772 g_free(enc_in);
773 g_free(dec_in); 773 g_free(dec_in);
774 774
775 if (js->sasl_state != SASL_OK) { 775 if (js->sasl_state != SASL_OK) {
776 /* This should never happen! */ 776 /* This should never happen! */
777 gaim_connection_error(js->gc, _("Invalid response from server.")); 777 purple_connection_error(js->gc, _("Invalid response from server."));
778 } 778 }
779 } 779 }
780 /* If we've negotiated a security layer, we need to enable it */ 780 /* If we've negotiated a security layer, we need to enable it */
781 sasl_getprop(js->sasl, SASL_SSF, &x); 781 sasl_getprop(js->sasl, SASL_SSF, &x);
782 if (*x > 0) { 782 if (*x > 0) {
791 void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet) 791 void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet)
792 { 792 {
793 char *msg = jabber_parse_error(js, packet); 793 char *msg = jabber_parse_error(js, packet);
794 794
795 if(!msg) { 795 if(!msg) {
796 gaim_connection_error(js->gc, _("Invalid response from server.")); 796 purple_connection_error(js->gc, _("Invalid response from server."));
797 } else { 797 } else {
798 gaim_connection_error(js->gc, msg); 798 purple_connection_error(js->gc, msg);
799 g_free(msg); 799 g_free(msg);
800 } 800 }
801 } 801 }