cpw.malu.xmpp.jingle_ft: 71cf8fb2: Nick the buffer overflow fix from si.c f...
malu at pidgin.im
malu at pidgin.im
Mon May 25 16:35:55 EDT 2009
-----------------------------------------------------------------
Revision: 71cf8fb22c31106720a6e174f2e824ef06946732
Ancestor: 2828f30cf66749918006b44e32dddc677db793d6
Author: malu at pidgin.im
Date: 2009-05-25T20:32:16
Branch: im.pidgin.cpw.malu.xmpp.jingle_ft
URL: http://d.pidgin.im/viewmtn/revision/info/71cf8fb22c31106720a6e174f2e824ef06946732
Modified files:
libpurple/protocols/jabber/jingle/s5b.c
ChangeLog:
Nick the buffer overflow fix from si.c for the Jingle S5B transport
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jingle/s5b.c 371f8cffc6951266acf18eaac07d738837067002
+++ libpurple/protocols/jabber/jingle/s5b.c ddba74424eeeed0b9d50fe6f0ea7a25fafd1265a
@@ -577,7 +577,7 @@ jingle_s5b_send_read_again_cb(gpointer d
const gchar *who = jingle_session_get_remote_jid(session);
JabberID *dstjid = jabber_id_new(who);
JabberStream *js = jingle_session_get_js(session);
- char buffer[256];
+ char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/
int len;
char *dstaddr, *hash;
const char *host;
@@ -605,8 +605,11 @@ jingle_s5b_send_read_again_cb(gpointer d
s5b->priv->rxlen += len;
return;
} else if(s5b->priv->rxqueue[0] != 0x05 || s5b->priv->rxqueue[1] != 0x01 ||
- s5b->priv->rxqueue[3] != 0x03) {
- purple_debug_info("jingle-s5b", "invalid socks5 stuff\n");
+ s5b->priv->rxqueue[3] != 0x03 || s5b->priv->rxqueue[4] != 40) {
+ purple_debug_info("jingle-s5b",
+ "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n",
+ s5b->priv->rxqueue[0], s5b->priv->rxqueue[1], s5b->priv->rxqueue[2],
+ s5b->priv->rxqueue[3], s5b->priv->rxqueue[4]);
purple_input_remove(s5b->priv->watcher);
s5b->priv->watcher = 0;
close(source);
@@ -615,9 +618,13 @@ jingle_s5b_send_read_again_cb(gpointer d
g_free(data);
return;
} else if(s5b->priv->rxlen - 5 < s5b->priv->rxqueue[4] + 2) {
- purple_debug_info("jingle-s5b", "reading umpteen more bytes\n");
- len = read(source, buffer,
- s5b->priv->rxqueue[4] + 5 + 2 - s5b->priv->rxlen);
+ purple_debug_info("jingle-s5b",
+ "reading %u bytes for DST.ADDR + port num (trying to read %u now)\n",
+ s5b->priv->rxqueue[4] + 2,
+ s5b->priv->rxqueue[4] + 2 - (s5b->priv->rxlen - 5));
+ len = read(source, buffer,
+ s5b->priv->rxqueue[4] + 2 - (s5b->priv->rxlen - 5));
+
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
@@ -635,6 +642,7 @@ jingle_s5b_send_read_again_cb(gpointer d
s5b->priv->rxlen += len;
}
+ /* Have we not read all of DST.ADDR and the following 2-byte port number? */
if(s5b->priv->rxlen - 5 < s5b->priv->rxqueue[4] + 2)
return;
@@ -652,10 +660,19 @@ jingle_s5b_send_read_again_cb(gpointer d
purple_debug_info("jingle-s5b", "dstaddr: %s\n", dstaddr);
purple_debug_info("jingle-s5b", "expecting to receive hash %s\n", hash);
- if(s5b->priv->rxqueue[4] != 40 || strncmp(hash, s5b->priv->rxqueue+5, 40) ||
+ if (strncmp(hash, s5b->priv->rxqueue + 5, 40) ||
s5b->priv->rxqueue[45] != 0x00 || s5b->priv->rxqueue[46] != 0x00) {
- purple_debug_error("jingle-s5b",
- "someone connected with the wrong info!\n");
+ if (s5b->priv->rxqueue[45] != 0x00 || s5b->priv->rxqueue[46] != 0x00)
+ purple_debug_error("jingle-s5b",
+ "Got SOCKS5 BS conn with the wrong DST.PORT "
+ " (must be 0 - got[0x%x,0x%x]).\n",
+ s5b->priv->rxqueue[45], s5b->priv->rxqueue[46]);
+ else
+ purple_debug_error("jingle-s5b",
+ "Got SOCKS5 BS conn with the wrong DST.ADDR"
+ " (expected '%s' - got '%.40s').\n",
+ hash, s5b->priv->rxqueue + 5);
+
close(source);
if (s5b->priv->error_cb && s5b->priv->error_content)
s5b->priv->error_cb(s5b->priv->error_content);
@@ -726,11 +743,13 @@ jingle_s5b_send_read_response_cb(gpointe
purple_input_remove(s5b->priv->watcher);
s5b->priv->watcher = 0;
+ /* If we sent a "Success", wait for a response, otherwise give up and cancel */
if (s5b->priv->rxqueue[1] == 0x00) {
s5b->priv->watcher = purple_input_add(source, PURPLE_INPUT_READ,
jingle_s5b_send_read_again_cb, data);
g_free(s5b->priv->rxqueue);
s5b->priv->rxqueue = NULL;
+ s5b->priv->rxlen = 0;
} else {
close(source);
if (s5b->priv->error_cb && s5b->priv->error_content)
@@ -750,7 +769,8 @@ jingle_s5b_send_read_cb(gpointer data, g
purple_debug_info("jingle-s5b", "in jingle_s5b_send_read_cb\n");
s5b->priv->local_fd = source;
-
+
+ /* Try to read the SOCKS5 header */
if(s5b->priv->rxlen < 2) {
purple_debug_info("jingle-s5b", "reading those first two bytes\n");
len = read(source, buffer, 2 - s5b->priv->rxlen);
@@ -771,8 +791,11 @@ jingle_s5b_send_read_cb(gpointer data, g
s5b->priv->rxlen += len;
return;
} else if(s5b->priv->rxlen - 2 < s5b->priv->rxqueue[1]) {
- purple_debug_info("jingle-s5b", "reading the next umpteen bytes\n");
- len = read(source, buffer, s5b->priv->rxqueue[1] + 2 - s5b->priv->rxlen);
+ purple_debug_info("jingle-s5b",
+ "reading %u bytes for auth methods (trying to read %u now)\n",
+ s5b->priv->rxqueue[1], s5b->priv->rxqueue[1] - (s5b->priv->rxlen - 2));
+ len = read(source, buffer, s5b->priv->rxqueue[1] - (s5b->priv->rxlen - 2));
+
if(len < 0 && errno == EAGAIN)
return;
else if(len <= 0) {
@@ -790,7 +813,8 @@ jingle_s5b_send_read_cb(gpointer data, g
s5b->priv->rxlen += len;
}
- if(s5b->priv->rxlen -2 < s5b->priv->rxqueue[1])
+ /* Have we not read all the auth. method bytes? */
+ if(s5b->priv->rxlen - 2 < s5b->priv->rxqueue[1])
return;
purple_input_remove(s5b->priv->watcher);
More information about the Commits
mailing list