Changes in / [136c2bb:07874be]
- Files:
-
- 2 added
- 2 deleted
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/misc.c
r136c2bb r07874be 298 298 void http_encode( char *s ) 299 299 { 300 char *t;300 char t[strlen(s)+1]; 301 301 int i, j; 302 302 303 t = g_strdup( s ); 304 303 strcpy( t, s ); 305 304 for( i = j = 0; t[i]; i ++, j ++ ) 306 305 { … … 320 319 } 321 320 s[j] = 0; 322 323 g_free( t );324 321 } 325 322 -
lib/sha1.c
r136c2bb r07874be 36 36 */ 37 37 38 #include <string.h> 38 39 #include "sha1.h" 39 40 … … 374 375 sha1_process_block(context); 375 376 } 377 378 #define HMAC_BLOCK_SIZE 64 379 380 /* BitlBee addition: */ 381 void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size]) 382 { 383 sha1_state_t sha1; 384 uint8_t hash[sha1_hash_size]; 385 uint8_t key[HMAC_BLOCK_SIZE+1]; 386 int i; 387 388 if( key_len == 0 ) 389 key_len = strlen( key_ ); 390 if( payload_len == 0 ) 391 payload_len = strlen( payload ); 392 393 /* Create K. If our current key is >64 chars we have to hash it, 394 otherwise just pad. */ 395 memset( key, 0, HMAC_BLOCK_SIZE + 1 ); 396 if( key_len > HMAC_BLOCK_SIZE ) 397 { 398 sha1_init( &sha1 ); 399 sha1_append( &sha1, (uint8_t*) key_, key_len ); 400 sha1_finish( &sha1, key ); 401 } 402 else 403 { 404 memcpy( key, key_, key_len ); 405 } 406 407 /* Inner part: H(K XOR 0x36, text) */ 408 sha1_init( &sha1 ); 409 for( i = 0; i < HMAC_BLOCK_SIZE; i ++ ) 410 key[i] ^= 0x36; 411 sha1_append( &sha1, key, HMAC_BLOCK_SIZE ); 412 sha1_append( &sha1, (const uint8_t*) payload, payload_len ); 413 sha1_finish( &sha1, hash ); 414 415 /* Final result: H(K XOR 0x5C, inner stuff) */ 416 sha1_init( &sha1 ); 417 for( i = 0; i < HMAC_BLOCK_SIZE; i ++ ) 418 key[i] ^= 0x36 ^ 0x5c; 419 sha1_append( &sha1, key, HMAC_BLOCK_SIZE ); 420 sha1_append( &sha1, hash, sha1_hash_size ); 421 sha1_finish( &sha1, Message_Digest ); 422 } -
lib/sha1.h
r136c2bb r07874be 67 67 G_MODULE_EXPORT int sha1_append(sha1_state_t *, const uint8_t *, unsigned int); 68 68 G_MODULE_EXPORT int sha1_finish(sha1_state_t *, uint8_t Message_Digest[sha1_hash_size]); 69 G_MODULE_EXPORT void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size]); 69 70 70 71 #endif -
lib/ssl_client.h
r136c2bb r07874be 78 78 the same action as the handler that just received the SSL_AGAIN.) */ 79 79 G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn ); 80 81 G_MODULE_EXPORT size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res); -
lib/ssl_gnutls.c
r136c2bb r07874be 189 189 ssl_errno = SSL_AGAIN; 190 190 191 if( getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st ); 192 191 193 return st; 192 194 } … … 207 209 if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) 208 210 ssl_errno = SSL_AGAIN; 211 212 if( getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st ); 209 213 210 214 return st; -
lib/ssl_openssl.c
r136c2bb r07874be 116 116 { 117 117 initialized = TRUE; 118 SSLeay_add_ssl_algorithms(); 118 SSL_library_init(); 119 //SSLeay_add_ssl_algorithms(); 120 //OpenSSL_add_all_algorithms(); 119 121 } 120 122 … … 205 207 } 206 208 209 if( getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st ); 210 207 211 return st; 208 212 } … … 219 223 220 224 st = SSL_write( ((struct scd*)conn)->ssl, buf, len ); 225 226 if( getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st ); 221 227 222 228 ssl_errno = SSL_OK; … … 272 278 return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ ); 273 279 } 280 281 size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res) 282 { 283 int output_length = 0; 284 EVP_CIPHER_CTX ctx; 285 286 *res = g_new0(unsigned char, 72); 287 288 /* Don't set key or IV because we will modify the parameters */ 289 EVP_CIPHER_CTX_init(&ctx); 290 EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1); 291 EVP_CIPHER_CTX_set_key_length(&ctx, key_len); 292 EVP_CIPHER_CTX_set_padding(&ctx, 0); 293 /* We finished modifying parameters so now we can set key and IV */ 294 EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1); 295 EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len); 296 EVP_CipherFinal_ex(&ctx, *res, &output_length); 297 EVP_CIPHER_CTX_cleanup(&ctx); 298 //EVP_cleanup(); 299 300 return output_length; 301 } -
lib/xmltree.c
r136c2bb r07874be 141 141 /* Feed the parser, don't execute any handler. Returns -1 on errors, 0 on 142 142 end-of-stream and 1 otherwise. */ 143 int xt_feed( struct xt_parser *xt, c har *text, int text_len )143 int xt_feed( struct xt_parser *xt, const char *text, int text_len ) 144 144 { 145 145 if( !g_markup_parse_context_parse( xt->parser, text, text_len, &xt->gerr ) ) … … 174 174 if( node->flags & XT_COMPLETE && !( node->flags & XT_SEEN ) ) 175 175 { 176 for( i = 0; xt->handlers[i].func; i ++ )176 if( xt->handlers ) for( i = 0; xt->handlers[i].func; i ++ ) 177 177 { 178 178 /* This one is fun! \o/ */ 179 179 180 180 /* If handler.name == NULL it means it should always match. */ 181 181 if( ( xt->handlers[i].name == NULL || 182 182 /* If it's not, compare. There should always be a name. */ 183 183 g_strcasecmp( xt->handlers[i].name, node->name ) == 0 ) && 184 184 /* If handler.parent == NULL, it's a match. */ 185 185 ( xt->handlers[i].parent == NULL || 186 186 /* If there's a parent node, see if the name matches. */ 187 187 ( node->parent ? g_strcasecmp( xt->handlers[i].parent, node->parent->name ) == 0 : 188 189 g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )188 /* If there's no parent, the handler should mention <root> as a parent. */ 189 strcmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) ) 190 190 { 191 191 st = xt->handlers[i].func( node, xt->data ); … … 260 260 } 261 261 262 struct xt_node *xt_from_string( const char *in ) 263 { 264 struct xt_parser *parser; 265 struct xt_node *ret; 266 267 parser = xt_new( NULL, NULL ); 268 xt_feed( parser, in, strlen( in ) ); 269 ret = parser->root; 270 parser->root = NULL; 271 xt_free( parser ); 272 273 return ret; 274 } 275 262 276 static void xt_to_string_real( struct xt_node *node, GString *str ) 263 277 { … … 550 564 } 551 565 566 /* Same, but at the beginning. */ 567 void xt_insert_child( struct xt_node *parent, struct xt_node *child ) 568 { 569 struct xt_node *node, *last; 570 571 for( node = child; node; node = node->next ) 572 { 573 if( node->parent != NULL ) 574 { 575 /* ERROR CONDITION: They seem to have a parent already??? */ 576 } 577 578 node->parent = parent; 579 last = node; 580 } 581 582 last->next = parent->children; 583 parent->children = child; 584 } 585 552 586 void xt_add_attr( struct xt_node *node, const char *key, const char *value ) 553 587 { -
lib/xmltree.h
r136c2bb r07874be 79 79 struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data ); 80 80 void xt_reset( struct xt_parser *xt ); 81 int xt_feed( struct xt_parser *xt, c har *text, int text_len );81 int xt_feed( struct xt_parser *xt, const char *text, int text_len ); 82 82 int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth ); 83 83 void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth ); 84 struct xt_node *xt_from_string( const char *in ); 84 85 char *xt_to_string( struct xt_node *node ); 85 86 void xt_print( struct xt_node *node ); … … 92 93 struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children ); 93 94 void xt_add_child( struct xt_node *parent, struct xt_node *child ); 95 void xt_insert_child( struct xt_node *parent, struct xt_node *child ); 94 96 void xt_add_attr( struct xt_node *node, const char *key, const char *value ); 95 97 int xt_remove_attr( struct xt_node *node, const char *key ); -
protocols/bee.h
r136c2bb r07874be 148 148 * - 'state' and 'message' can be NULL */ 149 149 G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ); 150 G_MODULE_EXPORT void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message ); 150 151 G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle ); 151 152 /* Call when a handle says something. 'flags' and 'sent_at may be just 0. */ -
protocols/bee_user.c
r136c2bb r07874be 187 187 /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */ 188 188 bu->flags = flags; 189 bu->status = g_strdup( ( flags & OPT_AWAY ) && state == NULL ? "Away" : state );190 189 bu->status_msg = g_strdup( message ); 190 if( state && *state ) 191 bu->status = g_strdup( state ); 192 else if( flags & OPT_AWAY ) 193 bu->status = g_strdup( "Away" ); 194 else 195 bu->status = NULL; 191 196 192 197 if( bee->ui->user_status ) … … 198 203 } 199 204 205 /* Same, but only change the away/status message, not any away/online state info. */ 206 void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message ) 207 { 208 bee_t *bee = ic->bee; 209 bee_user_t *bu, *old; 210 211 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 212 { 213 return; 214 } 215 216 old = g_memdup( bu, sizeof( bee_user_t ) ); 217 218 bu->status_msg = g_strdup( message ); 219 220 if( bee->ui->user_status ) 221 bee->ui->user_status( bee, bu, old ); 222 223 g_free( old->status_msg ); 224 g_free( old ); 225 } 226 200 227 void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle ) 201 228 { -
protocols/msn/Makefile
r136c2bb r07874be 13 13 14 14 # [SH] Program variables 15 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o15 objects = msn.o msn_util.o ns.o sb.o soap.o tables.o 16 16 17 17 LFLAGS += -r … … 43 43 @$(LD) $(LFLAGS) $(objects) -o msn_mod.o 44 44 45 45 soap.o: soap.h soap.c -
protocols/msn/msn.c
r136c2bb r07874be 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 … … 25 25 26 26 #include "nogaim.h" 27 #include "soap.h" 27 28 #include "msn.h" 28 29 … … 35 36 static void msn_init( account_t *acc ) 36 37 { 37 set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); 38 set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc ); 38 set_t *s; 39 40 s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); 41 s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; 42 39 43 set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); 40 44 set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc ); 45 46 acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE; 41 47 } 42 48 … … 68 74 md->ic = ic; 69 75 md->away_state = msn_away_state_list; 76 md->domaintree = g_tree_new( msn_domaintree_cmp ); 70 77 71 78 msn_connections = g_slist_append( msn_connections, ic ); … … 103 110 g_free( md->grouplist[--md->groupcount] ); 104 111 g_free( md->grouplist ); 112 g_free( md->tokens[0] ); 113 g_free( md->tokens[1] ); 114 g_free( md->tokens[2] ); 115 g_free( md->lock_key ); 116 117 g_tree_destroy( md->domaintree ); 118 md->domaintree = NULL; 105 119 106 120 while( md->grpq ) … … 174 188 { 175 189 char buf[1024]; 190 char *uux; 176 191 struct msn_data *md = ic->proto_data; 177 192 … … 182 197 183 198 g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, md->away_state->code ); 184 msn_write( ic, buf, strlen( buf ) ); 185 } 186 187 static void msn_set_my_name( struct im_connection *ic, char *info ) 188 { 189 msn_set_display_name( ic, info ); 199 if( !msn_write( ic, buf, strlen( buf ) ) ) 200 return; 201 202 uux = g_markup_printf_escaped( "<Data><PSM>%s</PSM><CurrentMedia></CurrentMedia>" 203 "</Data>", message ? message : "" ); 204 g_snprintf( buf, sizeof( buf ), "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux ); 205 if( !msn_write( ic, buf, strlen( buf ) ) ) 206 return; 190 207 } 191 208 … … 314 331 account_t *acc = set->data; 315 332 struct im_connection *ic = acc->ic; 316 317 /* Allow any name if we're offline. */ 318 if( ic == NULL ) 319 return value; 333 struct msn_data *md = ic->proto_data; 334 char buf[512]; 335 char *fn; 320 336 321 337 if( strlen( value ) > 129 ) … … 325 341 } 326 342 327 /* Returning NULL would be better, because the server still has to 328 confirm the name change. However, it looks a bit confusing to the 329 user. */ 330 return msn_set_display_name( ic, value ) ? value : NULL; 343 msn_soap_addressbook_set_display_name( ic, value ); 344 345 fn = g_malloc( strlen( value ) * 3 + 1 ); 346 strcpy( fn, value ); 347 http_encode( fn ); 348 g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n", 349 ++md->trId, fn ); 350 g_free( fn ); 351 352 /* Note: We don't actually know if the server accepted the new name, 353 and won't give proper feedback yet if it doesn't. */ 354 return msn_write( ic, buf, strlen( buf ) ) ? value : NULL; 355 } 356 357 static void msn_buddy_data_add( bee_user_t *bu ) 358 { 359 struct msn_data *md = bu->ic->proto_data; 360 bu->data = g_new0( struct msn_buddy_data, 1 ); 361 g_tree_insert( md->domaintree, bu->handle, bu ); 362 } 363 364 static void msn_buddy_data_free( bee_user_t *bu ) 365 { 366 struct msn_data *md = bu->ic->proto_data; 367 g_tree_remove( md->domaintree, bu->handle ); 368 g_free( bu->data ); 331 369 } 332 370 … … 343 381 ret->set_away = msn_set_away; 344 382 ret->get_info = msn_get_info; 345 ret->set_my_name = msn_set_my_name;346 383 ret->add_buddy = msn_add_buddy; 347 384 ret->remove_buddy = msn_remove_buddy; … … 357 394 ret->send_typing = msn_send_typing; 358 395 ret->handle_cmp = g_strcasecmp; 396 ret->buddy_data_add = msn_buddy_data_add; 397 ret->buddy_data_free = msn_buddy_data_free; 398 359 399 //ret->transfer_request = msn_ftp_transfer_request; 360 400 -
protocols/msn/msn.h
r136c2bb r07874be 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 … … 39 39 #endif 40 40 41 #define QRY_NAME "msmsgs@msnmsgr.com" 42 #define QRY_CODE "Q1P7W2E4J9R8U3S5" 41 /* This should be MSN Messenger 7.0.0813 42 #define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T" 43 #define MSNP11_PROD_ID "PROD0101{0RM?UBW" 44 */ 45 46 /* Some other version. 47 #define MSNP11_PROD_KEY "O4BG@C7BWLYQX?5G" 48 #define MSNP11_PROD_ID "PROD01065C%ZFN6F" 49 */ 50 51 #define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX" 52 //PK}_A_0N_K%O?A9S" 53 #define MSNP11_PROD_ID "PROD0119GSJUC$18" 54 //PROD0114ES4Z%Q5W" 55 #define MSNP_VER "MSNP15" 56 #define MSNP_BUILD "8.5.1288" 57 //"8.1.0178" 43 58 44 59 #define MSN_SB_NEW -24062002 … … 69 84 70 85 int trId; 86 char *tokens[3]; 87 char *lock_key; 71 88 72 89 GSList *msgq, *grpq; … … 80 97 int groupcount; 81 98 char **grouplist; 99 GTree *domaintree; 82 100 }; 83 101 … … 140 158 int (*exec_command) ( gpointer data, char **cmd, int count ); 141 159 int (*exec_message) ( gpointer data, char *msg, int msglen, char **cmd, int count ); 160 }; 161 162 typedef enum 163 { 164 MSN_BUDDY_FL = 1, /* Warning: FL,AL,BL *must* be 1,2,4. */ 165 MSN_BUDDY_AL = 2, 166 MSN_BUDDY_BL = 4, 167 MSN_BUDDY_RL = 8, 168 MSN_BUDDY_PL = 16, 169 } msn_buddy_flags_t; 170 171 struct msn_buddy_data 172 { 173 char *cid; 174 msn_buddy_flags_t flags; 142 175 }; 143 176 … … 162 195 /* ns.c */ 163 196 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ); 197 void msn_auth_got_passport_token( struct im_connection *ic, char *token ); 198 void msn_auth_got_contact_list( struct im_connection *ic ); 164 199 165 200 /* msn_util.c */ … … 172 207 char **msn_linesplit( char *line ); 173 208 int msn_handler( struct msn_handler_data *h ); 174 char *msn_http_encode( const char *input );175 209 void msn_msgq_purge( struct im_connection *ic, GSList **list ); 176 210 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ); 211 char *msn_p11_challenge( char *challenge ); 212 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ ); 177 213 178 214 /* tables.c */ … … 196 232 void msn_sb_stop_keepalives( struct msn_switchboard *sb ); 197 233 198 /* invitation.c */199 void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );200 201 234 #endif //_MSN_H -
protocols/msn/msn_util.c
r136c2bb r07874be 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" 28 29 #include <ctype.h> 29 30 … … 32 33 struct msn_data *md = ic->proto_data; 33 34 int st; 35 36 if( getenv( "BITLBEE_DEBUG" ) ) 37 { 38 write( 2, "->NS:", 5 ); 39 write( 2, s, len ); 40 } 34 41 35 42 st = write( md->fd, s, len ); … … 54 61 { 55 62 struct msn_data *md = ic->proto_data; 56 char buf[1024], *realname, groupid[8];63 char buf[1024], realname[strlen(realname_)*3+1], groupid[8]; 57 64 58 65 *groupid = '\0'; … … 87 94 if( l == NULL ) 88 95 { 89 char *groupname = msn_http_encode( group ); 96 char groupname[strlen(group)+1]; 97 strcpy( groupname, group ); 98 http_encode( groupname ); 90 99 g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); 91 g_free( groupname );92 100 return msn_write( ic, buf, strlen( buf ) ); 93 101 } … … 102 110 } 103 111 104 realname = msn_http_encode( realname_ ); 112 strcpy( realname, realname_ ); 113 http_encode( realname ); 105 114 g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid ); 106 g_free( realname );107 115 108 116 return msn_write( ic, buf, strlen( buf ) ); … … 279 287 if( st <= 0 ) 280 288 return( -1 ); 289 290 if( getenv( "BITLBEE_DEBUG" ) ) 291 { 292 write( 2, "->C:", 4 ); 293 write( 2, h->rxq + h->rxlen - st, st ); 294 } 281 295 282 296 while( st ) … … 367 381 } 368 382 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 383 void msn_msgq_purge( struct im_connection *ic, GSList **list ) 396 384 { … … 433 421 } 434 422 435 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ) 436 { 437 char *fn = msn_http_encode( rawname ); 438 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 } 423 /* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */ 424 char *msn_p11_challenge( char *challenge ) 425 { 426 char *output, buf[256]; 427 md5_state_t md5c; 428 unsigned char md5Hash[16], *newHash; 429 unsigned int *md5Parts, *chlStringParts, newHashParts[5]; 430 long long nHigh = 0, nLow = 0; 431 int i, n; 432 433 /* Create the MD5 hash */ 434 md5_init(&md5c); 435 md5_append(&md5c, (unsigned char*) challenge, strlen(challenge)); 436 md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY)); 437 md5_finish(&md5c, md5Hash); 438 439 /* Split it into four integers */ 440 md5Parts = (unsigned int *)md5Hash; 441 for (i = 0; i < 4; i ++) 442 { 443 md5Parts[i] = GUINT32_TO_LE(md5Parts[i]); 444 445 /* & each integer with 0x7FFFFFFF */ 446 /* and save one unmodified array for later */ 447 newHashParts[i] = md5Parts[i]; 448 md5Parts[i] &= 0x7FFFFFFF; 449 } 450 451 /* make a new string and pad with '0' */ 452 n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID); 453 /* truncate at an 8-byte boundary */ 454 buf[n&=~7] = '\0'; 455 456 /* split into integers */ 457 chlStringParts = (unsigned int *)buf; 458 459 /* this is magic */ 460 for (i = 0; i < (n / 4) - 1; i += 2) 461 { 462 long long temp; 463 464 chlStringParts[i] = GUINT32_TO_LE(chlStringParts[i]); 465 chlStringParts[i+1] = GUINT32_TO_LE(chlStringParts[i+1]); 466 467 temp = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF; 468 nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF; 469 nLow = nLow + nHigh + temp; 470 } 471 nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF; 472 nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF; 473 474 newHashParts[0] ^= nHigh; 475 newHashParts[1] ^= nLow; 476 newHashParts[2] ^= nHigh; 477 newHashParts[3] ^= nLow; 478 479 /* swap more bytes if big endian */ 480 for (i = 0; i < 4; i ++) 481 newHashParts[i] = GUINT32_TO_LE(newHashParts[i]); 482 483 /* make a string of the parts */ 484 newHash = (unsigned char *)newHashParts; 485 486 /* convert to hexadecimal */ 487 output = g_new(char, 33); 488 for (i = 0; i < 16; i ++) 489 sprintf(output + i * 2, "%02x", newHash[i]); 490 491 return output; 492 } 493 494 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ ) 495 { 496 const char *a = a_, *b = b_; 497 gint ret; 498 499 if( !( a = strchr( a, '@' ) ) || !( b = strchr( b, '@' ) ) || 500 ( ret = strcmp( a, b ) ) == 0 ) 501 ret = strcmp( a_, b_ ); 502 503 return ret; 504 } -
protocols/msn/ns.c
r136c2bb r07874be 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 … … 27 27 #include "nogaim.h" 28 28 #include "msn.h" 29 #include "passport.h"30 29 #include "md5.h" 30 #include "soap.h" 31 #include "xmltree.h" 31 32 32 33 static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond ); … … 34 35 static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); 35 36 36 static void msn_auth_got_passport_token( struct msn_auth_data *mad ); 37 static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name ); 37 static void msn_ns_send_adl( struct im_connection *ic ); 38 38 39 39 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) … … 73 73 md->handler->rxq = g_new0( char, 1 ); 74 74 75 g_snprintf( s, sizeof( s ), "VER %d MSNP8 CVR0\r\n", ++md->trId);75 g_snprintf( s, sizeof( s ), "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ); 76 76 if( msn_write( ic, s, strlen( s ) ) ) 77 77 { … … 113 113 if( strcmp( cmd[0], "VER" ) == 0 ) 114 114 { 115 if( cmd[2] && strncmp( cmd[2], "MSNP8", 5 ) != 0 )115 if( cmd[2] && strncmp( cmd[2], MSNP_VER, 5 ) != 0 ) 116 116 { 117 117 imcb_error( ic, "Unsupported protocol" ); … … 127 127 { 128 128 /* We don't give a damn about the information we just received */ 129 g_snprintf( buf, sizeof( buf ), "USR %d TWNI %s\r\n", ++md->trId, ic->acc->user );129 g_snprintf( buf, sizeof( buf ), "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user ); 130 130 return( msn_write( ic, buf, strlen( buf ) ) ); 131 131 } … … 135 135 int port; 136 136 137 if( num_parts == 6 && strcmp( cmd[2], "NS" ) == 0 )137 if( num_parts >= 6 && strcmp( cmd[2], "NS" ) == 0 ) 138 138 { 139 139 b_event_remove( ic->inpa ); … … 156 156 md->fd = proxy_connect( server, port, msn_ns_connected, ic ); 157 157 } 158 else if( num_parts == 6 && strcmp( cmd[2], "SB" ) == 0 )158 else if( num_parts >= 6 && strcmp( cmd[2], "SB" ) == 0 ) 159 159 { 160 160 struct msn_switchboard *sb; … … 220 220 else if( strcmp( cmd[0], "USR" ) == 0 ) 221 221 { 222 if( num_parts == 5 && strcmp( cmd[2], "TWN" ) == 0 && strcmp( cmd[3], "S" ) == 0 ) 223 { 224 /* Time for some Passport black magic... */ 225 if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) ) 226 { 227 imcb_error( ic, "Error while contacting Passport server" ); 228 imc_logout( ic, TRUE ); 229 return( 0 ); 230 } 231 } 232 else if( num_parts >= 7 && strcmp( cmd[2], "OK" ) == 0 ) 233 { 234 if( num_parts == 7 ) 235 msn_ns_got_display_name( ic, cmd[4] ); 236 else 237 imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); 238 222 if( num_parts >= 6 && strcmp( cmd[2], "SSO" ) == 0 && 223 strcmp( cmd[3], "S" ) == 0 ) 224 { 225 msn_soap_passport_sso_request( ic, cmd[4], cmd[5] ); 226 } 227 else if( strcmp( cmd[2], "OK" ) == 0 ) 228 { 239 229 imcb_log( ic, "Authenticated, getting buddy list" ); 240 241 g_snprintf( buf, sizeof( buf ), "SYN %d 0\r\n", ++md->trId ); 242 return( msn_write( ic, buf, strlen( buf ) ) ); 230 msn_soap_memlist_request( ic ); 243 231 } 244 232 else … … 251 239 else if( strcmp( cmd[0], "MSG" ) == 0 ) 252 240 { 253 if( num_parts !=4 )241 if( num_parts < 4 ) 254 242 { 255 243 imcb_error( ic, "Syntax error" ); … … 267 255 } 268 256 } 269 else if( strcmp( cmd[0], "SYN" ) == 0 ) 270 { 271 if( num_parts == 5 ) 272 { 273 int i, groupcount; 274 275 groupcount = atoi( cmd[4] ); 276 if( groupcount > 0 ) 277 { 278 /* valgrind says this is leaking memory, I'm guessing 279 that this happens during server redirects. */ 280 if( md->grouplist ) 281 { 282 for( i = 0; i < md->groupcount; i ++ ) 283 g_free( md->grouplist[i] ); 284 g_free( md->grouplist ); 285 } 286 287 md->groupcount = groupcount; 288 md->grouplist = g_new0( char *, md->groupcount ); 289 } 290 291 md->buddycount = atoi( cmd[3] ); 292 if( !*cmd[3] || md->buddycount == 0 ) 293 msn_logged_in( ic ); 294 } 295 else 296 { 297 /* Hrrm... This SYN reply doesn't really look like something we expected. 298 Let's assume everything is okay. */ 299 300 msn_logged_in( ic ); 301 } 302 } 303 else if( strcmp( cmd[0], "LST" ) == 0 ) 304 { 305 int list; 306 307 if( num_parts != 4 && num_parts != 5 ) 308 { 309 imcb_error( ic, "Syntax error" ); 310 imc_logout( ic, TRUE ); 311 return( 0 ); 312 } 313 314 http_decode( cmd[2] ); 315 list = atoi( cmd[3] ); 316 317 if( list & 1 ) /* FL */ 318 { 319 char *group = NULL; 320 int num; 321 322 if( cmd[4] != NULL && sscanf( cmd[4], "%d", &num ) == 1 && num < md->groupcount ) 323 group = md->grouplist[num]; 324 325 imcb_add_buddy( ic, cmd[1], group ); 326 imcb_rename_buddy( ic, cmd[1], cmd[2] ); 327 } 328 if( list & 2 ) /* AL */ 329 { 330 ic->permit = g_slist_append( ic->permit, g_strdup( cmd[1] ) ); 331 } 332 if( list & 4 ) /* BL */ 333 { 334 ic->deny = g_slist_append( ic->deny, g_strdup( cmd[1] ) ); 335 } 336 if( list & 8 ) /* RL */ 337 { 338 if( ( list & 6 ) == 0 ) 339 msn_buddy_ask( ic, cmd[1], cmd[2] ); 340 } 341 342 if( --md->buddycount == 0 ) 343 { 344 if( ic->flags & OPT_LOGGED_IN ) 345 { 346 imcb_log( ic, "Successfully transferred to different server" ); 347 g_snprintf( buf, sizeof( buf ), "CHG %d %s %d\r\n", ++md->trId, md->away_state->code, 0 ); 348 return( msn_write( ic, buf, strlen( buf ) ) ); 349 } 350 else 351 { 352 msn_logged_in( ic ); 353 } 354 } 355 } 356 else if( strcmp( cmd[0], "LSG" ) == 0 ) 357 { 358 int num; 359 360 if( num_parts != 4 ) 361 { 362 imcb_error( ic, "Syntax error" ); 363 imc_logout( ic, TRUE ); 364 return( 0 ); 365 } 366 367 http_decode( cmd[2] ); 368 num = atoi( cmd[1] ); 369 370 if( num < md->groupcount ) 371 md->grouplist[num] = g_strdup( cmd[2] ); 257 else if( strcmp( cmd[0], "BLP" ) == 0 ) 258 { 259 msn_ns_send_adl( ic ); 260 } 261 else if( strcmp( cmd[0], "ADL" ) == 0 ) 262 { 263 if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 ) 264 { 265 char buf[1024]; 266 char *fn_raw = set_getstr( &ic->acc->set, "display_name" ); 267 char *fn; 268 269 if( fn_raw == NULL ) 270 fn_raw = ic->acc->user; 271 fn = g_malloc( strlen( fn_raw ) * 3 + 1 ); 272 strcpy( fn, fn_raw ); 273 http_encode( fn ); 274 275 g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n", 276 ++md->trId, fn ); 277 g_free( fn ); 278 279 msn_write( ic, buf, strlen( buf ) ); 280 } 281 } 282 else if( strcmp( cmd[0], "PRP" ) == 0 ) 283 { 284 imcb_connected( ic ); 372 285 } 373 286 else if( strcmp( cmd[0], "CHL" ) == 0 ) 374 287 { 375 md5_state_t state; 376 md5_byte_t digest[16]; 377 int i; 378 379 if( num_parts != 3 ) 380 { 381 imcb_error( ic, "Syntax error" ); 382 imc_logout( ic, TRUE ); 383 return( 0 ); 384 } 385 386 md5_init( &state ); 387 md5_append( &state, (const md5_byte_t *) cmd[2], strlen( cmd[2] ) ); 388 md5_append( &state, (const md5_byte_t *) QRY_CODE, strlen( QRY_CODE ) ); 389 md5_finish( &state, digest ); 390 391 g_snprintf( buf, sizeof( buf ), "QRY %d %s %d\r\n", ++md->trId, QRY_NAME, 32 ); 392 for( i = 0; i < 16; i ++ ) 393 g_snprintf( buf + strlen( buf ), 3, "%02x", digest[i] ); 288 char *resp; 289 290 if( num_parts < 3 ) 291 { 292 imcb_error( ic, "Syntax error" ); 293 imc_logout( ic, TRUE ); 294 return( 0 ); 295 } 296 297 resp = msn_p11_challenge( cmd[2] ); 298 g_snprintf( buf, sizeof( buf ), "QRY %d %s %zd\r\n%s", 299 ++md->trId, MSNP11_PROD_ID, 300 strlen( resp ), resp ); 301 g_free( resp ); 394 302 395 303 return( msn_write( ic, buf, strlen( buf ) ) ); … … 399 307 const struct msn_away_state *st; 400 308 401 if( num_parts !=6 )402 { 403 imcb_error( ic, "Syntax error" ); 404 imc_logout( ic, TRUE ); 405 return( 0 ); 406 } 407 408 http_decode( cmd[ 4] );409 imcb_rename_buddy( ic, cmd[3], cmd[ 4] );309 if( num_parts < 6 ) 310 { 311 imcb_error( ic, "Syntax error" ); 312 imc_logout( ic, TRUE ); 313 return( 0 ); 314 } 315 316 http_decode( cmd[5] ); 317 imcb_rename_buddy( ic, cmd[3], cmd[5] ); 410 318 411 319 st = msn_away_state_by_code( cmd[2] ); … … 433 341 const struct msn_away_state *st; 434 342 435 if( num_parts !=5 )436 { 437 imcb_error( ic, "Syntax error" ); 438 imc_logout( ic, TRUE ); 439 return( 0 ); 440 } 441 442 http_decode( cmd[ 3] );443 imcb_rename_buddy( ic, cmd[2], cmd[ 3] );343 if( num_parts < 5 ) 344 { 345 imcb_error( ic, "Syntax error" ); 346 imc_logout( ic, TRUE ); 347 return( 0 ); 348 } 349 350 http_decode( cmd[4] ); 351 imcb_rename_buddy( ic, cmd[2], cmd[4] ); 444 352 445 353 st = msn_away_state_by_code( cmd[1] ); … … 462 370 int session, port; 463 371 464 if( num_parts !=7 )372 if( num_parts < 7 ) 465 373 { 466 374 imcb_error( ic, "Syntax error" ); … … 506 414 else if( strcmp( cmd[0], "ADD" ) == 0 ) 507 415 { 508 if( num_parts == 6 && strcmp( cmd[2], "RL" ) == 0 )416 if( num_parts >= 6 && strcmp( cmd[2], "RL" ) == 0 ) 509 417 { 510 418 GSList *l; … … 565 473 return( 0 ); 566 474 } 567 #if 0568 /* Discard this one completely for now since I don't care about the ack569 and since MSN servers can apparently screw up the formatting. */570 else if( strcmp( cmd[0], "REA" ) == 0 )571 {572 if( num_parts != 5 )573 {574 imcb_error( ic, "Syntax error" );575 imc_logout( ic, TRUE );576 return( 0 );577 }578 579 if( g_strcasecmp( cmd[3], ic->acc->user ) == 0 )580 {581 set_t *s;582 583 http_decode( cmd[4] );584 strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) );585 ic->displayname[sizeof(ic->displayname)-1] = 0;586 587 if( ( s = set_find( &ic->acc->set, "display_name" ) ) )588 {589 g_free( s->value );590 s->value = g_strdup( cmd[4] );591 }592 }593 else594 {595 /* This is not supposed to happen, but let's handle it anyway... */596 http_decode( cmd[4] );597 imcb_rename_buddy( ic, cmd[3], cmd[4] );598 }599 }600 #endif601 475 else if( strcmp( cmd[0], "IPG" ) == 0 ) 602 476 { … … 655 529 } 656 530 } 531 } 532 else if( strcmp( cmd[0], "GCF" ) == 0 ) 533 { 534 /* Coming up is cmd[2] bytes of stuff we're supposed to 535 censore. Meh. */ 536 md->handler->msglen = atoi( cmd[2] ); 537 } 538 else if( strcmp( cmd[0], "UBX" ) == 0 ) 539 { 540 /* Status message. Parser coming soon. */ 541 if( num_parts >= 4 ) 542 md->handler->msglen = atoi( cmd[3] ); 543 } 544 else if( strcmp( cmd[0], "NOT" ) == 0 ) 545 { 546 /* Some kind of notification, not sure if it still exists 547 but we have to skip the payload or stuff breaks. */ 548 if( num_parts >= 3 ) 549 md->handler->msglen = atoi( cmd[2] ); 657 550 } 658 551 else if( isdigit( cmd[0][0] ) ) … … 765 658 } 766 659 } 660 else if( strcmp( cmd[0], "UBX" ) == 0 ) 661 { 662 struct xt_node *psm; 663 char *psm_text = NULL; 664 665 psm = xt_from_string( msg ); 666 if( psm && strcmp( psm->name, "Data" ) == 0 && 667 ( psm = xt_find_node( psm->children, "PSM" ) ) ) 668 psm_text = psm->text; 669 670 imcb_buddy_status_msg( ic, cmd[1], psm_text ); 671 xt_free_node( psm ); 672 } 767 673 768 674 return( 1 ); 769 675 } 770 676 771 static void msn_auth_got_passport_token( struct msn_auth_data *mad)677 void msn_auth_got_passport_token( struct im_connection *ic, char *token ) 772 678 { 773 struct im_connection *ic = mad->data;774 679 struct msn_data *md; 775 680 … … 779 684 780 685 md = ic->proto_data; 781 if( mad->token )686 782 687 { 783 688 char buf[1024]; 784 689 785 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );690 g_snprintf( buf, sizeof( buf ), "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token ); 786 691 msn_write( ic, buf, strlen( buf ) ); 787 692 } 788 else789 {790 imcb_error( ic, "Error during Passport authentication: %s", mad->error );791 imc_logout( ic, TRUE );792 }793 693 } 794 694 795 static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name)695 void msn_auth_got_contact_list( struct im_connection *ic ) 796 696 { 797 set_t *s; 798 799 if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL ) 800 return FALSE; /* Shouldn't happen.. */ 801 802 http_decode( name ); 803 804 if( s->value && strcmp( s->value, name ) == 0 ) 805 { 806 return TRUE; 807 /* The names match, nothing to worry about. */ 808 } 809 else if( s->value != NULL && 810 ( strcmp( name, ic->acc->user ) == 0 || 811 set_getbool( &ic->acc->set, "local_display_name" ) ) ) 812 { 813 /* The server thinks our display name is our e-mail address 814 which is probably wrong, or the user *wants* us to do this: 815 Always use the locally set display_name. */ 816 return msn_set_display_name( ic, s->value ); 817 } 818 else 819 { 820 if( s->value && *s->value ) 821 imcb_log( ic, "BitlBee thinks your display name is `%s' but " 822 "the MSN server says it's `%s'. Using the MSN " 823 "server's name. Set local_display_name to true " 824 "to use the local name.", s->value, name ); 825 826 if( g_utf8_validate( name, -1, NULL ) ) 827 { 828 g_free( s->value ); 829 s->value = g_strdup( name ); 830 } 831 else 832 { 833 imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); 834 } 835 836 return TRUE; 837 } 697 char buf[64]; 698 struct msn_data *md; 699 700 /* Dead connection? */ 701 if( g_slist_find( msn_connections, ic ) == NULL ) 702 return; 703 704 md = ic->proto_data; 705 706 707 g_snprintf( buf, sizeof( buf ), "BLP %d %s\r\n", ++md->trId, "BL" ); 708 msn_write( ic, buf, strlen( buf ) ); 838 709 } 710 711 static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data ) 712 { 713 struct xt_node *adl = data, *d, *c; 714 struct bee_user *bu = value; 715 struct msn_buddy_data *bd = bu->data; 716 char handle[strlen(bu->handle)]; 717 char *domain; 718 char l[4]; 719 720 strcpy( handle, bu->handle ); 721 if( ( domain = strchr( handle, '@' ) ) == NULL ) /* WTF */ 722 return FALSE; 723 *domain = '\0'; 724 domain ++; 725 726 if( ( d = adl->children ) == NULL || 727 g_strcasecmp( xt_find_attr( d, "n" ), domain ) != 0 ) 728 { 729 d = xt_new_node( "d", NULL, NULL ); 730 xt_add_attr( d, "n", domain ); 731 xt_insert_child( adl, d ); 732 } 733 734 g_snprintf( l, sizeof( l ), "%d", bd->flags & 7 ); 735 c = xt_new_node( "c", NULL, NULL ); 736 xt_add_attr( c, "n", handle ); 737 xt_add_attr( c, "l", l ); 738 xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */ 739 xt_insert_child( d, c ); 740 741 return FALSE; 742 } 743 744 static void msn_ns_send_adl( struct im_connection *ic ) 745 { 746 struct xt_node *adl; 747 struct msn_data *md; 748 char *adls, buf[64]; 749 750 /* Dead connection? */ 751 if( g_slist_find( msn_connections, ic ) == NULL ) 752 return; 753 754 md = ic->proto_data; 755 756 adl = xt_new_node( "ml", NULL, NULL ); 757 xt_add_attr( adl, "l", "1" ); 758 g_tree_foreach( md->domaintree, msn_ns_send_adl_1, adl ); 759 adls = xt_to_string( adl ); 760 761 g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n", ++md->trId, strlen( adls ) ); 762 if( msn_write( ic, buf, strlen( buf ) ) ) 763 msn_write( ic, adls, strlen( adls ) ); 764 765 g_free( adls ); 766 xt_free_node( adl ); 767 } -
protocols/msn/sb.c
r136c2bb r07874be 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 05Wilmer van der Gaast and others *4 * Copyright 2002-2010 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 27 27 #include "nogaim.h" 28 28 #include "msn.h" 29 #include "passport.h"30 29 #include "md5.h" 30 #include "soap.h" 31 31 #include "invitation.h" 32 32 … … 38 38 { 39 39 int st; 40 41 if( getenv( "BITLBEE_DEBUG" ) ) 42 { 43 write( 2, "->SB:", 5 ); 44 write( 2, s, len ); 45 } 40 46 41 47 st = write( sb->fd, s, len ); … … 407 413 else if( strcmp( cmd[0], "USR" ) == 0 ) 408 414 { 409 if( num_parts !=5 )415 if( num_parts < 5 ) 410 416 { 411 417 msn_sb_destroy( sb ); … … 433 439 int num, tot; 434 440 435 if( num_parts !=6 )441 if( num_parts < 6 ) 436 442 { 437 443 msn_sb_destroy( sb ); … … 470 476 else if( strcmp( cmd[0], "ANS" ) == 0 ) 471 477 { 472 if( num_parts !=3 )478 if( num_parts < 3 ) 473 479 { 474 480 msn_sb_destroy( sb ); … … 489 495 else if( strcmp( cmd[0], "CAL" ) == 0 ) 490 496 { 491 if( num_parts !=4 || !isdigit( cmd[3][0] ) )497 if( num_parts < 4 || !isdigit( cmd[3][0] ) ) 492 498 { 493 499 msn_sb_destroy( sb ); … … 499 505 else if( strcmp( cmd[0], "JOI" ) == 0 ) 500 506 { 501 if( num_parts !=3 )507 if( num_parts < 3 ) 502 508 { 503 509 msn_sb_destroy( sb ); … … 560 566 else if( strcmp( cmd[0], "MSG" ) == 0 ) 561 567 { 562 if( num_parts !=4 )568 if( num_parts < 4 ) 563 569 { 564 570 msn_sb_destroy( sb ); … … 625 631 const struct msn_status_code *err = msn_status_by_number( num ); 626 632 627 imcb_error( ic, "Error reported by switchboard server: %s", err->text ); 633 /* If the person is offline, send an offline message instead, 634 and don't report an error. */ 635 if( num == 217 ) 636 msn_soap_oim_send_queue( ic, &sb->msgq ); 637 else 638 imcb_error( ic, "Error reported by switchboard server: %s", err->text ); 628 639 629 640 if( err->flags & STATUS_SB_FATAL ) -
protocols/msn/tables.c
r136c2bb r07874be 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 -
protocols/nogaim.c
r136c2bb r07874be 326 326 imcb_log( ic, "Signing off.." ); 327 327 328 b_event_remove( ic->keepalive );329 ic->keepalive = 0;330 ic->acc->prpl->logout( ic );331 b_event_remove( ic->inpa );332 333 g_free( ic->away );334 ic->away = NULL;335 336 328 for( l = bee->users; l; ) 337 329 { … … 344 336 l = next; 345 337 } 338 339 b_event_remove( ic->keepalive ); 340 ic->keepalive = 0; 341 ic->acc->prpl->logout( ic ); 342 b_event_remove( ic->inpa ); 343 344 g_free( ic->away ); 345 ic->away = NULL; 346 346 347 347 query_del_by_conn( (irc_t*) ic->bee->ui_data, ic ); -
protocols/nogaim.h
r136c2bb r07874be 194 194 this info via imcb_log(). Implementing these are optional. */ 195 195 void (* get_info) (struct im_connection *, char *who); 196 /* set_my_name is *DEPRECATED*, not used by the UI anymore. Use the 197 display_name setting instead. */ 196 198 void (* set_my_name) (struct im_connection *, char *name); 197 199 void (* set_name) (struct im_connection *, char *who, char *name); -
storage_xml.c
r136c2bb r07874be 320 320 else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting ) 321 321 { 322 if( xd->current_account ) 323 { 324 set_t *s = set_find( xd->current_set_head, xd->current_setting ); 325 if( s && ( s->flags & ACC_SET_ONLINE_ONLY ) ) 326 { 327 g_free( xd->current_setting ); 328 xd->current_setting = NULL; 329 return; 330 } 331 } 322 332 set_setstr( xd->current_set_head, xd->current_setting, (char*) text ); 323 333 g_free( xd->current_setting );
Note: See TracChangeset
for help on using the changeset viewer.