Changeset 21029d0


Ignore:
Timestamp:
2010-03-20T13:56:27Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
e5a8118
Parents:
0baed0d
Message:

Add MSNP11 challenge code which I'll need for doing this SOAP stuff.

Location:
protocols/msn
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn.h

    r0baed0d r21029d0  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    4040#define QRY_NAME "msmsgs@msnmsgr.com"
    4141#define QRY_CODE "Q1P7W2E4J9R8U3S5"
     42
     43/* This should be MSN Messenger 7.0.0813 */
     44#define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T"
     45#define MSNP11_PROD_ID  "PROD0101{0RM?UBW"
    4246
    4347#define MSN_SB_NEW         -24062002
     
    161165char *msn_http_encode( const char *input );
    162166void msn_msgq_purge( struct im_connection *ic, GSList **list );
     167char *msn_p11_challenge( char *challenge );
    163168
    164169/* tables.c */
  • protocols/msn/msn_util.c

    r0baed0d r21029d0  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2626#include "nogaim.h"
    2727#include "msn.h"
     28#include "md5.h"
    2829#include <ctype.h>
    2930
     
    377378        g_string_free( ret, TRUE );
    378379}
     380
     381unsigned int little_endian( unsigned int dw )
     382{
     383#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
     384        return dw;
     385#else
     386        /* We're still not sure if this machine is big endian since the
     387           constants above are not that portable. Don't swap bytes, just
     388           force-compose a 32-bit little endian integer. */
     389        unsigned int ret = 0, i;
     390        char *dst = (char*) (&ret + 1);
     391       
     392        for (i = 0; i < 4; i ++)
     393        {
     394                *(--dst) = dw >> 24;
     395                dw <<= 8;
     396        }
     397       
     398        return ret;
     399#endif
     400}
     401
     402/* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */
     403
     404char *msn_p11_challenge( char *challenge )
     405{
     406        char *output, buf[256];
     407        md5_state_t md5c;
     408        unsigned char md5Hash[16], *newHash;
     409        unsigned int *md5Parts, *chlStringParts, newHashParts[5];
     410        long long nHigh = 0, nLow = 0;
     411        int i, n;
     412
     413        /* Create the MD5 hash */
     414        md5_init(&md5c);
     415        md5_append(&md5c, (unsigned char*) challenge, strlen(challenge));
     416        md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY));
     417        md5_finish(&md5c, md5Hash);
     418
     419        /* Split it into four integers */
     420        md5Parts = (unsigned int *)md5Hash;
     421        for (i = 0; i < 4; i ++)
     422        { 
     423                md5Parts[i] = little_endian(md5Parts[i]);
     424               
     425                /* & each integer with 0x7FFFFFFF */
     426                /* and save one unmodified array for later */
     427                newHashParts[i] = md5Parts[i];
     428                md5Parts[i] &= 0x7FFFFFFF;
     429        }
     430       
     431        /* make a new string and pad with '0' */
     432        n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID);
     433        /* truncate at an 8-byte boundary */
     434        buf[n&=~7] = '\0';
     435       
     436        /* split into integers */
     437        chlStringParts = (unsigned int *)buf;
     438       
     439        /* this is magic */
     440        for (i = 0; i < (n / 4) - 1; i += 2)
     441        {
     442                long long temp;
     443
     444                chlStringParts[i]   = little_endian(chlStringParts[i]);
     445                chlStringParts[i+1] = little_endian(chlStringParts[i+1]);
     446
     447                temp  = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
     448                nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
     449                nLow  = nLow + nHigh + temp;
     450        }
     451        nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF;
     452        nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF;
     453       
     454        newHashParts[0] ^= nHigh;
     455        newHashParts[1] ^= nLow;
     456        newHashParts[2] ^= nHigh;
     457        newHashParts[3] ^= nLow;
     458       
     459        /* swap more bytes if big endian */
     460        for (i = 0; i < 4; i ++)
     461                newHashParts[i] = little_endian(newHashParts[i]);
     462       
     463        /* make a string of the parts */
     464        newHash = (unsigned char *)newHashParts;
     465       
     466        /* convert to hexadecimal */
     467        output = g_new(char, 33);
     468        for (i = 0; i < 16; i ++)
     469                sprintf(output + i * 2, "%02x", newHash[i]);
     470       
     471        return output;
     472}
Note: See TracChangeset for help on using the changeset viewer.