Changes in protocols/msn/msn_util.c [e0e1546:4255320]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/msn/msn_util.c
re0e1546 r4255320 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 10Wilmer van der Gaast and others *4 * Copyright 2002-2004 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 26 26 #include "nogaim.h" 27 27 #include "msn.h" 28 #include "md5.h"29 #include "soap.h"30 28 #include <ctype.h> 31 29 … … 34 32 struct msn_data *md = ic->proto_data; 35 33 int st; 36 37 if( getenv( "BITLBEE_DEBUG" ) )38 {39 write( 2, "->NS:", 5 );40 write( 2, s, len );41 }42 34 43 35 st = write( md->fd, s, len ); … … 59 51 } 60 52 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 ) 53 int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group ) 76 54 { 77 55 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]; 82 57 83 58 *groupid = '\0'; 84 #if 085 59 if( group ) 86 60 { … … 113 87 if( l == NULL ) 114 88 { 115 char groupname[strlen(group)+1]; 116 strcpy( groupname, group ); 117 http_encode( groupname ); 89 char *groupname = msn_http_encode( group ); 118 90 g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); 91 g_free( groupname ); 119 92 return msn_write( ic, buf, strlen( buf ) ); 120 93 } … … 128 101 } 129 102 } 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 111 int msn_buddy_list_remove( struct im_connection *ic, char *list, const char *who, const char *group ) 157 112 { 158 113 struct msn_data *md = ic->proto_data; 159 114 char buf[1024], groupid[8]; 160 bee_user_t *bu;161 struct msn_buddy_data *bd;162 char *adl;163 115 164 116 *groupid = '\0'; 165 #if 0166 117 if( group ) 167 118 { … … 174 125 } 175 126 } 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 ); 199 133 } 200 134 … … 210 144 struct msn_buddy_ask_data *bla = data; 211 145 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 ); 213 147 214 148 imcb_ask_add( bla->ic, bla->handle, NULL ); … … 223 157 struct msn_buddy_ask_data *bla = data; 224 158 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 ); 226 160 227 161 g_free( bla->handle ); … … 230 164 } 231 165 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; 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 ); 236 169 char buf[1024]; 237 170 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 ); 245 174 246 175 g_snprintf( buf, sizeof( buf ), 247 176 "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 ); 250 179 } 251 180 … … 350 279 if( st <= 0 ) 351 280 return( -1 ); 352 353 if( getenv( "BITLBEE_DEBUG" ) )354 {355 write( 2, "->C:", 4 );356 write( 2, h->rxq + h->rxlen - st, st );357 }358 281 359 282 while( st ) … … 444 367 } 445 368 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 446 395 void msn_msgq_purge( struct im_connection *ic, GSList **list ) 447 396 { … … 484 433 } 485 434 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 { 435 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ) 436 { 437 char *fn = msn_http_encode( rawname ); 571 438 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.