Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn_util.c

    re0e1546 r4255320  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2626#include "nogaim.h"
    2727#include "msn.h"
    28 #include "md5.h"
    29 #include "soap.h"
    3028#include <ctype.h>
    3129
     
    3432        struct msn_data *md = ic->proto_data;
    3533        int st;
    36        
    37         if( getenv( "BITLBEE_DEBUG" ) )
    38         {
    39                 write( 2, "->NS:", 5 );
    40                 write( 2, s, len );
    41         }
    4234       
    4335        st = write( md->fd, s, len );
     
    5951}
    6052
    61 static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list )
    62 {
    63         char *domain, handle[strlen(handle_)+1];
    64        
    65         strcpy( handle, handle_ );
    66         if( ( domain = strchr( handle, '@' ) ) )
    67                 *(domain++) = '\0';
    68         else
    69                 return NULL;
    70        
    71         return g_markup_printf_escaped( "<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>",
    72                 domain, handle, list );
    73 }
    74 
    75 int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group )
     53int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group )
    7654{
    7755        struct msn_data *md = ic->proto_data;
    78         char buf[1024], groupid[8];
    79         bee_user_t *bu;
    80         struct msn_buddy_data *bd;
    81         char *adl;
     56        char buf[1024], *realname, groupid[8];
    8257       
    8358        *groupid = '\0';
    84 #if 0
    8559        if( group )
    8660        {
     
    11387                        if( l == NULL )
    11488                        {
    115                                 char groupname[strlen(group)+1];
    116                                 strcpy( groupname, group );
    117                                 http_encode( groupname );
     89                                char *groupname = msn_http_encode( group );
    11890                                g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 );
     91                                g_free( groupname );
    11992                                return msn_write( ic, buf, strlen( buf ) );
    12093                        }
     
    128101                }
    129102        }
    130 #endif
    131        
    132         if( !( ( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
    133                ( bu = bee_user_new( ic->bee, ic, who, 0 ) ) ) ||
    134             !( bd = bu->data ) || bd->flags & list )
    135                 return 1;
    136        
    137         bd->flags |= list;
    138        
    139         if( list == MSN_BUDDY_FL )
    140                 msn_soap_ab_contact_add( ic, bu );
    141         else
    142                 msn_soap_memlist_edit( ic, who, TRUE, list );
    143        
    144         if( ( adl = adlrml_entry( who, list ) ) )
    145         {
    146                 g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n%s",
    147                             ++md->trId, strlen( adl ), adl );
    148                 g_free( adl );
    149                
    150                 return msn_write( ic, buf, strlen( buf ) );
    151         }
    152        
    153         return 1;
    154 }
    155 
    156 int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group )
     103       
     104        realname = msn_http_encode( realname_ );
     105        g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid );
     106        g_free( realname );
     107       
     108        return msn_write( ic, buf, strlen( buf ) );
     109}
     110
     111int msn_buddy_list_remove( struct im_connection *ic, char *list, const char *who, const char *group )
    157112{
    158113        struct msn_data *md = ic->proto_data;
    159114        char buf[1024], groupid[8];
    160         bee_user_t *bu;
    161         struct msn_buddy_data *bd;
    162         char *adl;
    163115       
    164116        *groupid = '\0';
    165 #if 0
    166117        if( group )
    167118        {
     
    174125                        }
    175126        }
    176 #endif
    177        
    178         if( !( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
    179             !( bd = bu->data ) || !( bd->flags & list ) )
    180                 return 1;
    181        
    182         bd->flags &= ~list;
    183        
    184         if( list == MSN_BUDDY_FL )
    185                 msn_soap_ab_contact_del( ic, bu );
    186         else
    187                 msn_soap_memlist_edit( ic, who, FALSE, list );
    188        
    189         if( ( adl = adlrml_entry( who, list ) ) )
    190         {
    191                 g_snprintf( buf, sizeof( buf ), "RML %d %zd\r\n%s",
    192                             ++md->trId, strlen( adl ), adl );
    193                 g_free( adl );
    194                
    195                 return msn_write( ic, buf, strlen( buf ) );
    196         }
    197        
    198         return 1;
     127       
     128        g_snprintf( buf, sizeof( buf ), "REM %d %s %s%s\r\n", ++md->trId, list, who, groupid );
     129        if( msn_write( ic, buf, strlen( buf ) ) )
     130                return( 1 );
     131       
     132        return( 0 );
    199133}
    200134
     
    210144        struct msn_buddy_ask_data *bla = data;
    211145       
    212         msn_buddy_list_add( bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL );
     146        msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname, NULL );
    213147       
    214148        imcb_ask_add( bla->ic, bla->handle, NULL );
     
    223157        struct msn_buddy_ask_data *bla = data;
    224158       
    225         msn_buddy_list_add( bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL );
     159        msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname, NULL );
    226160       
    227161        g_free( bla->handle );
     
    230164}
    231165
    232 void msn_buddy_ask( bee_user_t *bu )
    233 {
    234         struct msn_buddy_ask_data *bla;
    235         struct msn_buddy_data *bd = bu->data;
     166void msn_buddy_ask( struct im_connection *ic, char *handle, char *realname )
     167{
     168        struct msn_buddy_ask_data *bla = g_new0( struct msn_buddy_ask_data, 1 );
    236169        char buf[1024];
    237170       
    238         if( ( bd->flags & 30 ) != 8 && ( bd->flags & 30 ) != 16 )
    239                 return;
    240        
    241         bla = g_new0( struct msn_buddy_ask_data, 1 );
    242         bla->ic = bu->ic;
    243         bla->handle = g_strdup( bu->handle );
    244         bla->realname = g_strdup( bu->fullname );
     171        bla->ic = ic;
     172        bla->handle = g_strdup( handle );
     173        bla->realname = g_strdup( realname );
    245174       
    246175        g_snprintf( buf, sizeof( buf ),
    247176                    "The user %s (%s) wants to add you to his/her buddy list.",
    248                     bu->handle, bu->fullname );
    249         imcb_ask( bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
     177                    handle, realname );
     178        imcb_ask( ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
    250179}
    251180
     
    350279        if( st <= 0 )
    351280                return( -1 );
    352        
    353         if( getenv( "BITLBEE_DEBUG" ) )
    354         {
    355                 write( 2, "->C:", 4 );
    356                 write( 2, h->rxq + h->rxlen - st, st );
    357         }
    358281       
    359282        while( st )
     
    444367}
    445368
     369/* The difference between this function and the normal http_encode() function
     370   is that this one escapes every 7-bit ASCII character because this is said
     371   to avoid some lame server-side checks when setting a real-name. Also,
     372   non-ASCII characters are not escaped because MSN servers don't seem to
     373   appreciate that! */
     374char *msn_http_encode( const char *input )
     375{
     376        char *ret, *s;
     377        int i;
     378       
     379        ret = s = g_new0( char, strlen( input ) * 3 + 1 );
     380        for( i = 0; input[i]; i ++ )
     381                if( input[i] & 128 )
     382                {
     383                        *s = input[i];
     384                        s ++;
     385                }
     386                else
     387                {
     388                        g_snprintf( s, 4, "%%%02X", input[i] );
     389                        s += 3;
     390                }
     391       
     392        return ret;
     393}
     394
    446395void msn_msgq_purge( struct im_connection *ic, GSList **list )
    447396{
     
    484433}
    485434
    486 /* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */
    487 char *msn_p11_challenge( char *challenge )
    488 {
    489         char *output, buf[256];
    490         md5_state_t md5c;
    491         unsigned char md5Hash[16], *newHash;
    492         unsigned int *md5Parts, *chlStringParts, newHashParts[5];
    493         long long nHigh = 0, nLow = 0;
    494         int i, n;
    495 
    496         /* Create the MD5 hash */
    497         md5_init(&md5c);
    498         md5_append(&md5c, (unsigned char*) challenge, strlen(challenge));
    499         md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY));
    500         md5_finish(&md5c, md5Hash);
    501 
    502         /* Split it into four integers */
    503         md5Parts = (unsigned int *)md5Hash;
    504         for (i = 0; i < 4; i ++)
    505         { 
    506                 md5Parts[i] = GUINT32_TO_LE(md5Parts[i]);
    507                
    508                 /* & each integer with 0x7FFFFFFF */
    509                 /* and save one unmodified array for later */
    510                 newHashParts[i] = md5Parts[i];
    511                 md5Parts[i] &= 0x7FFFFFFF;
    512         }
    513        
    514         /* make a new string and pad with '0' */
    515         n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID);
    516         /* truncate at an 8-byte boundary */
    517         buf[n&=~7] = '\0';
    518        
    519         /* split into integers */
    520         chlStringParts = (unsigned int *)buf;
    521        
    522         /* this is magic */
    523         for (i = 0; i < (n / 4) - 1; i += 2)
    524         {
    525                 long long temp;
    526 
    527                 chlStringParts[i]   = GUINT32_TO_LE(chlStringParts[i]);
    528                 chlStringParts[i+1] = GUINT32_TO_LE(chlStringParts[i+1]);
    529 
    530                 temp  = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
    531                 nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
    532                 nLow  = nLow + nHigh + temp;
    533         }
    534         nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF;
    535         nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF;
    536        
    537         newHashParts[0] ^= nHigh;
    538         newHashParts[1] ^= nLow;
    539         newHashParts[2] ^= nHigh;
    540         newHashParts[3] ^= nLow;
    541        
    542         /* swap more bytes if big endian */
    543         for (i = 0; i < 4; i ++)
    544                 newHashParts[i] = GUINT32_TO_LE(newHashParts[i]);
    545        
    546         /* make a string of the parts */
    547         newHash = (unsigned char *)newHashParts;
    548        
    549         /* convert to hexadecimal */
    550         output = g_new(char, 33);
    551         for (i = 0; i < 16; i ++)
    552                 sprintf(output + i * 2, "%02x", newHash[i]);
    553        
    554         return output;
    555 }
    556 
    557 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ )
    558 {
    559         const char *a = a_, *b = b_;
    560         gint ret;
    561        
    562         if( !( a = strchr( a, '@' ) ) || !( b = strchr( b, '@' ) ) ||
    563             ( ret = strcmp( a, b ) ) == 0 )
    564                 ret = strcmp( a_, b_ );
    565        
    566         return ret;
    567 }
    568 
    569 struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name )
    570 {
     435gboolean msn_set_display_name( struct im_connection *ic, const char *rawname )
     436{
     437        char *fn = msn_http_encode( rawname );
    571438        struct msn_data *md = ic->proto_data;
    572         GSList *l;
    573        
    574         for( l = md->groups; l; l = l->next )
    575         {
    576                 struct msn_group *mg = l->data;
    577                
    578                 if( g_strcasecmp( mg->name, name ) == 0 )
    579                         return mg;
    580         }
    581        
    582         return NULL;
    583 }
    584 
    585 struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id )
    586 {
    587         struct msn_data *md = ic->proto_data;
    588         GSList *l;
    589        
    590         for( l = md->groups; l; l = l->next )
    591         {
    592                 struct msn_group *mg = l->data;
    593                
    594                 if( g_strcasecmp( mg->id, id ) == 0 )
    595                         return mg;
    596         }
    597        
    598         return NULL;
    599 }
    600 
    601 int msn_ns_set_display_name( struct im_connection *ic, const char *value )
    602 {
    603         struct msn_data *md = ic->proto_data;
    604         char fn[strlen(value)*3+1];
    605         char buf[512];
    606        
    607         strcpy( fn, value );
    608         http_encode( fn );
    609         g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n",
    610                     ++md->trId, fn );
    611        
    612         /* Note: We don't actually know if the server accepted the new name,
    613            and won't give proper feedback yet if it doesn't. */
    614         return msn_write( ic, buf, strlen( buf ) );
    615 }
     439        char buf[1024];
     440       
     441        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
     442        g_free( fn );
     443       
     444        return msn_write( ic, buf, strlen( buf ) ) != 0;
     445}
Note: See TracChangeset for help on using the changeset viewer.