Mercurial > pidgin
changeset 24302:040c66dffbf0
Perform some sanity checking on inbound IQs and send an error / drop as needed.
This has the effect of preventing us from sending an invalid response when we
get an invalid request (e.g. missing an id).
Fixes #7290.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Sun, 26 Oct 2008 17:23:40 +0000 |
parents | 785db7300ef2 |
children | 8643ff79db35 a548c565780f |
files | libpurple/protocols/jabber/iq.c |
diffstat | 1 files changed, 38 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/jabber/iq.c Sun Oct 26 00:29:27 2008 +0000 +++ b/libpurple/protocols/jabber/iq.c Sun Oct 26 17:23:40 2008 +0000 @@ -105,8 +105,7 @@ void jabber_iq_set_id(JabberIq *iq, const char *id) { - if(iq->id) - g_free(iq->id); + g_free(iq->id); if(id) { xmlnode_set_attrib(iq->node, "id", id); @@ -320,9 +319,42 @@ from = xmlnode_get_attrib(packet, "from"); id = xmlnode_get_attrib(packet, "id"); + if(type == NULL || !(!strcmp(type, "get") || !strcmp(type, "set") + || !strcmp(type, "result") || !strcmp(type, "error"))) { + purple_debug_error("jabber", "IQ with invalid type ('%s') - ignoring.\n", + type ? type : "(null)"); + return; + } + + /* All IQs must have an ID, so send an error for a set/get that doesn't */ + if(!id || !*id) { + + if(!strcmp(type, "set") || !strcmp(type, "get")) { + JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); + + xmlnode_free(iq->node); + iq->node = xmlnode_copy(packet); + xmlnode_set_attrib(iq->node, "to", from); + xmlnode_remove_attrib(iq->node, "from"); + xmlnode_set_attrib(iq->node, "type", "error"); + /* This id is clearly not useful, but we must put something there for a valid stanza */ + iq->id = jabber_get_next_id(js); + xmlnode_set_attrib(iq->node, "id", iq->id); + error = xmlnode_new_child(iq->node, "error"); + xmlnode_set_attrib(error, "type", "modify"); + x = xmlnode_new_child(error, "bad-request"); + xmlnode_set_namespace(x, "urn:ietf:params:xml:ns:xmpp-stanzas"); + + jabber_iq_send(iq); + } else + purple_debug_error("jabber", "IQ of type '%s' missing id - ignoring.\n", type); + + return; + } + /* First, lets see if a special callback got registered */ - if(type && (!strcmp(type, "result") || !strcmp(type, "error"))) { + if(!strcmp(type, "result") || !strcmp(type, "error")) { if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { jcd->callback(js, packet, jcd->data); jabber_iq_remove_callback_by_id(js, id); @@ -332,7 +364,7 @@ /* Apparently not, so lets see if we have a pre-defined handler */ - if(type && query && (xmlns = xmlnode_get_namespace(query))) { + if(query && (xmlns = xmlnode_get_namespace(query))) { if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { jih(js, packet); return; @@ -348,7 +380,7 @@ jabber_gmail_poke(js, packet); return; } - + purple_debug_info("jabber", "jabber_iq_parse\n"); if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) { @@ -362,7 +394,7 @@ } /* If we get here, send the default error reply mandated by XMPP-CORE */ - if(type && (!strcmp(type, "set") || !strcmp(type, "get"))) { + if(!strcmp(type, "set") || !strcmp(type, "get")) { JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); xmlnode_free(iq->node);