comparison libpurple/protocols/simple/simple.c @ 22925:4007d1a39da5

Patch from Will Hawkins to fix SIMPLE authentication on some servers. Fixes #4890.
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 13 May 2008 18:55:06 +0000
parents cc8903c59d6b
children 25161f5ea347
comparison
equal deleted inserted replaced
22924:f05da3bc20d9 22925:4007d1a39da5
307 static char *parse_attribute(const char *attrname, const char *source) { 307 static char *parse_attribute(const char *attrname, const char *source) {
308 const char *tmp, *tmp2; 308 const char *tmp, *tmp2;
309 char *retval = NULL; 309 char *retval = NULL;
310 int len = strlen(attrname); 310 int len = strlen(attrname);
311 311
312 /* we know that source is NULL-terminated.
313 * Therefore this loop won't be infinite.
314 */
315 while (source[0] == ' ')
316 source++;
317
312 if(!strncmp(source, attrname, len)) { 318 if(!strncmp(source, attrname, len)) {
313 tmp = source + len; 319 tmp = source + len;
314 tmp2 = g_strstr_len(tmp, strlen(tmp), "\""); 320 tmp2 = g_strstr_len(tmp, strlen(tmp), "\"");
315 if(tmp2) 321 if(tmp2)
316 retval = g_strndup(tmp, tmp2 - tmp); 322 retval = g_strndup(tmp, tmp2 - tmp);
339 } 345 }
340 346
341 if(!g_ascii_strncasecmp(hdr, "NTLM", 4)) { 347 if(!g_ascii_strncasecmp(hdr, "NTLM", 4)) {
342 purple_debug_info("simple", "found NTLM\n"); 348 purple_debug_info("simple", "found NTLM\n");
343 auth->type = 2; 349 auth->type = 2;
344 parts = g_strsplit(hdr+5, "\", ", 0); 350 parts = g_strsplit(hdr+5, "\",", 0);
345 i = 0; 351 i = 0;
346 while(parts[i]) { 352 while(parts[i]) {
347 purple_debug_info("simple", "parts[i] %s\n", parts[i]); 353 purple_debug_info("simple", "parts[i] %s\n", parts[i]);
348 if((tmp = parse_attribute("gssapi-data=\"", parts[i]))) { 354 if((tmp = parse_attribute("gssapi-data=\"", parts[i]))) {
349 auth->nonce = g_memdup(purple_ntlm_parse_type2(tmp, &auth->flags), 8); 355 auth->nonce = g_memdup(purple_ntlm_parse_type2(tmp, &auth->flags), 8);
366 auth->nc = 1; 372 auth->nc = 1;
367 if(!strstr(hdr, "gssapi-data")) { 373 if(!strstr(hdr, "gssapi-data")) {
368 auth->nc = 1; 374 auth->nc = 1;
369 } else { 375 } else {
370 auth->nc = 3; 376 auth->nc = 3;
371 } 377 }
378
372 return; 379 return;
373 } 380 } else if(!g_ascii_strncasecmp(hdr, "DIGEST", 6)) {
374 381
375 auth->type = 1; 382 purple_debug_info("simple", "found DIGEST\n");
376 parts = g_strsplit(hdr, " ", 0); 383
377 while(parts[i]) { 384 auth->type = 1;
378 if((tmp = parse_attribute("nonce=\"", parts[i]))) { 385 parts = g_strsplit(hdr+7, ",", 0);
379 auth->nonce = tmp; 386 while(parts[i]) {
380 } 387 if((tmp = parse_attribute("nonce=\"", parts[i]))) {
381 else if((tmp = parse_attribute("realm=\"", parts[i]))) { 388 auth->nonce = tmp;
382 auth->realm = tmp; 389 }
383 } 390 else if((tmp = parse_attribute("realm=\"", parts[i]))) {
384 i++; 391 auth->realm = tmp;
385 } 392 }
386 g_strfreev(parts); 393 i++;
387 394 }
388 purple_debug(PURPLE_DEBUG_MISC, "simple", "nonce: %s realm: %s\n", auth->nonce ? auth->nonce : "(null)", auth->realm ? auth->realm : "(null)"); 395 g_strfreev(parts);
389 if(auth->realm) { 396 purple_debug(PURPLE_DEBUG_MISC, "simple", "nonce: %s realm: %s\n",
390 auth->digest_session_key = purple_cipher_http_digest_calculate_session_key( 397 auth->nonce ? auth->nonce : "(null)",
398 auth->realm ? auth->realm : "(null)");
399
400 if(auth->realm) {
401 auth->digest_session_key = purple_cipher_http_digest_calculate_session_key(
391 "md5", authuser, auth->realm, sip->password, auth->nonce, NULL); 402 "md5", authuser, auth->realm, sip->password, auth->nonce, NULL);
392 403
393 auth->nc = 1; 404 auth->nc = 1;
394 } 405 }
406
407 } else {
408 purple_debug_error("simple", "Unsupported or bad WWW-Authenticate header (%s).\n", hdr);
409 }
410
395 } 411 }
396 412
397 static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition cond) { 413 static void simple_canwrite_cb(gpointer data, gint source, PurpleInputCondition cond) {
398 PurpleConnection *gc = data; 414 PurpleConnection *gc = data;
399 struct simple_account_data *sip = gc->proto_data; 415 struct simple_account_data *sip = gc->proto_data;