cpw.malu.xmpp.jingle_ft: dcd7ea4d: Update si.c to use the new socks5 listen...
malu at pidgin.im
malu at pidgin.im
Thu May 6 16:45:42 EDT 2010
-----------------------------------------------------------------
Revision: dcd7ea4dc58df407789d69e90a36c5322dc30cd8
Ancestor: 8edd40ff9d29b7707182311439f25c0e8e52c802
Author: malu at pidgin.im
Date: 2010-05-06T20:32:55
Branch: im.pidgin.cpw.malu.xmpp.jingle_ft
URL: http://d.pidgin.im/viewmtn/revision/info/dcd7ea4dc58df407789d69e90a36c5322dc30cd8
Modified files:
libpurple/protocols/jabber/si.c
ChangeLog:
Update si.c to use the new socks5 listening stuff
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/si.c 92da5ffed83f07a21215fb12359c49e55f7bc3c6
+++ libpurple/protocols/jabber/si.c 3944118f9aeb5efcdbb4375e626d7fb7cd046fcd
@@ -38,6 +38,7 @@
#include "ibb.h"
#include "iq.h"
#include "si.h"
+#include "socks5.h"
#include "xfer.h"
#define STREAMHOST_CONNECT_TIMEOUT 15
@@ -65,9 +66,7 @@ typedef struct _JabberSIXfer {
GList *streamhosts;
PurpleProxyInfo *gpi;
- char *rxqueue;
- size_t rxlen;
- gsize rxmaxlen;
+ JabberSocks5ListenData *socks5_listen_data;
int local_streamhost_fd;
JabberIBBSession *ibb_session;
@@ -370,299 +369,31 @@ static void
static void
-jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source,
- PurpleInputCondition cond)
+jabber_si_listen_connect_cb(int fd, gpointer data)
{
- PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
- int len;
+ PurpleXfer *xfer = (PurpleXfer *) data;
+ JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
- len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
- if (len < 0 && errno == EAGAIN)
- return;
- else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- g_free(jsx->rxqueue);
- jsx->rxqueue = NULL;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxlen += len;
-
- if (jsx->rxlen < jsx->rxmaxlen)
- return;
-
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- g_free(jsx->rxqueue);
- jsx->rxqueue = NULL;
-
- /* Before actually starting sending the file, we need to wait until the
- * recipient sends the IQ result with <streamhost-used/>
- */
- purple_debug_info("jabber", "SOCKS5 connection negotiation completed. "
- "Waiting for IQ result to start file transfer.\n");
+ jabber_socks5_listen_data_free(jsx->socks5_listen_data);
+ jsx->socks5_listen_data = NULL;
+ xfer->fd = fd;
+ /* waiting for <streamhost-used/> */
}
static void
-jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source,
- PurpleInputCondition cond)
+jabber_si_listen_error_cb(gpointer data)
{
- PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
- char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/
- int len;
- char *dstaddr, *hash;
- const char *host;
-
- purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_again_cb\n");
-
- if(jsx->rxlen < 5) {
- purple_debug_info("jabber", "reading the first 5 bytes\n");
- len = read(source, buffer, 5 - jsx->rxlen);
- if(len < 0 && errno == EAGAIN)
- return;
- else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
- memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
- jsx->rxlen += len;
- return;
- } else if(jsx->rxqueue[0] != 0x05 || jsx->rxqueue[1] != 0x01 ||
- jsx->rxqueue[3] != 0x03 || jsx->rxqueue[4] != 40) {
- purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n",
- jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2],
- jsx->rxqueue[3], jsx->rxqueue[4]);
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- } else if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) {
- /* Upper-bound of 257 (jsx->rxlen = 5, jsx->rxqueue[4] = 0xFF) */
- unsigned short to_read = jsx->rxqueue[4] + 2 - (jsx->rxlen - 5);
- purple_debug_info("jabber", "reading %u bytes for DST.ADDR + port num (trying to read %hu now)\n",
- jsx->rxqueue[4] + 2, to_read);
- len = read(source, buffer, to_read);
- if(len < 0 && errno == EAGAIN)
- return;
- else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
- memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
- jsx->rxlen += len;
- }
-
- /* Have we not read all of DST.ADDR and the following 2-byte port number? */
- if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2)
- return;
-
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
-
- dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id,
- jsx->js->user->node, jsx->js->user->domain,
- jsx->js->user->resource, xfer->who);
-
- /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
- hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
-
- if(strncmp(hash, jsx->rxqueue + 5, 40) ||
- jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) {
- if (jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00)
- purple_debug_error("jabber", "Got SOCKS5 BS conn with the wrong DST.PORT"
- " (must be 0 - got[0x%x,0x%x]).\n",
- jsx->rxqueue[45], jsx->rxqueue[46]);
- else
- purple_debug_error("jabber", "Got SOCKS5 BS conn with the wrong DST.ADDR"
- " (expected '%s' - got '%.40s').\n",
- hash, jsx->rxqueue + 5);
- close(source);
- purple_xfer_cancel_remote(xfer);
- g_free(hash);
- g_free(dstaddr);
- return;
- }
-
- g_free(hash);
- g_free(dstaddr);
-
- g_free(jsx->rxqueue);
- host = purple_network_get_my_ip(jsx->js->fd);
-
- jsx->rxmaxlen = 5 + strlen(host) + 2;
- jsx->rxqueue = g_malloc(jsx->rxmaxlen);
- jsx->rxlen = 0;
-
- jsx->rxqueue[0] = 0x05;
- jsx->rxqueue[1] = 0x00;
- jsx->rxqueue[2] = 0x00;
- jsx->rxqueue[3] = 0x03;
- jsx->rxqueue[4] = strlen(host);
- memcpy(jsx->rxqueue + 5, host, strlen(host));
- jsx->rxqueue[5+strlen(host)] = 0x00;
- jsx->rxqueue[6+strlen(host)] = 0x00;
-
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer);
- jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source,
- PURPLE_INPUT_WRITE);
+ PurpleXfer *xfer = (PurpleXfer *) data;
+ JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+
+ purple_debug_info("jabber", "in jabber_si_listen_error_cb\n");
+ jabber_socks5_listen_data_free(jsx->socks5_listen_data);
+ jsx->socks5_listen_data = NULL;
+ purple_xfer_cancel_remote(xfer);
}
-static void
-jabber_si_xfer_bytestreams_send_read_response_cb(gpointer data, gint source,
- PurpleInputCondition cond)
-{
- PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
- int len;
- len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen);
- if (len < 0 && errno == EAGAIN)
- return;
- else if (len < 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- g_free(jsx->rxqueue);
- jsx->rxqueue = NULL;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxlen += len;
- if (jsx->rxlen < jsx->rxmaxlen)
- return;
-
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
-
- /* If we sent a "Success", wait for a response, otherwise give up and cancel */
- if (jsx->rxqueue[1] == 0x00) {
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_again_cb, xfer);
- g_free(jsx->rxqueue);
- jsx->rxqueue = NULL;
- jsx->rxlen = 0;
- } else {
- close(source);
- purple_xfer_cancel_remote(xfer);
- }
-}
-
-static void
-jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source,
- PurpleInputCondition cond)
-{
- PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
- int i;
- int len;
- char buffer[256];
-
- purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n");
-
- xfer->fd = source;
-
- /** Try to read the SOCKS5 header */
- if(jsx->rxlen < 2) {
- purple_debug_info("jabber", "reading those first two bytes\n");
- len = read(source, buffer, 2 - jsx->rxlen);
- if(len < 0 && errno == EAGAIN)
- return;
- else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
- memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
- jsx->rxlen += len;
- return;
- } else if(jsx->rxlen - 2 < jsx->rxqueue[1]) {
- /* Has a maximum value of 255 (jsx->rxlen = 2, jsx->rxqueue[1] = 0xFF) */
- unsigned short to_read = jsx->rxqueue[1] - (jsx->rxlen - 2);
- purple_debug_info("jabber", "reading %u bytes for auth methods (trying to read %hu now)\n",
- jsx->rxqueue[1], to_read);
- len = read(source, buffer, to_read);
- if(len < 0 && errno == EAGAIN)
- return;
- else if(len <= 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
- jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen);
- memcpy(jsx->rxqueue + jsx->rxlen, buffer, len);
- jsx->rxlen += len;
- }
-
- /* Have we not read all the auth. method bytes? */
- if(jsx->rxlen -2 < jsx->rxqueue[1])
- return;
-
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
-
- purple_debug_info("jabber", "checking to make sure we're socks FIVE\n");
-
- if(jsx->rxqueue[0] != 0x05) {
- close(source);
- purple_xfer_cancel_remote(xfer);
- return;
- }
-
- purple_debug_info("jabber", "going to test %hhu different methods\n", jsx->rxqueue[1]);
-
- for(i=0; i<jsx->rxqueue[1]; i++) {
-
- purple_debug_info("jabber", "testing %hhu\n", jsx->rxqueue[i+2]);
- if(jsx->rxqueue[i+2] == 0x00) {
- g_free(jsx->rxqueue);
- jsx->rxlen = 0;
- jsx->rxmaxlen = 2;
- jsx->rxqueue = g_malloc(jsx->rxmaxlen);
- jsx->rxqueue[0] = 0x05;
- jsx->rxqueue[1] = 0x00;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_response_cb,
- xfer);
- jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
- source, PURPLE_INPUT_WRITE);
- jsx->rxqueue = NULL;
- jsx->rxlen = 0;
- return;
- }
- }
-
- g_free(jsx->rxqueue);
- jsx->rxlen = 0;
- jsx->rxmaxlen = 2;
- jsx->rxqueue = g_malloc(jsx->rxmaxlen);
- jsx->rxqueue[0] = 0x05;
- jsx->rxqueue[1] = 0xFF;
- xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
- jabber_si_xfer_bytestreams_send_read_response_cb, xfer);
- jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
- source, PURPLE_INPUT_WRITE);
-}
-
static gint
jabber_si_compare_jid(gconstpointer a, gconstpointer b)
{
@@ -674,39 +405,7 @@ jabber_si_compare_jid(gconstpointer a, g
return strcmp(sh->jid, (char *)b);
}
-static void
-jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source,
- PurpleInputCondition cond)
-{
- PurpleXfer *xfer = data;
- JabberSIXfer *jsx = xfer->data;
- int acceptfd, flags;
- purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n");
-
- acceptfd = accept(source, NULL, 0);
- if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
- return;
- else if(acceptfd == -1) {
- purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno));
- /* Don't cancel the ft - allow it to fall to the next streamhost.*/
- return;
- }
-
- purple_input_remove(xfer->watcher);
- close(source);
- jsx->local_streamhost_fd = -1;
-
- flags = fcntl(acceptfd, F_GETFL);
- fcntl(acceptfd, F_SETFL, flags | O_NONBLOCK);
-#ifndef _WIN32
- fcntl(acceptfd, F_SETFD, FD_CLOEXEC);
-#endif
-
- xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_read_cb, xfer);
-}
-
static void
jabber_si_connect_proxy_cb(JabberStream *js, const char *from,
JabberIqType type, const char *id,
@@ -804,9 +503,10 @@ jabber_si_connect_proxy_cb(JabberStream
}
/* Clean up the local streamhost - it isn't going to be used.*/
- if (xfer->watcher > 0) {
- purple_input_remove(xfer->watcher);
- xfer->watcher = 0;
+ if (jsx->socks5_listen_data) {
+ jabber_socks5_listen_cancel(jsx->socks5_listen_data);
+ jabber_socks5_listen_data_free(jsx->socks5_listen_data);
+ jsx->socks5_listen_data = NULL;
}
if (jsx->local_streamhost_fd >= 0) {
close(jsx->local_streamhost_fd);
@@ -859,14 +559,19 @@ jabber_si_xfer_bytestreams_listen_cb(int
purple_network_get_all_local_system_ips();
const char *public_ip;
gboolean has_public_ip = FALSE;
-
- jsx->local_streamhost_fd = sock;
+ gchar *dstaddr;
+ JabberID *dstjid = jabber_id_new(xfer->who);
jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
jsx->js->user->domain, jsx->js->user->resource);
+ jsx->local_streamhost_fd = sock;
+
+
xfer->local_port = purple_network_get_port_from_fd(sock);
g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
-
+ dstaddr = g_strdup_printf("%s%s%s@%s/%s", jsx->stream_id,
+ jid, dstjid->node, dstjid->domain, dstjid->resource);
+ jabber_id_free(dstjid);
public_ip = purple_network_get_my_ip(jsx->js->fd);
/* Include the localhost's IPs (for in-network transfers) */
@@ -895,8 +600,9 @@ jabber_si_xfer_bytestreams_listen_cb(int
g_free(jid);
/* The listener for the local proxy */
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_connected_cb, xfer);
+ jsx->socks5_listen_data = jabber_socks5_listen(sock, dstaddr,
+ jabber_si_listen_connect_cb, jabber_si_listen_error_cb, xfer);
+ g_free(dstaddr);
}
for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) {
@@ -1323,6 +1029,10 @@ static void jabber_si_xfer_free(PurpleXf
purple_proxy_connect_cancel(jsx->connect_data);
if (jsx->listen_data != NULL)
purple_network_listen_cancel(jsx->listen_data);
+ if (jsx->socks5_listen_data != NULL) {
+ jabber_socks5_listen_cancel(jsx->socks5_listen_data);
+ jabber_socks5_listen_data_free(jsx->socks5_listen_data);
+ }
if (jsx->iq_id != NULL)
jabber_iq_remove_callback_by_id(js, jsx->iq_id);
if (jsx->local_streamhost_fd >= 0)
@@ -1357,7 +1067,6 @@ static void jabber_si_xfer_free(PurpleXf
g_free(jsx->stream_id);
g_free(jsx->iq_id);
/* XXX: free other stuff */
- g_free(jsx->rxqueue);
g_free(jsx);
xfer->data = NULL;
}
More information about the Commits
mailing list