Skip to content

Commit

Permalink
add src ip disclosure options to socks4
Browse files Browse the repository at this point in the history
Append the client IP address (and optionally the port) to the SOCKS4 login
name.
  • Loading branch information
wertarbyte committed Apr 13, 2016
1 parent f94a981 commit 182daac
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 9 deletions.
2 changes: 2 additions & 0 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ static int vp_disclose_src(parser_context *context, void *addr, const char *toke
{ "X-Forwarded-For", DISCLOSE_X_FORWARDED_FOR },
{ "Forwarded_ip", DISCLOSE_FORWARDED_IP },
{ "Forwarded_ipport", DISCLOSE_FORWARDED_IPPORT },
{ "username_append_ip", DISCLOSE_USERNAME_APPEND_IP },
{ "username_append_ipport", DISCLOSE_USERNAME_APPEND_IPPORT },
};
for (int i = 0; i < SIZEOF_ARRAY(opt); ++i) {
if (strcmp(token, opt[i].name) == 0) {
Expand Down
2 changes: 2 additions & 0 deletions parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ enum disclose_src_e {
DISCLOSE_X_FORWARDED_FOR,
DISCLOSE_FORWARDED_IP,
DISCLOSE_FORWARDED_IPPORT,
DISCLOSE_USERNAME_APPEND_IP,
DISCLOSE_USERNAME_APPEND_IPPORT,
};

typedef enum {
Expand Down
20 changes: 17 additions & 3 deletions redsocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,23 @@ static int redsocks_onexit(parser_section *section)
return -1;
}

if (instance->config.disclose_src != DISCLOSE_NONE && instance->relay_ss != &http_connect_subsys) {
parser_error(section->context, "only `http-connect` supports `disclose_src` at the moment");
return -1;
switch(instance->config.disclose_src) {
case DISCLOSE_X_FORWARDED_FOR:
case DISCLOSE_FORWARDED_IP:
case DISCLOSE_FORWARDED_IPPORT:
if (instance->relay_ss != &http_connect_subsys) {
parser_error(section->context, "only `http-connect` supports the configured `disclose_src` option at the moment");
return -1;
}
case DISCLOSE_USERNAME_APPEND_IP:
case DISCLOSE_USERNAME_APPEND_IPPORT:
if (instance->relay_ss != &socks4_subsys) {
parser_error(section->context, "only `socks4` supports the configured `disclose_src` option at the moment");
return -1;
}
case DISCLOSE_NONE:
default:
break;
}

if (!instance->config.min_backoff_ms) {
Expand Down
4 changes: 4 additions & 0 deletions redsocks.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ redsocks {
// X-Forwarded-For -- X-Forwarded-For: IP
// Forwarded_ip -- Forwarded: for=IP # see RFC7239
// Forwarded_ipport -- Forwarded: for="IP:port" # see RFC7239
// socks4 supports:
// username_append_ip -- login@IP
// username_append_ipport -- login@IP:port
//
// disclose_src = false;
}

Expand Down
35 changes: 29 additions & 6 deletions socks4.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,42 @@ static void socks4_read_cb(struct bufferevent *buffev, void *_arg)
static struct evbuffer *socks4_mkconnect(redsocks_client *client)
{
const redsocks_config *config = &client->instance->config;
const char *username = config->login ? config->login : "";
const char *login = config->login ? config->login : "";

// space for \0 comes from socks4_req->login
size_t username_len = strlen(username);
size_t len = sizeof(socks4_req) + username_len;
socks4_req *req = calloc(1, len);
size_t buf_len = sizeof(socks4_req) + strlen(login);
if (config->disclose_src == DISCLOSE_USERNAME_APPEND_IP ||
config->disclose_src == DISCLOSE_USERNAME_APPEND_IPPORT) {
buf_len += NI_MAXHOST + 1 + NI_MAXSERV + 1;
}

socks4_req *req = calloc(1, buf_len);

req->ver = socks4_ver;
req->cmd = socks4_cmd_connect;
req->port = client->destaddr.sin_port;
req->addr = client->destaddr.sin_addr.s_addr;
memcpy(req->login, username, username_len + 1);
strcat(req->login, login);
if (config->disclose_src == DISCLOSE_USERNAME_APPEND_IP ||
config->disclose_src == DISCLOSE_USERNAME_APPEND_IPPORT) {
strcat(req->login, "@");
// append origin addresss (and maybe port) to login (separated by @)
char host[NI_MAXHOST];
char port[NI_MAXSERV];
if (!getnameinfo((struct sockaddr*) &client->clientaddr, sizeof(client->clientaddr),
host, sizeof(host),
port, sizeof(port),
NI_NUMERICHOST)) {
strcat(req->login, host);
// also append the port
if (config->disclose_src == DISCLOSE_USERNAME_APPEND_IPPORT) {
strcat(req->login, ":");
strcat(req->login, port);
}
}
}

struct evbuffer *ret = mkevbuffer(req, len);
struct evbuffer *ret = mkevbuffer(req, sizeof(socks4_req) + strlen(req->login));
free(req);
return ret;
}
Expand Down

0 comments on commit 182daac

Please sign in to comment.