diff options
| -rw-r--r-- | conf.c | 2 | ||||
| -rw-r--r-- | lib/proxy.c | 29 | ||||
| -rw-r--r-- | lib/proxy.h | 1 | ||||
| -rw-r--r-- | lib/url.c | 2 | ||||
| -rw-r--r-- | lib/url.h | 1 | ||||
| -rw-r--r-- | protocols/purple/purple.c | 7 | 
6 files changed, 35 insertions, 7 deletions
| @@ -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; @@ -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;  		} @@ -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; | 
