comparison libpurple/protocols/jabber/jingle/rtp.c @ 32380:231c9635b82a

Fix crashes and memory leaks when receiving malformed voice and video requests. Thanks to Thijs Alkemade for reporting this!
author Mark Doliner <mark@kingant.net>
date Tue, 06 Dec 2011 07:06:01 +0000
parents 76b7754ba906
children
comparison
equal deleted inserted replaced
32379:76b7754ba906 32380:231c9635b82a
588 media_type = jingle_rtp_get_media_type(content); 588 media_type = jingle_rtp_get_media_type(content);
589 remote_jid = jingle_session_get_remote_jid(session); 589 remote_jid = jingle_session_get_remote_jid(session);
590 senders = jingle_content_get_senders(content); 590 senders = jingle_content_get_senders(content);
591 transport = jingle_content_get_transport(content); 591 transport = jingle_content_get_transport(content);
592 592
593 if (media_type == NULL) {
594 g_free(name);
595 g_free(remote_jid);
596 g_free(senders);
597 g_free(params);
598 g_object_unref(transport);
599 g_object_unref(session);
600 return FALSE;
601 }
602
593 if (JINGLE_IS_RAWUDP(transport)) 603 if (JINGLE_IS_RAWUDP(transport))
594 transmitter = "rawudp"; 604 transmitter = "rawudp";
595 else if (JINGLE_IS_ICEUDP(transport)) 605 else if (JINGLE_IS_ICEUDP(transport))
596 transmitter = "nice"; 606 transmitter = "nice";
597 else 607 else
598 transmitter = "notransmitter"; 608 transmitter = "notransmitter";
599 g_object_unref(transport); 609 g_object_unref(transport);
600 610
601 is_audio = !strcmp(media_type, "audio"); 611 is_audio = g_str_equal(media_type, "audio");
602 612
603 if (!strcmp(senders, "both")) 613 if (purple_strequal(senders, "both"))
604 type = is_audio == TRUE ? PURPLE_MEDIA_AUDIO 614 type = is_audio ? PURPLE_MEDIA_AUDIO
605 : PURPLE_MEDIA_VIDEO; 615 : PURPLE_MEDIA_VIDEO;
606 else if ((strcmp(senders, "initiator") == 0) == 616 else if (purple_strequal(senders, "initiator") ==
607 jingle_session_is_initiator(session)) 617 jingle_session_is_initiator(session))
608 type = is_audio == TRUE ? PURPLE_MEDIA_SEND_AUDIO 618 type = is_audio ? PURPLE_MEDIA_SEND_AUDIO
609 : PURPLE_MEDIA_SEND_VIDEO; 619 : PURPLE_MEDIA_SEND_VIDEO;
610 else 620 else
611 type = is_audio == TRUE ? PURPLE_MEDIA_RECV_AUDIO 621 type = is_audio ? PURPLE_MEDIA_RECV_AUDIO
612 : PURPLE_MEDIA_RECV_VIDEO; 622 : PURPLE_MEDIA_RECV_VIDEO;
613 623
614 params = 624 params =
615 jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0, 625 jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0,
616 NULL, NULL, &num_params); 626 NULL, NULL, &num_params);
617 627
618 creator = jingle_content_get_creator(content); 628 creator = jingle_content_get_creator(content);
619 if (!strcmp(creator, "initiator")) 629 if (creator == NULL) {
630 g_free(name);
631 g_free(media_type);
632 g_free(remote_jid);
633 g_free(senders);
634 g_free(params);
635 g_object_unref(session);
636 return FALSE;
637 }
638
639 if (g_str_equal(creator, "initiator"))
620 is_creator = jingle_session_is_initiator(session); 640 is_creator = jingle_session_is_initiator(session);
621 else 641 else
622 is_creator = !jingle_session_is_initiator(session); 642 is_creator = !jingle_session_is_initiator(session);
623 g_free(creator); 643 g_free(creator);
624 644
625 if(!purple_media_add_stream(media, name, remote_jid, 645 if(!purple_media_add_stream(media, name, remote_jid,
626 type, is_creator, transmitter, num_params, params)) { 646 type, is_creator, transmitter, num_params, params)) {
627 purple_media_end(media, NULL, NULL); 647 purple_media_end(media, NULL, NULL);
648 /* TODO: How much clean-up is necessary here? (does calling
649 purple_media_end lead to cleaning up Jingle structs?) */
628 return FALSE; 650 return FALSE;
629 } 651 }
630 652
631 g_free(name); 653 g_free(name);
632 g_free(media_type); 654 g_free(media_type);
644 GList *codecs = NULL; 666 GList *codecs = NULL;
645 xmlnode *codec_element = NULL; 667 xmlnode *codec_element = NULL;
646 const char *encoding_name,*id, *clock_rate; 668 const char *encoding_name,*id, *clock_rate;
647 PurpleMediaCodec *codec; 669 PurpleMediaCodec *codec;
648 const gchar *media = xmlnode_get_attrib(description, "media"); 670 const gchar *media = xmlnode_get_attrib(description, "media");
649 PurpleMediaSessionType type = 671 PurpleMediaSessionType type;
650 !strcmp(media, "video") ? PURPLE_MEDIA_VIDEO : 672
651 !strcmp(media, "audio") ? PURPLE_MEDIA_AUDIO : 0; 673 if (media == NULL) {
674 purple_debug_warning("jingle-rtp", "missing media type\n");
675 return NULL;
676 }
677
678 if (g_str_equal(media, "video")) {
679 type = PURPLE_MEDIA_VIDEO;
680 } else if (g_str_equal(media, "audio")) {
681 type = PURPLE_MEDIA_AUDIO;
682 } else {
683 purple_debug_warning("jingle-rtp", "unknown media type: %s\n",
684 media);
685 return NULL;
686 }
652 687
653 for (codec_element = xmlnode_get_child(description, "payload-type") ; 688 for (codec_element = xmlnode_get_child(description, "payload-type") ;
654 codec_element ; 689 codec_element ;
655 codec_element = xmlnode_get_next_twin(codec_element)) { 690 codec_element = xmlnode_get_next_twin(codec_element)) {
656 xmlnode *param; 691 xmlnode *param;
767 jingle_rtp_handle_action_internal(JingleContent *content, xmlnode *xmlcontent, JingleActionType action) 802 jingle_rtp_handle_action_internal(JingleContent *content, xmlnode *xmlcontent, JingleActionType action)
768 { 803 {
769 switch (action) { 804 switch (action) {
770 case JINGLE_SESSION_ACCEPT: 805 case JINGLE_SESSION_ACCEPT:
771 case JINGLE_SESSION_INITIATE: { 806 case JINGLE_SESSION_INITIATE: {
772 JingleSession *session = jingle_content_get_session(content); 807 JingleSession *session;
773 JingleTransport *transport = jingle_transport_parse( 808 JingleTransport *transport;
774 xmlnode_get_child(xmlcontent, "transport")); 809 xmlnode *description;
775 xmlnode *description = xmlnode_get_child(xmlcontent, "description"); 810 GList *candidates;
776 GList *candidates = jingle_rtp_transport_to_candidates(transport); 811 GList *codecs;
777 GList *codecs = jingle_rtp_parse_codecs(description); 812 gchar *name;
778 gchar *name = jingle_content_get_name(content); 813 gchar *remote_jid;
779 gchar *remote_jid =
780 jingle_session_get_remote_jid(session);
781 PurpleMedia *media; 814 PurpleMedia *media;
782 815
816 session = jingle_content_get_session(content);
817
783 if (action == JINGLE_SESSION_INITIATE && 818 if (action == JINGLE_SESSION_INITIATE &&
784 jingle_rtp_init_media(content) == FALSE) { 819 !jingle_rtp_init_media(content)) {
785 /* XXX: send error */ 820 /* XXX: send error */
786 jabber_iq_send(jingle_session_terminate_packet( 821 jabber_iq_send(jingle_session_terminate_packet(
787 session, "general-error")); 822 session, "general-error"));
788 g_object_unref(session); 823 g_object_unref(session);
789 break; 824 break;
790 } 825 }
826
827 transport = jingle_transport_parse(
828 xmlnode_get_child(xmlcontent, "transport"));
829 description = xmlnode_get_child(xmlcontent, "description");
830 candidates = jingle_rtp_transport_to_candidates(transport);
831 codecs = jingle_rtp_parse_codecs(description);
832 name = jingle_content_get_name(content);
833 remote_jid = jingle_session_get_remote_jid(session);
791 834
792 media = jingle_rtp_get_media(session); 835 media = jingle_rtp_get_media(session);
793 purple_media_set_remote_codecs(media, 836 purple_media_set_remote_codecs(media,
794 name, remote_jid, codecs); 837 name, remote_jid, codecs);
795 purple_media_add_remote_candidates(media, 838 purple_media_add_remote_candidates(media,