aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-10-21 10:14:17 -0300
committerdequis <dx@dxzone.com.ar>2015-10-21 10:14:17 -0300
commit12f041de930a20a3df91f9f90c4fd518162ea82c (patch)
treebfe4f8b160ea4707d2600b73eb0e28d3b5f505c8
parent3314ced0efff64ce4f92caf24b9272f5249c3a17 (diff)
socks4a proxy support (like socks4 with remote DNS)
Fixes trac ticket 995 https://bugs.bitlbee.org/bitlbee/ticket/995 This is slightly pointless for the suggested use case (tor), since with socks5 we already send a hostname instead of an IP address. Either way, it was easy to implement, so I hope it helps.
-rw-r--r--conf.c2
-rw-r--r--lib/proxy.c29
-rw-r--r--lib/proxy.h1
-rw-r--r--lib/url.c2
-rw-r--r--lib/url.h1
-rw-r--r--protocols/purple/purple.c7
6 files changed, 35 insertions, 7 deletions
diff --git a/conf.c b/conf.c
index 845731b2..ac02f1b1 100644
--- a/conf.c
+++ b/conf.c
@@ -294,6 +294,8 @@ static int conf_loadini(conf_t *conf, char *file)
proxytype = PROXY_SOCKS4;
} else if (url->proto == PROTO_SOCKS5) {
proxytype = PROXY_SOCKS5;
+ } else if (url->proto == PROTO_SOCKS4A) {
+ proxytype = PROXY_SOCKS4A;
}
g_free(url);
diff --git a/lib/proxy.c b/lib/proxy.c
index 4028f750..c4f75772 100644
--- a/lib/proxy.c
+++ b/lib/proxy.c
@@ -293,6 +293,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
struct PHB *phb = data;
socklen_t len;
int error = ETIMEDOUT;
+ gboolean is_socks4a = (proxytype == PROXY_SOCKS4A);
if (phb->inpa > 0) {
b_event_remove(phb->inpa);
@@ -303,8 +304,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
}
sock_make_blocking(source);
- /* XXX does socks4 not support host name lookups by the proxy? */
- if (!(hp = gethostbyname(phb->host))) {
+ if (!is_socks4a && !(hp = gethostbyname(phb->host))) {
return phb_close(phb);
}
@@ -312,15 +312,30 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
packet[1] = 1;
packet[2] = phb->port >> 8;
packet[3] = phb->port & 0xff;
- packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
- packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
- packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
- packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
+ if (is_socks4a) {
+ packet[4] = 0;
+ packet[5] = 0;
+ packet[6] = 0;
+ packet[7] = 1;
+ } else {
+ packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
+ packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
+ packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
+ packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
+ }
packet[8] = 0;
if (write(source, packet, 9) != 9) {
return phb_close(phb);
}
+ if (is_socks4a) {
+ size_t host_len = strlen(phb->host) + 1; /* include the \0 */
+
+ if (write(source, phb->host, host_len) != host_len) {
+ return phb_close(phb);
+ }
+ }
+
phb->inpa = b_input_add(source, B_EV_IO_READ, s4_canread, phb);
return FALSE;
@@ -505,7 +520,7 @@ int proxy_connect(const char *host, int port, b_event_handler func, gpointer dat
return proxy_connect_none(host, port, phb);
} else if (proxytype == PROXY_HTTP) {
return proxy_connect_http(host, port, phb);
- } else if (proxytype == PROXY_SOCKS4) {
+ } else if (proxytype == PROXY_SOCKS4 || proxytype == PROXY_SOCKS4A) {
return proxy_connect_socks4(host, port, phb);
} else if (proxytype == PROXY_SOCKS5) {
return proxy_connect_socks5(host, port, phb);
diff --git a/lib/proxy.h b/lib/proxy.h
index 9688aaa6..eaf31375 100644
--- a/lib/proxy.h
+++ b/lib/proxy.h
@@ -39,6 +39,7 @@
#define PROXY_HTTP 1
#define PROXY_SOCKS4 2
#define PROXY_SOCKS5 3
+#define PROXY_SOCKS4A 4
extern char proxyhost[128];
extern int proxyport;
diff --git a/lib/url.c b/lib/url.c
index 38515669..082e3586 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -47,6 +47,8 @@ int url_set(url_t *url, const char *set_url)
url->proto = PROTO_SOCKS4;
} else if (g_strncasecmp(set_url, "socks5", i - set_url) == 0) {
url->proto = PROTO_SOCKS5;
+ } else if (g_strncasecmp(set_url, "socks4a", i - set_url) == 0) {
+ url->proto = PROTO_SOCKS4A;
} else {
return 0;
}
diff --git a/lib/url.h b/lib/url.h
index 4caf13d7..66abcd03 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -29,6 +29,7 @@
#define PROTO_HTTPS 5
#define PROTO_SOCKS4 3
#define PROTO_SOCKS5 4
+#define PROTO_SOCKS4A 5
#define PROTO_DEFAULT PROTO_HTTP
typedef struct url {
diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c
index b00d3078..a24b064a 100644
--- a/protocols/purple/purple.c
+++ b/protocols/purple/purple.c
@@ -121,6 +121,12 @@ static void purple_init(account_t *acc)
purple_blist_load();
purple_prefs_load();
+
+ if (proxytype == PROXY_SOCKS4A) {
+ /* do this here after loading prefs. yes, i know, it sucks */
+ purple_prefs_set_bool("/purple/proxy/socks4_remotedns", TRUE);
+ }
+
dir_fixed = TRUE;
}
@@ -1403,6 +1409,7 @@ void purple_initmodule()
if (proxytype != PROXY_NONE) {
PurpleProxyInfo *pi = purple_global_proxy_get_info();
switch (proxytype) {
+ case PROXY_SOCKS4A:
case PROXY_SOCKS4:
purple_proxy_info_set_type(pi, PURPLE_PROXY_SOCKS4);
break;