diff -up pidgin-2.6.6/libpurple/protocols/jabber/jingle/jingle.c.CVE-2011-4602 pidgin-2.6.6/libpurple/protocols/jabber/jingle/jingle.c --- pidgin-2.6.6/libpurple/protocols/jabber/jingle/jingle.c.CVE-2011-4602 2010-02-16 04:34:06.000000000 -0500 +++ pidgin-2.6.6/libpurple/protocols/jabber/jingle/jingle.c 2011-12-12 10:18:20.474586547 -0500 @@ -119,7 +119,7 @@ jingle_handle_content_modify(JingleSessi if (local_content != NULL) { const gchar *senders = xmlnode_get_attrib(content, "senders"); gchar *local_senders = jingle_content_get_senders(local_content); - if (strcmp(senders, local_senders)) + if (!purple_strequal(senders, local_senders)) jingle_content_modify(local_content, senders); g_free(local_senders); } else { diff -up pidgin-2.6.6/libpurple/protocols/jabber/jingle/rtp.c.CVE-2011-4602 pidgin-2.6.6/libpurple/protocols/jabber/jingle/rtp.c --- pidgin-2.6.6/libpurple/protocols/jabber/jingle/rtp.c.CVE-2011-4602 2010-02-16 04:34:06.000000000 -0500 +++ pidgin-2.6.6/libpurple/protocols/jabber/jingle/rtp.c 2011-12-12 10:18:20.476586529 -0500 @@ -580,6 +580,16 @@ jingle_rtp_init_media(JingleContent *con senders = jingle_content_get_senders(content); transport = jingle_content_get_transport(content); + if (media_type == NULL) { + g_free(name); + g_free(remote_jid); + g_free(senders); + g_free(params); + g_object_unref(transport); + g_object_unref(session); + return FALSE; + } + if (JINGLE_IS_RAWUDP(transport)) transmitter = "rawudp"; else if (JINGLE_IS_ICEUDP(transport)) @@ -588,24 +598,34 @@ jingle_rtp_init_media(JingleContent *con transmitter = "notransmitter"; g_object_unref(transport); - is_audio = !strcmp(media_type, "audio"); + is_audio = g_str_equal(media_type, "audio"); - if (!strcmp(senders, "both")) - type = is_audio == TRUE ? PURPLE_MEDIA_AUDIO + if (purple_strequal(senders, "both")) + type = is_audio ? PURPLE_MEDIA_AUDIO : PURPLE_MEDIA_VIDEO; - else if ((strcmp(senders, "initiator") == 0) == + else if (purple_strequal(senders, "initiator") == jingle_session_is_initiator(session)) - type = is_audio == TRUE ? PURPLE_MEDIA_SEND_AUDIO + type = is_audio ? PURPLE_MEDIA_SEND_AUDIO : PURPLE_MEDIA_SEND_VIDEO; else - type = is_audio == TRUE ? PURPLE_MEDIA_RECV_AUDIO + type = is_audio ? PURPLE_MEDIA_RECV_AUDIO : PURPLE_MEDIA_RECV_VIDEO; params = jingle_get_params(jingle_session_get_js(session), &num_params); creator = jingle_content_get_creator(content); - if (!strcmp(creator, "initiator")) + if (creator == NULL) { + g_free(name); + g_free(media_type); + g_free(remote_jid); + g_free(senders); + g_free(params); + g_object_unref(session); + return FALSE; + } + + if (g_str_equal(creator, "initiator")) is_creator = jingle_session_is_initiator(session); else is_creator = !jingle_session_is_initiator(session); @@ -614,6 +634,8 @@ jingle_rtp_init_media(JingleContent *con if(!purple_media_add_stream(media, name, remote_jid, type, is_creator, transmitter, num_params, params)) { purple_media_end(media, NULL, NULL); + /* TODO: How much clean-up is necessary here? (does calling + purple_media_end lead to cleaning up Jingle structs?) */ return FALSE; } @@ -635,9 +657,22 @@ jingle_rtp_parse_codecs(xmlnode *descrip const char *encoding_name,*id, *clock_rate; PurpleMediaCodec *codec; const gchar *media = xmlnode_get_attrib(description, "media"); - PurpleMediaSessionType type = - !strcmp(media, "video") ? PURPLE_MEDIA_VIDEO : - !strcmp(media, "audio") ? PURPLE_MEDIA_AUDIO : 0; + PurpleMediaSessionType type; + + if (media == NULL) { + purple_debug_warning("jingle-rtp", "missing media type\n"); + return NULL; + } + + if (g_str_equal(media, "video")) { + type = PURPLE_MEDIA_VIDEO; + } else if (g_str_equal(media, "audio")) { + type = PURPLE_MEDIA_AUDIO; + } else { + purple_debug_warning("jingle-rtp", "unknown media type: %s\n", + media); + return NULL; + } for (codec_element = xmlnode_get_child(description, "payload-type") ; codec_element ; @@ -758,19 +793,19 @@ jingle_rtp_handle_action_internal(Jingle switch (action) { case JINGLE_SESSION_ACCEPT: case JINGLE_SESSION_INITIATE: { - JingleSession *session = jingle_content_get_session(content); - JingleTransport *transport = jingle_transport_parse( - xmlnode_get_child(xmlcontent, "transport")); - xmlnode *description = xmlnode_get_child(xmlcontent, "description"); - GList *candidates = jingle_rtp_transport_to_candidates(transport); - GList *codecs = jingle_rtp_parse_codecs(description); - gchar *name = jingle_content_get_name(content); - gchar *remote_jid = - jingle_session_get_remote_jid(session); + JingleSession *session; + JingleTransport *transport; + xmlnode *description; + GList *candidates; + GList *codecs; + gchar *name; + gchar *remote_jid; PurpleMedia *media; + session = jingle_content_get_session(content); + if (action == JINGLE_SESSION_INITIATE && - jingle_rtp_init_media(content) == FALSE) { + !jingle_rtp_init_media(content)) { /* XXX: send error */ jabber_iq_send(jingle_session_terminate_packet( session, "general-error")); @@ -778,6 +813,14 @@ jingle_rtp_handle_action_internal(Jingle break; } + transport = jingle_transport_parse( + xmlnode_get_child(xmlcontent, "transport")); + description = xmlnode_get_child(xmlcontent, "description"); + candidates = jingle_rtp_transport_to_candidates(transport); + codecs = jingle_rtp_parse_codecs(description); + name = jingle_content_get_name(content); + remote_jid = jingle_session_get_remote_jid(session); + media = jingle_rtp_get_media(session); purple_media_set_remote_codecs(media, name, remote_jid, codecs); diff -up pidgin-2.6.6/libpurple/protocols/jabber/jingle/session.c.CVE-2011-4602 pidgin-2.6.6/libpurple/protocols/jabber/jingle/session.c --- pidgin-2.6.6/libpurple/protocols/jabber/jingle/session.c.CVE-2011-4602 2010-02-16 04:34:06.000000000 -0500 +++ pidgin-2.6.6/libpurple/protocols/jabber/jingle/session.c 2011-12-12 10:18:20.478586511 -0500 @@ -284,7 +284,7 @@ jingle_session_create(JabberStream *js, if (!js->sessions) { purple_debug_info("jingle", "Creating hash table for sessions\n"); - js->sessions = g_hash_table_new(g_str_hash, g_str_equal); + js->sessions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); } purple_debug_info("jingle", "inserting session with key: %s into table\n", sid); @@ -454,27 +454,25 @@ jingle_add_jingle_packet(JingleSession * xmlnode_new("jingle"); gchar *local_jid = jingle_session_get_local_jid(session); gchar *remote_jid = jingle_session_get_remote_jid(session); + gchar *sid = jingle_session_get_sid(session); xmlnode_set_namespace(jingle, JINGLE); xmlnode_set_attrib(jingle, "action", jingle_get_action_name(action)); if (jingle_session_is_initiator(session)) { - xmlnode_set_attrib(jingle, "initiator", - jingle_session_get_local_jid(session)); - xmlnode_set_attrib(jingle, "responder", - jingle_session_get_remote_jid(session)); + xmlnode_set_attrib(jingle, "initiator", local_jid); + xmlnode_set_attrib(jingle, "responder", remote_jid); } else { - xmlnode_set_attrib(jingle, "initiator", - jingle_session_get_remote_jid(session)); - xmlnode_set_attrib(jingle, "responder", - jingle_session_get_local_jid(session)); + xmlnode_set_attrib(jingle, "initiator", remote_jid); + xmlnode_set_attrib(jingle, "responder", local_jid); } + xmlnode_set_attrib(jingle, "sid", sid); + g_free(local_jid); g_free(remote_jid); + g_free(sid); - xmlnode_set_attrib(jingle, "sid", jingle_session_get_sid(session)); - return jingle; } @@ -551,11 +549,16 @@ void jingle_session_handle_action(Jingle JingleContent * jingle_session_find_content(JingleSession *session, const gchar *name, const gchar *creator) { - GList *iter = session->priv->contents; + GList *iter; + + if (name == NULL) + return NULL; + + iter = session->priv->contents; for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); - gboolean result = !strcmp(name, cname); + gboolean result = g_str_equal(name, cname); g_free(cname); if (creator != NULL) { @@ -573,11 +576,16 @@ jingle_session_find_content(JingleSessio JingleContent * jingle_session_find_pending_content(JingleSession *session, const gchar *name, const gchar *creator) { - GList *iter = session->priv->pending_contents; + GList *iter; + + if (name == NULL) + return NULL; + + iter = session->priv->pending_contents; for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); - gboolean result = !strcmp(name, cname); + gboolean result = g_str_equal(name, cname); g_free(cname); if (creator != NULL) {