Mercurial > pidgin
comparison libpurple/protocols/jabber/iq.c @ 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 | 305fac6af8f9 |
children | bcad7dc4b453 e30e9779e7bf b5052c66701c 45dbea660309 |
comparison
equal
deleted
inserted
replaced
24301:785db7300ef2 | 24302:040c66dffbf0 |
---|---|
103 iq->callback_data = data; | 103 iq->callback_data = data; |
104 } | 104 } |
105 | 105 |
106 void jabber_iq_set_id(JabberIq *iq, const char *id) | 106 void jabber_iq_set_id(JabberIq *iq, const char *id) |
107 { | 107 { |
108 if(iq->id) | 108 g_free(iq->id); |
109 g_free(iq->id); | |
110 | 109 |
111 if(id) { | 110 if(id) { |
112 xmlnode_set_attrib(iq->node, "id", id); | 111 xmlnode_set_attrib(iq->node, "id", id); |
113 iq->id = g_strdup(id); | 112 iq->id = g_strdup(id); |
114 } else { | 113 } else { |
318 query = xmlnode_get_child(packet, "query"); | 317 query = xmlnode_get_child(packet, "query"); |
319 type = xmlnode_get_attrib(packet, "type"); | 318 type = xmlnode_get_attrib(packet, "type"); |
320 from = xmlnode_get_attrib(packet, "from"); | 319 from = xmlnode_get_attrib(packet, "from"); |
321 id = xmlnode_get_attrib(packet, "id"); | 320 id = xmlnode_get_attrib(packet, "id"); |
322 | 321 |
322 if(type == NULL || !(!strcmp(type, "get") || !strcmp(type, "set") | |
323 || !strcmp(type, "result") || !strcmp(type, "error"))) { | |
324 purple_debug_error("jabber", "IQ with invalid type ('%s') - ignoring.\n", | |
325 type ? type : "(null)"); | |
326 return; | |
327 } | |
328 | |
329 /* All IQs must have an ID, so send an error for a set/get that doesn't */ | |
330 if(!id || !*id) { | |
331 | |
332 if(!strcmp(type, "set") || !strcmp(type, "get")) { | |
333 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); | |
334 | |
335 xmlnode_free(iq->node); | |
336 iq->node = xmlnode_copy(packet); | |
337 xmlnode_set_attrib(iq->node, "to", from); | |
338 xmlnode_remove_attrib(iq->node, "from"); | |
339 xmlnode_set_attrib(iq->node, "type", "error"); | |
340 /* This id is clearly not useful, but we must put something there for a valid stanza */ | |
341 iq->id = jabber_get_next_id(js); | |
342 xmlnode_set_attrib(iq->node, "id", iq->id); | |
343 error = xmlnode_new_child(iq->node, "error"); | |
344 xmlnode_set_attrib(error, "type", "modify"); | |
345 x = xmlnode_new_child(error, "bad-request"); | |
346 xmlnode_set_namespace(x, "urn:ietf:params:xml:ns:xmpp-stanzas"); | |
347 | |
348 jabber_iq_send(iq); | |
349 } else | |
350 purple_debug_error("jabber", "IQ of type '%s' missing id - ignoring.\n", type); | |
351 | |
352 return; | |
353 } | |
354 | |
323 /* First, lets see if a special callback got registered */ | 355 /* First, lets see if a special callback got registered */ |
324 | 356 |
325 if(type && (!strcmp(type, "result") || !strcmp(type, "error"))) { | 357 if(!strcmp(type, "result") || !strcmp(type, "error")) { |
326 if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { | 358 if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { |
327 jcd->callback(js, packet, jcd->data); | 359 jcd->callback(js, packet, jcd->data); |
328 jabber_iq_remove_callback_by_id(js, id); | 360 jabber_iq_remove_callback_by_id(js, id); |
329 return; | 361 return; |
330 } | 362 } |
331 } | 363 } |
332 | 364 |
333 /* Apparently not, so lets see if we have a pre-defined handler */ | 365 /* Apparently not, so lets see if we have a pre-defined handler */ |
334 | 366 |
335 if(type && query && (xmlns = xmlnode_get_namespace(query))) { | 367 if(query && (xmlns = xmlnode_get_namespace(query))) { |
336 if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { | 368 if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { |
337 jih(js, packet); | 369 jih(js, packet); |
338 return; | 370 return; |
339 } | 371 } |
340 } | 372 } |
346 | 378 |
347 if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) { | 379 if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) { |
348 jabber_gmail_poke(js, packet); | 380 jabber_gmail_poke(js, packet); |
349 return; | 381 return; |
350 } | 382 } |
351 | 383 |
352 purple_debug_info("jabber", "jabber_iq_parse\n"); | 384 purple_debug_info("jabber", "jabber_iq_parse\n"); |
353 | 385 |
354 if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) { | 386 if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) { |
355 jabber_ping_parse(js, packet); | 387 jabber_ping_parse(js, packet); |
356 return; | 388 return; |
360 jabber_data_parse(js, packet); | 392 jabber_data_parse(js, packet); |
361 return; | 393 return; |
362 } | 394 } |
363 | 395 |
364 /* If we get here, send the default error reply mandated by XMPP-CORE */ | 396 /* If we get here, send the default error reply mandated by XMPP-CORE */ |
365 if(type && (!strcmp(type, "set") || !strcmp(type, "get"))) { | 397 if(!strcmp(type, "set") || !strcmp(type, "get")) { |
366 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); | 398 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); |
367 | 399 |
368 xmlnode_free(iq->node); | 400 xmlnode_free(iq->node); |
369 iq->node = xmlnode_copy(packet); | 401 iq->node = xmlnode_copy(packet); |
370 xmlnode_set_attrib(iq->node, "to", from); | 402 xmlnode_set_attrib(iq->node, "to", from); |