Mercurial > pidgin
changeset 23496: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 | 0fc1d2df836e |
children | 01c3074b2299 |
files | libpurple/protocols/msn/msnutils.c libpurple/protocols/msn/notification.c |
diffstat | 2 files changed, 83 insertions(+), 91 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/msn/msnutils.c Sat Jun 21 07:36:16 2008 +0000 +++ b/libpurple/protocols/msn/msnutils.c Sun Jun 22 01:52:04 2008 +0000 @@ -24,7 +24,8 @@ #include "msn.h" #include "msnutils.h" #include "time.h" -//#include <openssl/md5.h> + +#include "cipher.h" char *rand_guid(void); @@ -465,10 +466,10 @@ host = g_strdup(str); - if ((c = strchr(host, ':')) != NULL){ + if ((c = strchr(host, ':')) != NULL) { *c = '\0'; port = atoi(c + 1); - }else{ + } else { port = 1863; } @@ -505,92 +506,102 @@ ***************************************************************************/ /* - * Handle MSN Chanllege computation - *This algorithm reference with http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges + * Handle MSN Challenge computation + * This algorithm references + * http://imfreedom.org/wiki/index.php/MSN:NS/Challenges */ #define BUFSIZE 256 void msn_handle_chl(char *input, char *output) { - PurpleCipher *cipher; - PurpleCipherContext *context; - char *productKey = MSNP15_WLM_PRODUCT_KEY, - *productID = MSNP15_WLM_PRODUCT_ID, - *hexChars = "0123456789abcdef", - buf[BUFSIZE]; - unsigned char md5Hash[16], *newHash; - unsigned int *md5Parts, *chlStringParts, newHashParts[5]; + PurpleCipher *cipher; + PurpleCipherContext *context; + const guchar productKey[] = MSNP15_WLM_PRODUCT_KEY; + const guchar productID[] = MSNP15_WLM_PRODUCT_ID; + const char hexChars[] = "0123456789abcdef"; + char buf[BUFSIZE]; + unsigned char md5Hash[16]; + unsigned char *newHash; + unsigned int *md5Parts; + unsigned int *chlStringParts; + unsigned int newHashParts[5]; - long long nHigh=0, nLow=0; - - int i; + long long nHigh = 0, nLow = 0; - /* Create the MD5 hash by using Purple MD5 algorithm*/ - cipher = purple_ciphers_find_cipher("md5"); - context = purple_cipher_context_new(cipher, NULL); + int len; + int i; - purple_cipher_context_append(context, (const guchar *)input, - strlen(input)); - purple_cipher_context_append(context, (const guchar *)productKey, - strlen(productKey)); - purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL); - purple_cipher_context_destroy(context); + /* Create the MD5 hash by using Purple MD5 algorithm */ + cipher = purple_ciphers_find_cipher("md5"); + context = purple_cipher_context_new(cipher, NULL); + + purple_cipher_context_append(context, (guchar *)input, strlen(input)); + purple_cipher_context_append(context, productKey, sizeof(productKey) - 1); + purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL); + purple_cipher_context_destroy(context); - /* Split it into four integers */ - md5Parts = (unsigned int *)md5Hash; - for(i=0; i<4; i++){ - /* adjust endianess */ - md5Parts[i] = GUINT_TO_LE(md5Parts[i]); + /* Split it into four integers */ + md5Parts = (unsigned int *)md5Hash; + for (i = 0; i < 4; i++) { + /* adjust endianess */ + md5Parts[i] = GUINT_TO_LE(md5Parts[i]); - /* & each integer with 0x7FFFFFFF */ - /* and save one unmodified array for later */ - newHashParts[i] = md5Parts[i]; - md5Parts[i] &= 0x7FFFFFFF; - } + /* & each integer with 0x7FFFFFFF */ + /* and save one unmodified array for later */ + newHashParts[i] = md5Parts[i]; + md5Parts[i] &= 0x7FFFFFFF; + } - /* make a new string and pad with '0' */ - snprintf(buf, BUFSIZE-5, "%s%s", input, productID); - i = strlen(buf); - memset(&buf[i], '0', 8 - (i % 8)); - buf[i + (8 - (i % 8))]='\0'; - - /* split into integers */ - chlStringParts = (unsigned int *)buf; + /* make a new string and pad with '0' to length that's a multiple of 8 */ + snprintf(buf, BUFSIZE - 5, "%s%s", input, productID); + len = strlen(buf); + if ((len % 8) != 0) { + int fix = 8 - (len % 8); + memset(&buf[len], '0', fix); + buf[len + fix] = '\0'; + len += fix; + } - /* this is magic */ - for (i=0; i<(strlen(buf)/4)-1; i+=2){ - long long temp; + /* split into integers */ + chlStringParts = (unsigned int *)buf; - chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]); - chlStringParts[i+1] = GUINT_TO_LE(chlStringParts[i+1]); + /* this is magic */ + for (i = 0; i < (strlen(buf) / 4); i += 2) { + long long temp; - temp=(md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF; - nHigh=(md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF; - nLow=nLow + nHigh + temp; - } - nHigh=(nHigh+md5Parts[1]) % 0x7FFFFFFF; - nLow=(nLow+md5Parts[3]) % 0x7FFFFFFF; + chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]); + chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]); + + temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF; + temp = (md5Parts[0] * (temp + nLow) + md5Parts[1]) % 0x7FFFFFFF; + nHigh += temp; - newHashParts[0]^=nHigh; - newHashParts[1]^=nLow; - newHashParts[2]^=nHigh; - newHashParts[3]^=nLow; + temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF; + nLow = (md5Parts[2] * temp + md5Parts[3]) % 0x7FFFFFFF; + nHigh += nLow; + } + nLow = (nLow + md5Parts[1]) % 0x7FFFFFFF; + nHigh = (nHigh + md5Parts[3]) % 0x7FFFFFFF; - /* adjust endianness */ - for(i=0; i<4; i++) - newHashParts[i] = GUINT_TO_LE(newHashParts[i]); - - /* make a string of the parts */ - newHash = (unsigned char *)newHashParts; + newHashParts[0] ^= nLow; + newHashParts[1] ^= nHigh; + newHashParts[2] ^= nLow; + newHashParts[3] ^= nHigh; - /* convert to hexadecimal */ - for (i=0; i<16; i++) - { - output[i*2]=hexChars[(newHash[i]>>4)&0xF]; - output[(i*2)+1]=hexChars[newHash[i]&0xF]; - } + /* adjust endianness */ + for(i = 0; i < 4; i++) + newHashParts[i] = GUINT_TO_LE(newHashParts[i]); + + /* make a string of the parts */ + newHash = (unsigned char *)newHashParts; - output[32]='\0'; + /* convert to hexadecimal */ + for (i = 0; i < 16; i++) + { + output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF]; + output[(i * 2) + 1] = hexChars[newHash[i] & 0xF]; + } -// purple_debug_info("MSNP14","chl output{%s}\n",output); + output[32] = '\0'; } +
--- a/libpurple/protocols/msn/notification.c Sat Jun 21 07:36:16 2008 +0000 +++ b/libpurple/protocols/msn/notification.c Sun Jun 22 01:52:04 2008 +0000 @@ -523,26 +523,7 @@ MsnTransaction *trans; char buf[33]; -#if 0 - cipher = purple_ciphers_find_cipher("md5"); - context = purple_cipher_context_new(cipher, NULL); - purple_cipher_context_append(context, (const guchar *)cmd->params[1], - strlen(cmd->params[1])); - challenge_resp = MSNP15_WLM_PRODUCT_KEY; - - purple_cipher_context_append(context, (const guchar *)challenge_resp, - strlen(challenge_resp)); - purple_cipher_context_digest(context, sizeof(digest), digest, NULL); - purple_cipher_context_destroy(context); - - for (i = 0; i < 16; i++) - { - g_snprintf(buf + (i*2), 3, "%02x", digest[i]); - } -#else msn_handle_chl(cmd->params[1], buf); -#endif -// purple_debug_info("MSNP14","<<challenge:{%s}:{%s}\n",cmd->params[1],buf); trans = msn_transaction_new(cmdproc, "QRY", "%s 32", MSNP15_WLM_PRODUCT_ID); msn_transaction_set_payload(trans, buf, 32);