comparison libpurple/protocols/jabber/jabber.c @ 29860:3a5194c70b38

jabber: A bunch of paranoia-induced Cyrus SASL changes. i.e. "Let's check return codes!" This was all inspired because "if (len == -1) len = strlen(data)" was being called in three places! The "SASL error: %s" string is from auth_cyrus.c
author Paul Aurich <paul@darkrain42.org>
date Sat, 01 May 2010 18:03:52 +0000
parents 2829dd1cc118
children 417a4e912738
comparison
equal deleted inserted replaced
29859:a97ddee04b78 29860:3a5194c70b38
362 static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len) 362 static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len)
363 { 363 {
364 int ret; 364 int ret;
365 gboolean success = TRUE; 365 gboolean success = TRUE;
366 366
367 if (len == -1) 367 g_return_val_if_fail(len > 0, FALSE);
368 len = strlen(data);
369 368
370 if (js->state == JABBER_STREAM_CONNECTED) 369 if (js->state == JABBER_STREAM_CONNECTED)
371 jabber_stream_restart_inactivity_timer(js); 370 jabber_stream_restart_inactivity_timer(js);
372 371
373 if (js->writeh == 0) 372 if (js->writeh == 0)
407 return success; 406 return success;
408 } 407 }
409 408
410 void jabber_send_raw(JabberStream *js, const char *data, int len) 409 void jabber_send_raw(JabberStream *js, const char *data, int len)
411 { 410 {
411 PurpleConnection *gc;
412 PurpleAccount *account;
413
414 gc = js->gc;
415 account = purple_connection_get_account(gc);
416
412 /* because printing a tab to debug every minute gets old */ 417 /* because printing a tab to debug every minute gets old */
413 if(strcmp(data, "\t")) { 418 if(strcmp(data, "\t")) {
414 const char *username; 419 const char *username;
415 char *text = NULL, *last_part = NULL, *tag_start = NULL; 420 char *text = NULL, *last_part = NULL, *tag_start = NULL;
416 421
434 439
435 last_part = strchr(data_start, '<'); 440 last_part = strchr(data_start, '<');
436 *data_start = '\0'; 441 *data_start = '\0';
437 } 442 }
438 443
439 username = purple_connection_get_display_name(js->gc); 444 username = purple_connection_get_display_name(gc);
440 if (!username) 445 if (!username)
441 username = purple_account_get_username(purple_connection_get_account(js->gc)); 446 username = purple_account_get_username(account);
442 447
443 purple_debug_misc("jabber", "Sending%s (%s): %s%s%s\n", 448 purple_debug_misc("jabber", "Sending%s (%s): %s%s%s\n",
444 jabber_stream_is_ssl(js) ? " (ssl)" : "", username, 449 jabber_stream_is_ssl(js) ? " (ssl)" : "", username,
445 text ? text : data, 450 text ? text : data,
446 last_part ? "password removed" : "", 451 last_part ? "password removed" : "",
447 last_part ? last_part : ""); 452 last_part ? last_part : "");
448 453
449 g_free(text); 454 g_free(text);
450 } 455 }
451 456
452 purple_signal_emit(purple_connection_get_prpl(js->gc), "jabber-sending-text", js->gc, &data); 457 purple_signal_emit(purple_connection_get_prpl(gc), "jabber-sending-text", gc, &data);
453 if (data == NULL) 458 if (data == NULL)
454 return; 459 return;
460
461 if (len == -1)
462 len = strlen(data);
455 463
456 /* If we've got a security layer, we need to encode the data, 464 /* If we've got a security layer, we need to encode the data,
457 * splitting it on the maximum buffer length negotiated */ 465 * splitting it on the maximum buffer length negotiated */
458 #ifdef HAVE_CYRUS_SASL 466 #ifdef HAVE_CYRUS_SASL
459 if (js->sasl_maxbuf>0) { 467 if (js->sasl_maxbuf>0) {
460 int pos = 0; 468 int pos = 0;
461 469
462 if (!js->gsc && js->fd<0) 470 if (!js->gsc && js->fd<0)
463 g_return_if_reached(); 471 g_return_if_reached();
464 472
465 if (len == -1)
466 len = strlen(data);
467
468 while (pos < len) { 473 while (pos < len) {
469 int towrite; 474 int towrite;
470 const char *out; 475 const char *out;
471 unsigned olen; 476 unsigned olen;
477 int rc;
472 478
473 towrite = MIN((len - pos), js->sasl_maxbuf); 479 towrite = MIN((len - pos), js->sasl_maxbuf);
474 480
475 sasl_encode(js->sasl, &data[pos], towrite, &out, &olen); 481 rc = sasl_encode(js->sasl, &data[pos], towrite,
482 &out, &olen);
483 if (rc != SASL_OK) {
484 gchar *error =
485 g_strdup_printf(_("SASL error: %s"),
486 sasl_errdetail(js->sasl));
487 purple_debug_error("jabber",
488 "sasl_encode error %d: %s\n", rc,
489 sasl_errdetail(js->sasl));
490 purple_connection_error_reason(gc,
491 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
492 error);
493 g_free(error);
494 return;
495 }
476 pos += towrite; 496 pos += towrite;
477 497
498 /* do_jabber_send_raw returns FALSE when it throws a
499 * connection error.
500 */
478 if (!do_jabber_send_raw(js, out, olen)) 501 if (!do_jabber_send_raw(js, out, olen))
479 break; 502 break;
480 } 503 }
481 return; 504 return;
482 } 505 }
483 #endif 506 #endif
484
485 if (len == -1)
486 len = strlen(data);
487 507
488 if (js->bosh) 508 if (js->bosh)
489 jabber_bosh_connection_send_raw(js->bosh, data); 509 jabber_bosh_connection_send_raw(js->bosh, data);
490 else 510 else
491 do_jabber_send_raw(js, data, len); 511 do_jabber_send_raw(js, data, len);
492 } 512 }
493 513
494 int jabber_prpl_send_raw(PurpleConnection *gc, const char *buf, int len) 514 int jabber_prpl_send_raw(PurpleConnection *gc, const char *buf, int len)
495 { 515 {
496 JabberStream *js = (JabberStream*)gc->proto_data; 516 JabberStream *js = purple_connection_get_protocol_data(gc);
497 jabber_send_raw(js, buf, len); 517 jabber_send_raw(js, buf, len);
498 return len; 518 return len;
499 } 519 }
500 520
501 void jabber_send_signal_cb(PurpleConnection *pc, xmlnode **packet, 521 void jabber_send_signal_cb(PurpleConnection *pc, xmlnode **packet,
595 615
596 static void 616 static void
597 jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition) 617 jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition)
598 { 618 {
599 PurpleConnection *gc = data; 619 PurpleConnection *gc = data;
600 JabberStream *js = gc->proto_data; 620 JabberStream *js = purple_connection_get_protocol_data(gc);
601 int len; 621 int len;
602 static char buf[4096]; 622 static char buf[4096];
603 623
604 if(!PURPLE_CONNECTION_IS_VALID(gc)) 624 if(!PURPLE_CONNECTION_IS_VALID(gc))
605 return; 625 return;
606 626
607 if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) { 627 if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) {
608 gc->last_received = time(NULL); 628 gc->last_received = time(NULL);
609 #ifdef HAVE_CYRUS_SASL 629 #ifdef HAVE_CYRUS_SASL
610 if (js->sasl_maxbuf>0) { 630 if (js->sasl_maxbuf > 0) {
611 const char *out; 631 const char *out;
612 unsigned int olen; 632 unsigned int olen;
613 sasl_decode(js->sasl, buf, len, &out, &olen); 633 int rc;
614 if (olen>0) { 634
635 rc = sasl_decode(js->sasl, buf, len, &out, &olen);
636 if (rc != SASL_OK) {
637 gchar *error =
638 g_strdup_printf(_("SASL error: %s"),
639 sasl_errdetail(js->sasl));
640 purple_debug_error("jabber",
641 "sasl_decode_error %d: %s\n", rc,
642 sasl_errdetail(js->sasl));
643 purple_connection_error_reason(gc,
644 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
645 error);
646 } else if (olen > 0) {
615 purple_debug_info("jabber", "RecvSASL (%u): %s\n", olen, out); 647 purple_debug_info("jabber", "RecvSASL (%u): %s\n", olen, out);
616 jabber_parser_process(js,out,olen); 648 jabber_parser_process(js, out, olen);
617 if(js->reinit) 649 if (js->reinit)
618 jabber_stream_init(js); 650 jabber_stream_init(js);
619 } 651 }
620 return; 652 return;
621 } 653 }
622 #endif 654 #endif