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"
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 *username;
int res;
@ -40,11 +40,11 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
case R_CONNECTP:
{
len = sprintf((char *)buf, "CONNECT ");
if(redir->type == R_CONNECTP && param->hostname) {
if(redir->type == R_CONNECTP && hostname) {
char * needreplace;
needreplace = strchr((char *)param->hostname, ':');
needreplace = strchr((char *)hostname, ':');
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++] = ']';
}
else {
@ -82,7 +82,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
buf[0] = 4;
buf[1] = 1;
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[7] = 3;
}
@ -91,12 +91,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
len = (int)strlen((char *)user) + 1;
memcpy(buf+8, user, len);
len += 8;
if(redir->type == R_SOCKS4P && param->hostname) {
if(redir->type == R_SOCKS4P && hostname) {
int hostnamelen;
hostnamelen = (int)strlen((char *)param->hostname) + 1;
hostnamelen = (int)strlen((char *)hostname) + 1;
if(hostnamelen > 255) hostnamelen = 255;
memcpy(buf+len, param->hostname, hostnamelen);
memcpy(buf+len, hostname, hostnamelen);
len += hostnamelen;
}
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[1] = 1;
buf[2] = 0;
if(redir->type == R_SOCKS5P && param->hostname) {
if(redir->type == R_SOCKS5P && hostname) {
buf[3] = 3;
len = (int)strlen((char *)param->hostname);
len = (int)strlen((char *)hostname);
if(len > 255) len = 255;
buf[4] = len;
memcpy(buf + 5, param->hostname, len);
memcpy(buf + 5, hostname, len);
len += 5;
}
else {
@ -304,7 +304,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
}
}
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;
}
redir = cur;
@ -327,7 +327,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
}
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){

View File

@ -701,21 +701,12 @@ static int h_parent(int argc, unsigned char **argv){
}
acl->action = 2;
chains = NULL;
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));
chains = myalloc(sizeof(struct chain));
if(!chains){
fprintf(stderr, "Chainig error: unable to allocate memory for chain\n");
return(2);
}
memset(chains, 0, sizeof(struct chain));
chains->weight = (unsigned)atoi((char *)argv[1]);
if(chains->weight == 0 || chains->weight >1000) {
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);
}
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]));
if(argc > 5) chains->extuser = (unsigned char *)mystrdup((char *)argv[5]);
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;
}
@ -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;
*SAPORT(&acl->chains->addr) = htons((unsigned short)atoi((char *)argv[2]));
acl->chains->weight = 1000;
acl->chains->extuser = NULL;
acl->chains->extpass = NULL;
acl->chains->next = NULL;
case ALLOW:
case DENY:
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)){
if(ch->extuser) myfree(ch->extuser);
if(ch->extpass) myfree(ch->extpass);
if(ch->exthost) myfree(ch->exthost);
}
}
}

View File

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