Changeset 62f53b50 for protocols/msn/msn_util.c
- Timestamp:
- 2010-10-02T05:34:53Z (14 years ago)
- Branches:
- master
- Children:
- 2af3e23
- Parents:
- 05bf2a0 (diff), 04cd284 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/msn/msn_util.c
r05bf2a0 r62f53b50 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 30 int msn_write( struct im_connection *ic, char *s, int len ) 32 int msn_logged_in( struct im_connection *ic ) 33 { 34 imcb_connected( ic ); 35 36 return( 0 ); 37 } 38 39 static 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 53 int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group ) 31 54 { 32 55 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; 57 60 58 61 *groupid = '\0'; 62 #if 0 59 63 if( group ) 60 64 { … … 87 91 if( l == NULL ) 88 92 { 89 char *groupname = msn_http_encode( group ); 93 char groupname[strlen(group)+1]; 94 strcpy( groupname, group ); 95 http_encode( groupname ); 90 96 g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); 91 g_free( groupname );92 97 return msn_write( ic, buf, strlen( buf ) ); 93 98 } … … 101 106 } 102 107 } 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 134 int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group ) 112 135 { 113 136 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; 115 141 116 142 *groupid = '\0'; 143 #if 0 117 144 if( group ) 118 145 { … … 125 152 } 126 153 } 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; 133 177 } 134 178 … … 144 188 struct msn_buddy_ask_data *bla = data; 145 189 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 ); 147 191 148 192 imcb_ask_add( bla->ic, bla->handle, NULL ); … … 157 201 struct msn_buddy_ask_data *bla = data; 158 202 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 ); 160 204 161 205 g_free( bla->handle ); … … 164 208 } 165 209 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 ); 210 void msn_buddy_ask( bee_user_t *bu ) 211 { 212 struct msn_buddy_ask_data *bla; 213 struct msn_buddy_data *bd = bu->data; 169 214 char buf[1024]; 170 215 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 ); 174 223 175 224 g_snprintf( buf, sizeof( buf ), 176 225 "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 ); 179 228 } 180 229 … … 279 328 if( st <= 0 ) 280 329 return( -1 ); 330 331 if( getenv( "BITLBEE_DEBUG" ) ) 332 { 333 write( 2, "->C:", 4 ); 334 write( 2, h->rxq + h->rxlen - st, st ); 335 } 281 336 282 337 while( st ) … … 296 351 cmd = msn_linesplit( cmd_text ); 297 352 for( count = 0; cmd[count]; count ++ ); 298 st = h->exec_command( h ->data, cmd, count );353 st = h->exec_command( h, cmd, count ); 299 354 g_free( cmd_text ); 300 355 … … 331 386 for( count = 0; cmd[count]; count ++ ); 332 387 333 st = h->exec_message( h ->data, msg, h->msglen, cmd, count );388 st = h->exec_message( h, msg, h->msglen, cmd, count ); 334 389 g_free( msg ); 335 390 g_free( h->cmd_text ); … … 367 422 } 368 423 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 424 void msn_msgq_purge( struct im_connection *ic, GSList **list ) 396 425 { … … 433 462 } 434 463 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 */ 465 char *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 535 gint 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 547 struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name ) 548 { 438 549 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 563 struct 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 579 int 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.