Support hostnames for chained socks5+/socks4+/connect+ requests

This commit is contained in:
z3APA3A 2017-03-07 01:19:04 +03:00
parent 4e4c090373
commit 4251322aad
4 changed files with 27 additions and 27 deletions

View File

@ -9,7 +9,7 @@
#include "proxy.h" #include "proxy.h"
int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr){ int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr, unsigned char * hostname){
unsigned char *buf; unsigned char *buf;
unsigned char *username; unsigned char *username;
int res; int res;
@ -40,11 +40,11 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
case R_CONNECTP: case R_CONNECTP:
{ {
len = sprintf((char *)buf, "CONNECT "); len = sprintf((char *)buf, "CONNECT ");
if(redir->type == R_CONNECTP && param->hostname) { if(redir->type == R_CONNECTP && hostname) {
char * needreplace; char * needreplace;
needreplace = strchr((char *)param->hostname, ':'); needreplace = strchr((char *)hostname, ':');
if(needreplace) buf[len++] = '['; if(needreplace) buf[len++] = '[';
len += sprintf((char *)buf + len, "%.256s", (char *)param->hostname); len += sprintf((char *)buf + len, "%.256s", (char *)hostname);
if(needreplace) buf[len++] = ']'; if(needreplace) buf[len++] = ']';
} }
else { else {
@ -82,7 +82,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
buf[0] = 4; buf[0] = 4;
buf[1] = 1; buf[1] = 1;
memcpy(buf+2, SAPORT(addr), 2); memcpy(buf+2, SAPORT(addr), 2);
if(redir->type == R_SOCKS4P && param->hostname) { if(redir->type == R_SOCKS4P && hostname) {
buf[4] = buf[5] = buf[6] = 0; buf[4] = buf[5] = buf[6] = 0;
buf[7] = 3; buf[7] = 3;
} }
@ -91,12 +91,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
len = (int)strlen((char *)user) + 1; len = (int)strlen((char *)user) + 1;
memcpy(buf+8, user, len); memcpy(buf+8, user, len);
len += 8; len += 8;
if(redir->type == R_SOCKS4P && param->hostname) { if(redir->type == R_SOCKS4P && hostname) {
int hostnamelen; int hostnamelen;
hostnamelen = (int)strlen((char *)param->hostname) + 1; hostnamelen = (int)strlen((char *)hostname) + 1;
if(hostnamelen > 255) hostnamelen = 255; if(hostnamelen > 255) hostnamelen = 255;
memcpy(buf+len, param->hostname, hostnamelen); memcpy(buf+len, hostname, hostnamelen);
len += hostnamelen; len += hostnamelen;
} }
if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){ if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){
@ -159,12 +159,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
buf[0] = 5; buf[0] = 5;
buf[1] = 1; buf[1] = 1;
buf[2] = 0; buf[2] = 0;
if(redir->type == R_SOCKS5P && param->hostname) { if(redir->type == R_SOCKS5P && hostname) {
buf[3] = 3; buf[3] = 3;
len = (int)strlen((char *)param->hostname); len = (int)strlen((char *)hostname);
if(len > 255) len = 255; if(len > 255) len = 255;
buf[4] = len; buf[4] = len;
memcpy(buf + 5, param->hostname, len); memcpy(buf + 5, hostname, len);
len += 5; len += 5;
} }
else { else {
@ -304,7 +304,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
} }
} }
else { else {
res = (redir)?clientnegotiate(redir, param, (struct sockaddr *)&cur->addr):0; res = (redir)?clientnegotiate(redir, param, (struct sockaddr *)&cur->addr, cur->exthost):0;
if(res) return res; if(res) return res;
} }
redir = cur; redir = cur;
@ -327,7 +327,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
} }
if(!connected || !redir) return 0; if(!connected || !redir) return 0;
return clientnegotiate(redir, param, (struct sockaddr *)&param->req); return clientnegotiate(redir, param, (struct sockaddr *)&param->req, param->hostname);
} }
int IPInentry(struct sockaddr *sa, struct iplist *ipentry){ int IPInentry(struct sockaddr *sa, struct iplist *ipentry){

View File

@ -701,21 +701,12 @@ static int h_parent(int argc, unsigned char **argv){
} }
acl->action = 2; acl->action = 2;
chains = NULL; chains = myalloc(sizeof(struct chain));
if(!acl->chains) {
chains = acl->chains = myalloc(sizeof(struct chain));
}
else {
chains = acl->chains;
while(chains->next)chains = chains->next;
chains->next = myalloc(sizeof(struct chain));
chains = chains->next;
}
memset(chains, 0, sizeof(struct chain));
if(!chains){ if(!chains){
fprintf(stderr, "Chainig error: unable to allocate memory for chain\n"); fprintf(stderr, "Chainig error: unable to allocate memory for chain\n");
return(2); return(2);
} }
memset(chains, 0, sizeof(struct chain));
chains->weight = (unsigned)atoi((char *)argv[1]); chains->weight = (unsigned)atoi((char *)argv[1]);
if(chains->weight == 0 || chains->weight >1000) { if(chains->weight == 0 || chains->weight >1000) {
fprintf(stderr, "Chaining error: bad chain weight %u line %d\n", chains->weight, linenum); fprintf(stderr, "Chaining error: bad chain weight %u line %d\n", chains->weight, linenum);
@ -742,9 +733,19 @@ static int h_parent(int argc, unsigned char **argv){
return(4); return(4);
} }
if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return 5; if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return 5;
chains->exthost = (unsigned char *)mystrdup((char *)argv[3]);
*SAPORT(&chains->addr) = htons((unsigned short)atoi((char *)argv[4])); *SAPORT(&chains->addr) = htons((unsigned short)atoi((char *)argv[4]));
if(argc > 5) chains->extuser = (unsigned char *)mystrdup((char *)argv[5]); if(argc > 5) chains->extuser = (unsigned char *)mystrdup((char *)argv[5]);
if(argc > 6) chains->extpass = (unsigned char *)mystrdup((char *)argv[6]); if(argc > 6) chains->extpass = (unsigned char *)mystrdup((char *)argv[6]);
if(!acl->chains) {
acl->chains = chains;
}
else {
struct chain *tmpchain;
for(tmpchain = acl->chains; tmpchain->next; tmpchain = tmpchain->next);
tmpchain->next = chains;
}
return 0; return 0;
} }
@ -1126,9 +1127,6 @@ static int h_ace(int argc, unsigned char **argv){
if(!getip46(46, argv[1], (struct sockaddr *)&acl->chains->addr)) return 5; if(!getip46(46, argv[1], (struct sockaddr *)&acl->chains->addr)) return 5;
*SAPORT(&acl->chains->addr) = htons((unsigned short)atoi((char *)argv[2])); *SAPORT(&acl->chains->addr) = htons((unsigned short)atoi((char *)argv[2]));
acl->chains->weight = 1000; acl->chains->weight = 1000;
acl->chains->extuser = NULL;
acl->chains->extpass = NULL;
acl->chains->next = NULL;
case ALLOW: case ALLOW:
case DENY: case DENY:
if(!conf.acl){ if(!conf.acl){

View File

@ -1123,6 +1123,7 @@ void freeacl(struct ace *ac){
for(ch = ac->chains; ch; ch = (struct chain *) itfree(ch, ch->next)){ for(ch = ac->chains; ch; ch = (struct chain *) itfree(ch, ch->next)){
if(ch->extuser) myfree(ch->extuser); if(ch->extuser) myfree(ch->extuser);
if(ch->extpass) myfree(ch->extpass); if(ch->extpass) myfree(ch->extpass);
if(ch->exthost) myfree(ch->exthost);
} }
} }
} }

View File

@ -261,6 +261,7 @@ struct chain {
struct sockaddr_in addr; struct sockaddr_in addr;
#endif #endif
unsigned short weight; unsigned short weight;
unsigned char * exthost;
unsigned char * extuser; unsigned char * extuser;
unsigned char * extpass; unsigned char * extpass;
}; };