Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/msnutils.c @ 23541:54f7e507ea7d
Fix calculating the response to MSN Challenge strings that are an exact
multiple of 8 characters long. This seems to happen sporadically when
sending OIM's.
Also, clean up the mess that is msn_handle_chl. No more 2-tab indent,
more consistent whitespace, and broke up some really long lines. Made
reference to the wiki on imfreedom.org instead of msnpiki, since it's
newer and I re-wrote it ;)
References #5379.
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sun, 22 Jun 2008 01:52:04 +0000 |
parents | 1ac5faa72c8d |
children | 7bceac816e19 |
comparison
equal
deleted
inserted
replaced
23540:0fc1d2df836e | 23541:54f7e507ea7d |
---|---|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
23 */ | 23 */ |
24 #include "msn.h" | 24 #include "msn.h" |
25 #include "msnutils.h" | 25 #include "msnutils.h" |
26 #include "time.h" | 26 #include "time.h" |
27 //#include <openssl/md5.h> | 27 |
28 #include "cipher.h" | |
28 | 29 |
29 char *rand_guid(void); | 30 char *rand_guid(void); |
30 | 31 |
31 /************************************************************************** | 32 /************************************************************************** |
32 * Util | 33 * Util |
463 char *c; | 464 char *c; |
464 int port; | 465 int port; |
465 | 466 |
466 host = g_strdup(str); | 467 host = g_strdup(str); |
467 | 468 |
468 if ((c = strchr(host, ':')) != NULL){ | 469 if ((c = strchr(host, ':')) != NULL) { |
469 *c = '\0'; | 470 *c = '\0'; |
470 port = atoi(c + 1); | 471 port = atoi(c + 1); |
471 }else{ | 472 } else { |
472 port = 1863; | 473 port = 1863; |
473 } | 474 } |
474 | 475 |
475 *ret_host = host; | 476 *ret_host = host; |
476 *ret_port = port; | 477 *ret_port = port; |
503 /*************************************************************************** | 504 /*************************************************************************** |
504 * MSN Challenge Computing Function | 505 * MSN Challenge Computing Function |
505 ***************************************************************************/ | 506 ***************************************************************************/ |
506 | 507 |
507 /* | 508 /* |
508 * Handle MSN Chanllege computation | 509 * Handle MSN Challenge computation |
509 *This algorithm reference with http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges | 510 * This algorithm references |
511 * http://imfreedom.org/wiki/index.php/MSN:NS/Challenges | |
510 */ | 512 */ |
511 #define BUFSIZE 256 | 513 #define BUFSIZE 256 |
512 void | 514 void |
513 msn_handle_chl(char *input, char *output) | 515 msn_handle_chl(char *input, char *output) |
514 { | 516 { |
515 PurpleCipher *cipher; | 517 PurpleCipher *cipher; |
516 PurpleCipherContext *context; | 518 PurpleCipherContext *context; |
517 char *productKey = MSNP15_WLM_PRODUCT_KEY, | 519 const guchar productKey[] = MSNP15_WLM_PRODUCT_KEY; |
518 *productID = MSNP15_WLM_PRODUCT_ID, | 520 const guchar productID[] = MSNP15_WLM_PRODUCT_ID; |
519 *hexChars = "0123456789abcdef", | 521 const char hexChars[] = "0123456789abcdef"; |
520 buf[BUFSIZE]; | 522 char buf[BUFSIZE]; |
521 unsigned char md5Hash[16], *newHash; | 523 unsigned char md5Hash[16]; |
522 unsigned int *md5Parts, *chlStringParts, newHashParts[5]; | 524 unsigned char *newHash; |
523 | 525 unsigned int *md5Parts; |
524 long long nHigh=0, nLow=0; | 526 unsigned int *chlStringParts; |
525 | 527 unsigned int newHashParts[5]; |
526 int i; | 528 |
527 | 529 long long nHigh = 0, nLow = 0; |
528 /* Create the MD5 hash by using Purple MD5 algorithm*/ | 530 |
529 cipher = purple_ciphers_find_cipher("md5"); | 531 int len; |
530 context = purple_cipher_context_new(cipher, NULL); | 532 int i; |
531 | 533 |
532 purple_cipher_context_append(context, (const guchar *)input, | 534 /* Create the MD5 hash by using Purple MD5 algorithm */ |
533 strlen(input)); | 535 cipher = purple_ciphers_find_cipher("md5"); |
534 purple_cipher_context_append(context, (const guchar *)productKey, | 536 context = purple_cipher_context_new(cipher, NULL); |
535 strlen(productKey)); | 537 |
536 purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL); | 538 purple_cipher_context_append(context, (guchar *)input, strlen(input)); |
537 purple_cipher_context_destroy(context); | 539 purple_cipher_context_append(context, productKey, sizeof(productKey) - 1); |
538 | 540 purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL); |
539 /* Split it into four integers */ | 541 purple_cipher_context_destroy(context); |
540 md5Parts = (unsigned int *)md5Hash; | 542 |
541 for(i=0; i<4; i++){ | 543 /* Split it into four integers */ |
542 /* adjust endianess */ | 544 md5Parts = (unsigned int *)md5Hash; |
543 md5Parts[i] = GUINT_TO_LE(md5Parts[i]); | 545 for (i = 0; i < 4; i++) { |
544 | 546 /* adjust endianess */ |
545 /* & each integer with 0x7FFFFFFF */ | 547 md5Parts[i] = GUINT_TO_LE(md5Parts[i]); |
546 /* and save one unmodified array for later */ | 548 |
547 newHashParts[i] = md5Parts[i]; | 549 /* & each integer with 0x7FFFFFFF */ |
548 md5Parts[i] &= 0x7FFFFFFF; | 550 /* and save one unmodified array for later */ |
549 } | 551 newHashParts[i] = md5Parts[i]; |
550 | 552 md5Parts[i] &= 0x7FFFFFFF; |
551 /* make a new string and pad with '0' */ | 553 } |
552 snprintf(buf, BUFSIZE-5, "%s%s", input, productID); | 554 |
553 i = strlen(buf); | 555 /* make a new string and pad with '0' to length that's a multiple of 8 */ |
554 memset(&buf[i], '0', 8 - (i % 8)); | 556 snprintf(buf, BUFSIZE - 5, "%s%s", input, productID); |
555 buf[i + (8 - (i % 8))]='\0'; | 557 len = strlen(buf); |
556 | 558 if ((len % 8) != 0) { |
557 /* split into integers */ | 559 int fix = 8 - (len % 8); |
558 chlStringParts = (unsigned int *)buf; | 560 memset(&buf[len], '0', fix); |
559 | 561 buf[len + fix] = '\0'; |
560 /* this is magic */ | 562 len += fix; |
561 for (i=0; i<(strlen(buf)/4)-1; i+=2){ | 563 } |
562 long long temp; | 564 |
563 | 565 /* split into integers */ |
564 chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]); | 566 chlStringParts = (unsigned int *)buf; |
565 chlStringParts[i+1] = GUINT_TO_LE(chlStringParts[i+1]); | 567 |
566 | 568 /* this is magic */ |
567 temp=(md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF; | 569 for (i = 0; i < (strlen(buf) / 4); i += 2) { |
568 nHigh=(md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF; | 570 long long temp; |
569 nLow=nLow + nHigh + temp; | 571 |
570 } | 572 chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]); |
571 nHigh=(nHigh+md5Parts[1]) % 0x7FFFFFFF; | 573 chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]); |
572 nLow=(nLow+md5Parts[3]) % 0x7FFFFFFF; | 574 |
573 | 575 temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF; |
574 newHashParts[0]^=nHigh; | 576 temp = (md5Parts[0] * (temp + nLow) + md5Parts[1]) % 0x7FFFFFFF; |
575 newHashParts[1]^=nLow; | 577 nHigh += temp; |
576 newHashParts[2]^=nHigh; | 578 |
577 newHashParts[3]^=nLow; | 579 temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF; |
578 | 580 nLow = (md5Parts[2] * temp + md5Parts[3]) % 0x7FFFFFFF; |
579 /* adjust endianness */ | 581 nHigh += nLow; |
580 for(i=0; i<4; i++) | 582 } |
581 newHashParts[i] = GUINT_TO_LE(newHashParts[i]); | 583 nLow = (nLow + md5Parts[1]) % 0x7FFFFFFF; |
582 | 584 nHigh = (nHigh + md5Parts[3]) % 0x7FFFFFFF; |
583 /* make a string of the parts */ | 585 |
584 newHash = (unsigned char *)newHashParts; | 586 newHashParts[0] ^= nLow; |
585 | 587 newHashParts[1] ^= nHigh; |
586 /* convert to hexadecimal */ | 588 newHashParts[2] ^= nLow; |
587 for (i=0; i<16; i++) | 589 newHashParts[3] ^= nHigh; |
588 { | 590 |
589 output[i*2]=hexChars[(newHash[i]>>4)&0xF]; | 591 /* adjust endianness */ |
590 output[(i*2)+1]=hexChars[newHash[i]&0xF]; | 592 for(i = 0; i < 4; i++) |
591 } | 593 newHashParts[i] = GUINT_TO_LE(newHashParts[i]); |
592 | 594 |
593 output[32]='\0'; | 595 /* make a string of the parts */ |
594 | 596 newHash = (unsigned char *)newHashParts; |
595 // purple_debug_info("MSNP14","chl output{%s}\n",output); | 597 |
596 } | 598 /* convert to hexadecimal */ |
599 for (i = 0; i < 16; i++) | |
600 { | |
601 output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF]; | |
602 output[(i * 2) + 1] = hexChars[newHash[i] & 0xF]; | |
603 } | |
604 | |
605 output[32] = '\0'; | |
606 } | |
607 |