Ignore:
Timestamp:
2010-10-03T02:45:26Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
04f0c10
Parents:
88de0c9 (diff), 2af3e23 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging mainline, which includes a huge msnp13 merge.

Not 100% sure about the OpenSSL merge, should double check that but I'm
currently offline.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn_util.c

    r88de0c9 r8e9e2b7  
    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"
     29#include "soap.h"
    2830#include <ctype.h>
    2931
    30 int msn_write( struct im_connection *ic, char *s, int len )
     32int msn_logged_in( struct im_connection *ic )
     33{
     34        imcb_connected( ic );
     35       
     36        return( 0 );
     37}
     38
     39static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list )
     40{
     41        char *domain, handle[strlen(handle_)+1];
     42       
     43        strcpy( handle, handle_ );
     44        if( ( domain = strchr( handle, '@' ) ) )
     45                *(domain++) = '\0';
     46        else
     47                return NULL;
     48       
     49        return g_markup_printf_escaped( "<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>",
     50                domain, handle, list );
     51}
     52
     53int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group )
    3154{
    3255        struct msn_data *md = ic->proto_data;
    33         int st;
    34        
    35         st = write( md->fd, s, len );
    36         if( st != len )
    37         {
    38                 imcb_error( ic, "Short write() to main server" );
    39                 imc_logout( ic, TRUE );
    40                 return 0;
    41         }
    42        
    43         return 1;
    44 }
    45 
    46 int msn_logged_in( struct im_connection *ic )
    47 {
    48         imcb_connected( ic );
    49        
    50         return( 0 );
    51 }
    52 
    53 int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group )
    54 {
    55         struct msn_data *md = ic->proto_data;
    56         char buf[1024], *realname, groupid[8];
     56        char groupid[8];
     57        bee_user_t *bu;
     58        struct msn_buddy_data *bd;
     59        char *adl;
    5760       
    5861        *groupid = '\0';
     62#if 0
    5963        if( group )
    6064        {
     
    8791                        if( l == NULL )
    8892                        {
    89                                 char *groupname = msn_http_encode( group );
     93                                char groupname[strlen(group)+1];
     94                                strcpy( groupname, group );
     95                                http_encode( groupname );
    9096                                g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 );
    91                                 g_free( groupname );
    9297                                return msn_write( ic, buf, strlen( buf ) );
    9398                        }
     
    101106                }
    102107        }
    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 
    111 int msn_buddy_list_remove( struct im_connection *ic, char *list, const char *who, const char *group )
     108#endif
     109       
     110        if( !( ( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
     111               ( bu = bee_user_new( ic->bee, ic, who, 0 ) ) ) ||
     112            !( bd = bu->data ) || bd->flags & list )
     113                return 1;
     114       
     115        bd->flags |= list;
     116       
     117        if( list == MSN_BUDDY_FL )
     118                msn_soap_ab_contact_add( ic, bu );
     119        else
     120                msn_soap_memlist_edit( ic, who, TRUE, list );
     121       
     122        if( ( adl = adlrml_entry( who, list ) ) )
     123        {
     124                int st = msn_ns_write( ic, -1, "ADL %d %zd\r\n%s",
     125                                       ++md->trId, strlen( adl ), adl );
     126                g_free( adl );
     127               
     128                return st;
     129        }
     130       
     131        return 1;
     132}
     133
     134int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group )
    112135{
    113136        struct msn_data *md = ic->proto_data;
    114         char buf[1024], groupid[8];
     137        char groupid[8];
     138        bee_user_t *bu;
     139        struct msn_buddy_data *bd;
     140        char *adl;
    115141       
    116142        *groupid = '\0';
     143#if 0
    117144        if( group )
    118145        {
     
    125152                        }
    126153        }
    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 );
     154#endif
     155       
     156        if( !( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
     157            !( bd = bu->data ) || !( bd->flags & list ) )
     158                return 1;
     159       
     160        bd->flags &= ~list;
     161       
     162        if( list == MSN_BUDDY_FL )
     163                msn_soap_ab_contact_del( ic, bu );
     164        else
     165                msn_soap_memlist_edit( ic, who, FALSE, list );
     166       
     167        if( ( adl = adlrml_entry( who, list ) ) )
     168        {
     169                int st = msn_ns_write( ic, -1, "RML %d %zd\r\n%s",
     170                                       ++md->trId, strlen( adl ), adl );
     171                g_free( adl );
     172               
     173                return st;
     174        }
     175       
     176        return 1;
    133177}
    134178
     
    144188        struct msn_buddy_ask_data *bla = data;
    145189       
    146         msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname, NULL );
     190        msn_buddy_list_add( bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL );
    147191       
    148192        imcb_ask_add( bla->ic, bla->handle, NULL );
     
    157201        struct msn_buddy_ask_data *bla = data;
    158202       
    159         msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname, NULL );
     203        msn_buddy_list_add( bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL );
    160204       
    161205        g_free( bla->handle );
     
    164208}
    165209
    166 void 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 );
     210void msn_buddy_ask( bee_user_t *bu )
     211{
     212        struct msn_buddy_ask_data *bla;
     213        struct msn_buddy_data *bd = bu->data;
    169214        char buf[1024];
    170215       
    171         bla->ic = ic;
    172         bla->handle = g_strdup( handle );
    173         bla->realname = g_strdup( realname );
     216        if( ( bd->flags & 30 ) != 8 && ( bd->flags & 30 ) != 16 )
     217                return;
     218       
     219        bla = g_new0( struct msn_buddy_ask_data, 1 );
     220        bla->ic = bu->ic;
     221        bla->handle = g_strdup( bu->handle );
     222        bla->realname = g_strdup( bu->fullname );
    174223       
    175224        g_snprintf( buf, sizeof( buf ),
    176225                    "The user %s (%s) wants to add you to his/her buddy list.",
    177                     handle, realname );
    178         imcb_ask( ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
     226                    bu->handle, bu->fullname );
     227        imcb_ask( bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
    179228}
    180229
     
    279328        if( st <= 0 )
    280329                return( -1 );
     330       
     331        if( getenv( "BITLBEE_DEBUG" ) )
     332        {
     333                write( 2, "->C:", 4 );
     334                write( 2, h->rxq + h->rxlen - st, st );
     335        }
    281336       
    282337        while( st )
     
    296351                                        cmd = msn_linesplit( cmd_text );
    297352                                        for( count = 0; cmd[count]; count ++ );
    298                                         st = h->exec_command( h->data, cmd, count );
     353                                        st = h->exec_command( h, cmd, count );
    299354                                        g_free( cmd_text );
    300355                                       
     
    331386                        for( count = 0; cmd[count]; count ++ );
    332387                       
    333                         st = h->exec_message( h->data, msg, h->msglen, cmd, count );
     388                        st = h->exec_message( h, msg, h->msglen, cmd, count );
    334389                        g_free( msg );
    335390                        g_free( h->cmd_text );
     
    367422}
    368423
    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! */
    374 char *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 
    395424void msn_msgq_purge( struct im_connection *ic, GSList **list )
    396425{
     
    433462}
    434463
    435 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname )
    436 {
    437         char *fn = msn_http_encode( rawname );
     464/* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */
     465char *msn_p11_challenge( char *challenge )
     466{
     467        char *output, buf[256];
     468        md5_state_t md5c;
     469        unsigned char md5Hash[16], *newHash;
     470        unsigned int *md5Parts, *chlStringParts, newHashParts[5];
     471        long long nHigh = 0, nLow = 0;
     472        int i, n;
     473
     474        /* Create the MD5 hash */
     475        md5_init(&md5c);
     476        md5_append(&md5c, (unsigned char*) challenge, strlen(challenge));
     477        md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY));
     478        md5_finish(&md5c, md5Hash);
     479
     480        /* Split it into four integers */
     481        md5Parts = (unsigned int *)md5Hash;
     482        for (i = 0; i < 4; i ++)
     483        { 
     484                md5Parts[i] = GUINT32_TO_LE(md5Parts[i]);
     485               
     486                /* & each integer with 0x7FFFFFFF */
     487                /* and save one unmodified array for later */
     488                newHashParts[i] = md5Parts[i];
     489                md5Parts[i] &= 0x7FFFFFFF;
     490        }
     491       
     492        /* make a new string and pad with '0' */
     493        n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID);
     494        /* truncate at an 8-byte boundary */
     495        buf[n&=~7] = '\0';
     496       
     497        /* split into integers */
     498        chlStringParts = (unsigned int *)buf;
     499       
     500        /* this is magic */
     501        for (i = 0; i < (n / 4) - 1; i += 2)
     502        {
     503                long long temp;
     504
     505                chlStringParts[i]   = GUINT32_TO_LE(chlStringParts[i]);
     506                chlStringParts[i+1] = GUINT32_TO_LE(chlStringParts[i+1]);
     507
     508                temp  = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
     509                nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
     510                nLow  = nLow + nHigh + temp;
     511        }
     512        nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF;
     513        nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF;
     514       
     515        newHashParts[0] ^= nHigh;
     516        newHashParts[1] ^= nLow;
     517        newHashParts[2] ^= nHigh;
     518        newHashParts[3] ^= nLow;
     519       
     520        /* swap more bytes if big endian */
     521        for (i = 0; i < 4; i ++)
     522                newHashParts[i] = GUINT32_TO_LE(newHashParts[i]);
     523       
     524        /* make a string of the parts */
     525        newHash = (unsigned char *)newHashParts;
     526       
     527        /* convert to hexadecimal */
     528        output = g_new(char, 33);
     529        for (i = 0; i < 16; i ++)
     530                sprintf(output + i * 2, "%02x", newHash[i]);
     531       
     532        return output;
     533}
     534
     535gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ )
     536{
     537        const char *a = a_, *b = b_;
     538        gint ret;
     539       
     540        if( !( a = strchr( a, '@' ) ) || !( b = strchr( b, '@' ) ) ||
     541            ( ret = strcmp( a, b ) ) == 0 )
     542                ret = strcmp( a_, b_ );
     543       
     544        return ret;
     545}
     546
     547struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name )
     548{
    438549        struct msn_data *md = ic->proto_data;
    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 }
     550        GSList *l;
     551       
     552        for( l = md->groups; l; l = l->next )
     553        {
     554                struct msn_group *mg = l->data;
     555               
     556                if( g_strcasecmp( mg->name, name ) == 0 )
     557                        return mg;
     558        }
     559       
     560        return NULL;
     561}
     562
     563struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id )
     564{
     565        struct msn_data *md = ic->proto_data;
     566        GSList *l;
     567       
     568        for( l = md->groups; l; l = l->next )
     569        {
     570                struct msn_group *mg = l->data;
     571               
     572                if( g_strcasecmp( mg->id, id ) == 0 )
     573                        return mg;
     574        }
     575       
     576        return NULL;
     577}
     578
     579int msn_ns_set_display_name( struct im_connection *ic, const char *value )
     580{
     581        struct msn_data *md = ic->proto_data;
     582        char fn[strlen(value)*3+1];
     583       
     584        strcpy( fn, value );
     585        http_encode( fn );
     586       
     587        /* Note: We don't actually know if the server accepted the new name,
     588           and won't give proper feedback yet if it doesn't. */
     589        return msn_ns_write( ic, -1, "PRP %d MFN %s\r\n", ++md->trId, fn );
     590}
Note: See TracChangeset for help on using the changeset viewer.