Changes in protocols/msn/msn_util.c [4255320:e0e1546]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/msn/msn_util.c
r4255320 re0e1546 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 04Wilmer van der Gaast and others *4 * Copyright 2002-2010 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" 28 30 #include <ctype.h> 29 31 … … 32 34 struct msn_data *md = ic->proto_data; 33 35 int st; 36 37 if( getenv( "BITLBEE_DEBUG" ) ) 38 { 39 write( 2, "->NS:", 5 ); 40 write( 2, s, len ); 41 } 34 42 35 43 st = write( md->fd, s, len ); … … 51 59 } 52 60 53 int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group ) 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 ) 54 76 { 55 77 struct msn_data *md = ic->proto_data; 56 char buf[1024], *realname, groupid[8]; 78 char buf[1024], groupid[8]; 79 bee_user_t *bu; 80 struct msn_buddy_data *bd; 81 char *adl; 57 82 58 83 *groupid = '\0'; 84 #if 0 59 85 if( group ) 60 86 { … … 87 113 if( l == NULL ) 88 114 { 89 char *groupname = msn_http_encode( group ); 115 char groupname[strlen(group)+1]; 116 strcpy( groupname, group ); 117 http_encode( groupname ); 90 118 g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); 91 g_free( groupname );92 119 return msn_write( ic, buf, strlen( buf ) ); 93 120 } … … 101 128 } 102 129 } 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 ) 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 ) 112 157 { 113 158 struct msn_data *md = ic->proto_data; 114 159 char buf[1024], groupid[8]; 160 bee_user_t *bu; 161 struct msn_buddy_data *bd; 162 char *adl; 115 163 116 164 *groupid = '\0'; 165 #if 0 117 166 if( group ) 118 167 { … … 125 174 } 126 175 } 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 ); 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; 133 199 } 134 200 … … 144 210 struct msn_buddy_ask_data *bla = data; 145 211 146 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname, NULL );212 msn_buddy_list_add( bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL ); 147 213 148 214 imcb_ask_add( bla->ic, bla->handle, NULL ); … … 157 223 struct msn_buddy_ask_data *bla = data; 158 224 159 msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname, NULL );225 msn_buddy_list_add( bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL ); 160 226 161 227 g_free( bla->handle ); … … 164 230 } 165 231 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 ); 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; 169 236 char buf[1024]; 170 237 171 bla->ic = ic; 172 bla->handle = g_strdup( handle ); 173 bla->realname = g_strdup( realname ); 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 ); 174 245 175 246 g_snprintf( buf, sizeof( buf ), 176 247 "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 );248 bu->handle, bu->fullname ); 249 imcb_ask( bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no ); 179 250 } 180 251 … … 279 350 if( st <= 0 ) 280 351 return( -1 ); 352 353 if( getenv( "BITLBEE_DEBUG" ) ) 354 { 355 write( 2, "->C:", 4 ); 356 write( 2, h->rxq + h->rxlen - st, st ); 357 } 281 358 282 359 while( st ) … … 367 444 } 368 445 369 /* The difference between this function and the normal http_encode() function370 is that this one escapes every 7-bit ASCII character because this is said371 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 to373 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 else387 {388 g_snprintf( s, 4, "%%%02X", input[i] );389 s += 3;390 }391 392 return ret;393 }394 395 446 void msn_msgq_purge( struct im_connection *ic, GSList **list ) 396 447 { … … 433 484 } 434 485 435 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ) 436 { 437 char *fn = msn_http_encode( rawname ); 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 { 438 571 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 } 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 }
Note: See TracChangeset
for help on using the changeset viewer.