src/protocols/msn/msn-utils.c

branch
soc.2006.msnp13
changeset 13855
24cff9e060d7
parent 13854
ab947cf0c2bb
child 13858
fe1fbb9cc42b
--- a/src/protocols/msn/msn-utils.c	Sun Jul 09 16:48:25 2006 +0000
+++ b/src/protocols/msn/msn-utils.c	Mon Jul 17 12:22:37 2006 +0000
@@ -23,6 +23,7 @@
  */
 #include "msn.h"
 #include "msn-utils.h"
+//#include <openssl/md5.h>
 
 void
 msn_parse_format(const char *mime, char **pre_ret, char **post_ret)
@@ -362,3 +363,122 @@
 	*ret_port = port;
 }
 
+/*check the edian of system*/
+int 
+isBigEndian(void)
+{
+		short int word = 0x0100;
+		char *byte = (char *)&word;
+
+		return(byte[0]);
+}
+
+/*swap utility*/
+unsigned int 
+swapInt(unsigned int dw)
+{
+		unsigned int tmp;
+		tmp =  (dw & 0x000000FF);
+		tmp = ((dw & 0x0000FF00) >> 0x08) | (tmp << 0x08);
+		tmp = ((dw & 0x00FF0000) >> 0x10) | (tmp << 0x08);
+		tmp = ((dw & 0xFF000000) >> 0x18) | (tmp << 0x08);
+		return(tmp);
+}
+
+/*
+ * handle MSN Chanllege computation
+ *This algorithm reference with http://msnpiki.msnfanatic.com/index.php/MSNP11:Challenges
+ */
+#define BUFSIZE	256
+void 
+msn_handle_chl(char *input, char *output)
+{
+		GaimCipher *cipher;
+		GaimCipherContext *context;
+		char *productKey = MSNP13_WLM_PRODUCT_KEY,
+			 *productID  = MSNP13_WLM_PRODUCT_ID,
+			 *hexChars   = "0123456789abcdef",
+			 buf[BUFSIZE];
+		unsigned char md5Hash[16], *newHash;
+		unsigned int *md5Parts, *chlStringParts, newHashParts[5];
+
+		long long nHigh=0, nLow=0;
+
+		int i, bigEndian;
+
+		/* Determine our endianess */
+		bigEndian = isBigEndian();
+
+		/* Create the MD5 hash by using Gaim MD5 algorithm*/
+		cipher = gaim_ciphers_find_cipher("md5");
+		context = gaim_cipher_context_new(cipher, NULL);
+
+		gaim_cipher_context_append(context, (const guchar *)input,
+						strlen(input));
+		gaim_cipher_context_append(context, (const guchar *)productKey,
+						strlen(productKey));
+		gaim_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL);
+		gaim_cipher_context_destroy(context);
+
+		/* Split it into four integers */
+		md5Parts = (unsigned int *)md5Hash;
+		for(i=0; i<4; i++){  
+				/* check for endianess */
+				if(bigEndian)
+						md5Parts[i] = swapInt(md5Parts[i]);
+
+				/* & 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;
+
+		/* this is magic */
+		for (i=0; i<(strlen(buf)/4)-1; i+=2){
+				long long temp;
+
+				if(bigEndian){
+						chlStringParts[i]   = swapInt(chlStringParts[i]);
+						chlStringParts[i+1] = swapInt(chlStringParts[i+1]);
+				}
+
+				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;
+
+		newHashParts[0]^=nHigh;
+		newHashParts[1]^=nLow;
+		newHashParts[2]^=nHigh;
+		newHashParts[3]^=nLow;
+
+		/* swap more bytes if big endian */
+		for(i=0; i<4 && bigEndian; i++)
+				newHashParts[i] = swapInt(newHashParts[i]); 
+
+		/* make a string of the parts */
+		newHash = (unsigned char *)newHashParts;
+
+		/* 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];
+		}
+
+		output[32]='\0';
+
+//		gaim_debug_info("MaYuan","chl output{%s}\n",output);
+}
+

mercurial