From fb5588856fa4dd6f140c72f7360302fe85b20c75 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 19 Apr 2012 14:10:54 +0200 Subject: [PATCH] Add support for SOCKS 5 proxies. This only covers outgoing TCP connections, and supports only username/password authentication or no authentication. --- src/net_setup.c | 2 +- src/protocol_auth.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/net_setup.c b/src/net_setup.c index 2eff09f3..eec438a8 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -422,7 +422,7 @@ static bool setup_myself(void) { if(proxyuser && *proxyuser) proxyuser = xstrdup(proxyuser); if(proxypass && *proxypass) - proxyuser = xstrdup(proxypass); + proxypass = xstrdup(proxypass); break; } diff --git a/src/protocol_auth.c b/src/protocol_auth.c index e5c4c166..81189332 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -67,8 +67,54 @@ static bool send_proxyrequest(connection_t *c) { c->tcplen = 8; return send_meta(c, s4req, sizeof s4req); } + case PROXY_SOCKS5: { + int len = 3 + 6 + (c->address.sa.sa_family == AF_INET ? 4 : 16); + c->tcplen = 2; + if(proxypass) + len += 3 + strlen(proxyuser) + strlen(proxypass); + char s5req[len]; + int i = 0; + s5req[i++] = 5; + s5req[i++] = 1; + if(proxypass) { + s5req[i++] = 2; + s5req[i++] = 1; + s5req[i++] = strlen(proxyuser); + strcpy(s5req + i, proxyuser); + i += strlen(proxyuser); + s5req[i++] = strlen(proxypass); + strcpy(s5req + i, proxypass); + i += strlen(proxypass); + c->tcplen += 2; + } else { + s5req[i++] = 0; + } + s5req[i++] = 5; + s5req[i++] = 1; + s5req[i++] = 0; + if(c->address.sa.sa_family == AF_INET) { + s5req[i++] = 1; + memcpy(s5req + i, &c->address.in.sin_addr, 4); + i += 4; + memcpy(s5req + i, &c->address.in.sin_port, 2); + i += 2; + c->tcplen += 10; + } else if(c->address.sa.sa_family == AF_INET6) { + s5req[i++] = 3; + memcpy(s5req + i, &c->address.in6.sin6_addr, 16); + i += 16; + memcpy(s5req + i, &c->address.in6.sin6_port, 2); + i += 2; + c->tcplen += 22; + } else { + logger(LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family); + return false; + } + if(i > len) + abort(); + return send_meta(c, s5req, sizeof s5req); + } case PROXY_SOCKS4A: - case PROXY_SOCKS5: logger(LOG_ERR, "Proxy type not implemented yet"); return false; default: -- 2.20.1