Mercurial > pidgin
comparison libpurple/protocols/jabber/si.c @ 25556:0d7f02640e2b
Make sure that the buffer is large enough to fit DST.ADDR + DST.PORT. This was found in the analysis that Veracode performed on the pidgin codebase.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Sat, 02 May 2009 17:43:14 +0000 |
parents | 61e0924de04a |
children | ab298d237562 |
comparison
equal
deleted
inserted
replaced
25555:62e619e4957e | 25556:0d7f02640e2b |
---|---|
352 jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source, | 352 jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source, |
353 PurpleInputCondition cond) | 353 PurpleInputCondition cond) |
354 { | 354 { |
355 PurpleXfer *xfer = data; | 355 PurpleXfer *xfer = data; |
356 JabberSIXfer *jsx = xfer->data; | 356 JabberSIXfer *jsx = xfer->data; |
357 char buffer[256]; | 357 char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/ |
358 int len; | 358 int len; |
359 char *dstaddr, *hash; | 359 char *dstaddr, *hash; |
360 const char *host; | 360 const char *host; |
361 | 361 |
362 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_again_cb\n"); | 362 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_again_cb\n"); |
376 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 376 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
377 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 377 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
378 jsx->rxlen += len; | 378 jsx->rxlen += len; |
379 return; | 379 return; |
380 } else if(jsx->rxqueue[0] != 0x05 || jsx->rxqueue[1] != 0x01 || | 380 } else if(jsx->rxqueue[0] != 0x05 || jsx->rxqueue[1] != 0x01 || |
381 jsx->rxqueue[3] != 0x03) { | 381 jsx->rxqueue[3] != 0x03 || jsx->rxqueue[4] != 40) { |
382 purple_debug_info("jabber", "invalid socks5 stuff\n"); | 382 purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n", |
383 jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2], | |
384 jsx->rxqueue[3], jsx->rxqueue[4]); | |
383 purple_input_remove(xfer->watcher); | 385 purple_input_remove(xfer->watcher); |
384 xfer->watcher = 0; | 386 xfer->watcher = 0; |
385 close(source); | 387 close(source); |
386 purple_xfer_cancel_remote(xfer); | 388 purple_xfer_cancel_remote(xfer); |
387 return; | 389 return; |
388 } else if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) { | 390 } else if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) { |
389 purple_debug_info("jabber", "reading umpteen more bytes\n"); | 391 purple_debug_info("jabber", "reading %u bytes for DST.ADDR + port num (trying to read %u now)\n", |
390 len = read(source, buffer, jsx->rxqueue[4] + 5 + 2 - jsx->rxlen); | 392 jsx->rxqueue[4] + 2, jsx->rxqueue[4] + 2 - (jsx->rxlen - 5)); |
393 len = read(source, buffer, jsx->rxqueue[4] + 2 - (jsx->rxlen - 5)); | |
391 if(len < 0 && errno == EAGAIN) | 394 if(len < 0 && errno == EAGAIN) |
392 return; | 395 return; |
393 else if(len <= 0) { | 396 else if(len <= 0) { |
394 purple_input_remove(xfer->watcher); | 397 purple_input_remove(xfer->watcher); |
395 xfer->watcher = 0; | 398 xfer->watcher = 0; |
400 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 403 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
401 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 404 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
402 jsx->rxlen += len; | 405 jsx->rxlen += len; |
403 } | 406 } |
404 | 407 |
408 /* Have we not read all of DST.ADDR and the following 2-byte port number? */ | |
405 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) | 409 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) |
406 return; | 410 return; |
407 | 411 |
408 purple_input_remove(xfer->watcher); | 412 purple_input_remove(xfer->watcher); |
409 xfer->watcher = 0; | 413 xfer->watcher = 0; |
413 jsx->js->user->resource, xfer->who); | 417 jsx->js->user->resource, xfer->who); |
414 | 418 |
415 /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */ | 419 /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */ |
416 hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr)); | 420 hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr)); |
417 | 421 |
418 if(jsx->rxqueue[4] != 40 || strncmp(hash, jsx->rxqueue+5, 40) || | 422 if(strncmp(hash, jsx->rxqueue + 5, 40) || |
419 jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) { | 423 jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) { |
420 purple_debug_error("jabber", "someone connected with the wrong info!\n"); | 424 if (jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) |
425 purple_debug_error("jabber", "Got SOCKS5 BS conn with the wrong DST.PORT" | |
426 " (must be 0 - got[0x%x,0x%x]).\n", | |
427 jsx->rxqueue[45], jsx->rxqueue[46]); | |
428 else | |
429 purple_debug_error("jabber", "Got SOCKS5 BS conn with the wrong DST.ADDR" | |
430 " (expected '%s' - got '%.40s').\n", | |
431 hash, jsx->rxqueue + 5); | |
421 close(source); | 432 close(source); |
422 purple_xfer_cancel_remote(xfer); | 433 purple_xfer_cancel_remote(xfer); |
423 g_free(hash); | 434 g_free(hash); |
424 g_free(dstaddr); | 435 g_free(dstaddr); |
425 return; | 436 return; |
476 return; | 487 return; |
477 | 488 |
478 purple_input_remove(xfer->watcher); | 489 purple_input_remove(xfer->watcher); |
479 xfer->watcher = 0; | 490 xfer->watcher = 0; |
480 | 491 |
492 /* If we sent a "Success", wait for a response, otherwise give up and cancel */ | |
481 if (jsx->rxqueue[1] == 0x00) { | 493 if (jsx->rxqueue[1] == 0x00) { |
482 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ, | 494 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ, |
483 jabber_si_xfer_bytestreams_send_read_again_cb, xfer); | 495 jabber_si_xfer_bytestreams_send_read_again_cb, xfer); |
484 g_free(jsx->rxqueue); | 496 g_free(jsx->rxqueue); |
485 jsx->rxqueue = NULL; | 497 jsx->rxqueue = NULL; |
498 jsx->rxlen = 0; | |
486 } else { | 499 } else { |
487 close(source); | 500 close(source); |
488 purple_xfer_cancel_remote(xfer); | 501 purple_xfer_cancel_remote(xfer); |
489 } | 502 } |
490 } | 503 } |
501 | 514 |
502 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n"); | 515 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n"); |
503 | 516 |
504 xfer->fd = source; | 517 xfer->fd = source; |
505 | 518 |
519 /** Try to read the SOCKS5 header */ | |
506 if(jsx->rxlen < 2) { | 520 if(jsx->rxlen < 2) { |
507 purple_debug_info("jabber", "reading those first two bytes\n"); | 521 purple_debug_info("jabber", "reading those first two bytes\n"); |
508 len = read(source, buffer, 2 - jsx->rxlen); | 522 len = read(source, buffer, 2 - jsx->rxlen); |
509 if(len < 0 && errno == EAGAIN) | 523 if(len < 0 && errno == EAGAIN) |
510 return; | 524 return; |
518 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 532 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
519 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 533 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
520 jsx->rxlen += len; | 534 jsx->rxlen += len; |
521 return; | 535 return; |
522 } else if(jsx->rxlen - 2 < jsx->rxqueue[1]) { | 536 } else if(jsx->rxlen - 2 < jsx->rxqueue[1]) { |
523 purple_debug_info("jabber", "reading the next umpteen bytes\n"); | 537 purple_debug_info("jabber", "reading %u bytes for auth methods (trying to read %u now)\n", |
524 len = read(source, buffer, jsx->rxqueue[1] + 2 - jsx->rxlen); | 538 jsx->rxqueue[1], jsx->rxqueue[1] - (jsx->rxlen - 2)); |
539 len = read(source, buffer, jsx->rxqueue[1] - (jsx->rxlen - 2)); | |
525 if(len < 0 && errno == EAGAIN) | 540 if(len < 0 && errno == EAGAIN) |
526 return; | 541 return; |
527 else if(len <= 0) { | 542 else if(len <= 0) { |
528 purple_input_remove(xfer->watcher); | 543 purple_input_remove(xfer->watcher); |
529 xfer->watcher = 0; | 544 xfer->watcher = 0; |
534 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 549 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
535 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 550 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
536 jsx->rxlen += len; | 551 jsx->rxlen += len; |
537 } | 552 } |
538 | 553 |
554 /* Have we not read all the auth. method bytes? */ | |
539 if(jsx->rxlen -2 < jsx->rxqueue[1]) | 555 if(jsx->rxlen -2 < jsx->rxqueue[1]) |
540 return; | 556 return; |
541 | 557 |
542 purple_input_remove(xfer->watcher); | 558 purple_input_remove(xfer->watcher); |
543 xfer->watcher = 0; | 559 xfer->watcher = 0; |