Update parser and remove most globals. Parser now supports multiple proxy chains, but the current code only uses the first one to break up the commit.
parent
71b7c8b7af
commit
8714e59afe
|
@ -10,6 +10,7 @@
|
|||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include "allocator_thread.h"
|
||||
#include "core.h"
|
||||
#include "shm.h"
|
||||
#include "debug.h"
|
||||
#include "ip_type.h"
|
||||
|
@ -17,6 +18,8 @@
|
|||
#include "hash.h"
|
||||
#include "stringdump.h"
|
||||
|
||||
extern proxy_chain_list *proxychains_chain_list;
|
||||
|
||||
/* stuff for our internal translation table */
|
||||
|
||||
typedef struct {
|
||||
|
@ -52,13 +55,12 @@ char *string_from_internal_ip(ip_type internalip) {
|
|||
return res;
|
||||
}
|
||||
|
||||
extern unsigned int remote_dns_subnet;
|
||||
ip_type make_internal_ip(uint32_t index) {
|
||||
ip_type ret;
|
||||
index++; // so we can start at .0.0.1
|
||||
if(index > 0xFFFFFF)
|
||||
return ip_type_invalid;
|
||||
ret.octet[0] = remote_dns_subnet & 0xFF;
|
||||
ret.octet[0] = proxychains_chain_list->remote_dns_subnet & 0xFF;
|
||||
ret.octet[1] = (index & 0xFF0000) >> 16;
|
||||
ret.octet[2] = (index & 0xFF00) >> 8;
|
||||
ret.octet[3] = index & 0xFF;
|
||||
|
|
45
src/core.c
45
src/core.c
|
@ -40,11 +40,8 @@
|
|||
#include "shm.h"
|
||||
#include "allocator_thread.h"
|
||||
|
||||
extern int tcp_read_time_out;
|
||||
extern int tcp_connect_time_out;
|
||||
extern int proxychains_quiet_mode;
|
||||
extern unsigned int proxychains_proxy_offset;
|
||||
extern unsigned int remote_dns_subnet;
|
||||
extern proxy_chain_list *proxychains_chain_list;
|
||||
|
||||
static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) {
|
||||
int ret;
|
||||
|
@ -140,7 +137,7 @@ static int read_n_bytes(int fd, char *buff, size_t size) {
|
|||
pfd[0].events = POLLIN;
|
||||
for(i = 0; i < size; i++) {
|
||||
pfd[0].revents = 0;
|
||||
ready = poll_retry(pfd, 1, tcp_read_time_out);
|
||||
ready = poll_retry(pfd, 1, proxychains_chain_list->tcp_read_time_out);
|
||||
if(ready != 1 || !(pfd[0].revents & POLLIN) || 1 != read(fd, &buff[i], 1))
|
||||
return -1;
|
||||
}
|
||||
|
@ -160,7 +157,7 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
|||
PDEBUG("\nconnect ret=%d\n", ret);
|
||||
|
||||
if(ret == -1 && errno == EINPROGRESS) {
|
||||
ret = poll_retry(pfd, 1, tcp_connect_time_out);
|
||||
ret = poll_retry(pfd, 1, proxychains_chain_list->tcp_connect_time_out);
|
||||
PDEBUG("\npoll ret=%d\n", ret);
|
||||
if(ret == 1) {
|
||||
value_len = sizeof(socklen_t);
|
||||
|
@ -199,7 +196,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
||||
// the results returned from gethostbyname et al.)
|
||||
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
|
||||
if(ip.octet[0] == remote_dns_subnet) {
|
||||
if(ip.octet[0] == proxychains_chain_list->remote_dns_subnet) {
|
||||
dns_len = at_get_host_for_ip(ip, hostnamebuf);
|
||||
if(!dns_len) goto err;
|
||||
else dns_name = hostnamebuf;
|
||||
|
@ -207,8 +204,8 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
|
||||
PDEBUG("host dns %s\n", dns_name ? dns_name : "<NULL>");
|
||||
|
||||
size_t ulen = strlen(user);
|
||||
size_t passlen = strlen(pass);
|
||||
size_t ulen = (user) ? strlen(user) : 0;
|
||||
size_t passlen = (pass) ? strlen(pass) : 0;
|
||||
|
||||
if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) {
|
||||
proxychains_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n");
|
||||
|
@ -231,7 +228,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
snprintf((char *) buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n", dns_name,
|
||||
ntohs(port));
|
||||
|
||||
if(user[0]) {
|
||||
if(ulen) {
|
||||
#define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1)
|
||||
// 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator.
|
||||
char src[HTTP_AUTH_MAX];
|
||||
|
@ -314,9 +311,9 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
}
|
||||
break;
|
||||
case SOCKS5_TYPE:{
|
||||
if(user) {
|
||||
if(ulen) {
|
||||
buff[0] = 5; //version
|
||||
buff[1] = 2; //nomber of methods
|
||||
buff[1] = 2; //number of methods
|
||||
buff[2] = 0; // no auth method
|
||||
buff[3] = 2; /// auth method -> username / password
|
||||
if(4 != write_n_bytes(sock, (char *) buff, 4))
|
||||
|
@ -523,7 +520,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||
|
||||
PFUNC();
|
||||
|
||||
if(pto->ip.octet[0] == remote_dns_subnet) {
|
||||
if(pto->ip.octet[0] == proxychains_chain_list->remote_dns_subnet) {
|
||||
if(!at_get_host_for_ip(pto->ip, hostname_buf)) goto usenumericip;
|
||||
else hostname = hostname_buf;
|
||||
} else {
|
||||
|
@ -552,9 +549,12 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||
return retcode;
|
||||
}
|
||||
|
||||
//~ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
//~ unsigned short target_port, proxy_data * pd,
|
||||
//~ unsigned int proxy_count, chain_type ct, unsigned int max_chain) {
|
||||
int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
unsigned short target_port, proxy_data * pd,
|
||||
unsigned int proxy_count, chain_type ct, unsigned int max_chain) {
|
||||
unsigned short target_port,
|
||||
proxy_chain *pc) {
|
||||
proxy_data p4;
|
||||
proxy_data *p1, *p2, *p3;
|
||||
int ns = -1;
|
||||
|
@ -565,13 +565,18 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
unsigned int curr_pos = 0;
|
||||
unsigned int looped = 0; // went back to start of list in RR mode
|
||||
|
||||
proxy_data * pd = pc->pd;
|
||||
unsigned int proxy_count = pc->count;
|
||||
chain_type ct = pc->ct;
|
||||
unsigned int max_chain = pc->max_chain;
|
||||
|
||||
p3 = &p4;
|
||||
|
||||
PFUNC();
|
||||
|
||||
again:
|
||||
rc = -1;
|
||||
DUMP_PROXY_CHAIN(pd, proxy_count);
|
||||
DUMP_PROXY_CHAIN(pc);
|
||||
|
||||
switch (ct) {
|
||||
case DYNAMIC_TYPE:
|
||||
|
@ -600,7 +605,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
|
||||
case ROUND_ROBIN_TYPE:
|
||||
alive_count = calc_alive(pd, proxy_count);
|
||||
curr_pos = offset = proxychains_proxy_offset;
|
||||
curr_pos = offset = pc->offset;
|
||||
if(alive_count < max_chain)
|
||||
goto error_more;
|
||||
PDEBUG("1:rr_offset = %d, curr_pos = %d\n", offset, curr_pos);
|
||||
|
@ -614,7 +619,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
} else if (looped && rc > 0 && offset >= curr_pos) {
|
||||
PDEBUG("GOTO MORE PROXIES 0\n");
|
||||
/* We've gone back to the start and now past our starting position */
|
||||
proxychains_proxy_offset = 0;
|
||||
pc->offset = 0;
|
||||
goto error_more;
|
||||
}
|
||||
PDEBUG("2:rr_offset = %d\n", offset);
|
||||
|
@ -638,8 +643,8 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
proxychains_proxy_offset = offset+1;
|
||||
PDEBUG("pd_offset = %d, curr_len = %d\n", proxychains_proxy_offset, curr_len);
|
||||
pc->offset = offset+1;
|
||||
PDEBUG("pd_offset = %d, curr_len = %d\n", pc->offset, curr_len);
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
goto error;
|
||||
break;
|
||||
|
|
27
src/core.h
27
src/core.h
|
@ -25,6 +25,8 @@
|
|||
#define __CORE_HEADER
|
||||
#define BUFF_SIZE 8*1024 // used to read responses from proxies.
|
||||
#define MAX_LOCALNET 64
|
||||
#define MAX_CHAIN_LISTS 64
|
||||
#define MAX_CHAIN 512
|
||||
|
||||
#include "ip_type.h"
|
||||
|
||||
|
@ -77,9 +79,30 @@ typedef struct {
|
|||
char pass[256];
|
||||
} proxy_data;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
chain_type ct;
|
||||
proxy_data *pd;
|
||||
unsigned int count;
|
||||
unsigned int offset;
|
||||
unsigned int max_chain;
|
||||
int tcp_read_time_out;
|
||||
int tcp_connect_time_out;
|
||||
} proxy_chain;
|
||||
|
||||
typedef struct {
|
||||
chain_type ct;
|
||||
proxy_chain *pc[MAX_CHAIN_LISTS];
|
||||
unsigned int count;
|
||||
localaddr_arg localnet_addr[MAX_LOCALNET];
|
||||
size_t num_localnet_addr;
|
||||
int remote_dns_subnet; // -1 means no remote dns
|
||||
int tcp_read_time_out;
|
||||
int tcp_connect_time_out;
|
||||
} proxy_chain_list;
|
||||
|
||||
int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port,
|
||||
proxy_data * pd, unsigned int proxy_count, chain_type ct,
|
||||
unsigned int max_chain );
|
||||
proxy_chain *pc );
|
||||
|
||||
void proxychains_write_log(char *str, ...);
|
||||
|
||||
|
|
28
src/debug.c
28
src/debug.c
|
@ -4,18 +4,30 @@
|
|||
# include "common.h"
|
||||
# include "debug.h"
|
||||
|
||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count) {
|
||||
|
||||
void DUMP_PROXY_DATA_LIST(proxy_data *plist, unsigned int count) {
|
||||
char ip_buf[16];
|
||||
for (; count; pchain++, count--) {
|
||||
pc_stringfromipv4(&pchain->ip.octet[0], ip_buf);
|
||||
PDEBUG("[%s] %s %s:%d", proxy_state_strmap[pchain->ps],
|
||||
proxy_type_strmap[pchain->pt],
|
||||
ip_buf, htons(pchain->port));
|
||||
if (*pchain->user || *pchain->pass) {
|
||||
PSTDERR(" [u=%s,p=%s]", pchain->user, pchain->pass);
|
||||
for (; count; plist++, count--) {
|
||||
pc_stringfromipv4(&plist->ip.octet[0], ip_buf);
|
||||
PDEBUG("PDATA:[%s] %s %s:%d", proxy_state_strmap[plist->ps],
|
||||
proxy_type_strmap[plist->pt],
|
||||
ip_buf, htons(plist->port));
|
||||
if (*plist->user || *plist->pass) {
|
||||
PSTDERR(" [u=%s,p=%s]", plist->user, plist->pass);
|
||||
}
|
||||
PSTDERR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DUMP_PROXY_CHAIN(proxy_chain *pchain) {
|
||||
PDEBUG("PCHAIN:[name: \"%s\"]\n", pchain->name);
|
||||
PDEBUG("PCHAIN:chain type: %s\n", chain_type_strmap[pchain->ct]);
|
||||
PDEBUG("PCHAIN:tcp_read_time_out: %d\n", pchain->tcp_read_time_out);
|
||||
PDEBUG("PCHAIN:tcp_connect_time_out: %d\n", pchain->tcp_connect_time_out);
|
||||
PDEBUG("PCHAIN:max_chain: %d\n", pchain->max_chain);
|
||||
PDEBUG("PCHAIN:offset: %d\n", pchain->offset);
|
||||
PDEBUG("PCHAIN:count: %d\n", pchain->count);
|
||||
DUMP_PROXY_DATA_LIST(pchain->pd, pchain->count);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
|
||||
|
||||
# include "core.h"
|
||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
|
||||
void DUMP_PROXY_DATA_LIST(proxy_data *plist, unsigned int count);
|
||||
void DUMP_PROXY_CHAIN(proxy_chain *pchain);
|
||||
|
||||
#else
|
||||
# define PDEBUG(fmt, args...) do {} while (0)
|
||||
# define DUMP_PROXY_CHAIN(args...) do {} while (0)
|
||||
# define DUMP_PROXY_DATA_LIST(args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#define SOCKADDR_2(x) (satosin(x)->sin_addr)
|
||||
#define SOCKPORT(x) (satosin(x)->sin_port)
|
||||
#define SOCKFAMILY(x) (satosin(x)->sin_family)
|
||||
#define MAX_CHAIN 512
|
||||
|
||||
close_t true_close;
|
||||
connect_t true_connect;
|
||||
|
@ -53,25 +52,18 @@ freeaddrinfo_t true_freeaddrinfo;
|
|||
getnameinfo_t true_getnameinfo;
|
||||
gethostbyaddr_t true_gethostbyaddr;
|
||||
|
||||
int tcp_read_time_out;
|
||||
int tcp_connect_time_out;
|
||||
chain_type proxychains_ct;
|
||||
proxy_data proxychains_pd[MAX_CHAIN];
|
||||
unsigned int proxychains_proxy_count = 0;
|
||||
unsigned int proxychains_proxy_offset = 0;
|
||||
int proxychains_got_chain_data = 0;
|
||||
unsigned int proxychains_max_chain = 1;
|
||||
int proxychains_quiet_mode = 0;
|
||||
int proxychains_resolver = 0;
|
||||
localaddr_arg localnet_addr[MAX_LOCALNET];
|
||||
size_t num_localnet_addr = 0;
|
||||
unsigned int remote_dns_subnet = 224;
|
||||
|
||||
proxy_chain_list *proxychains_chain_list = NULL;
|
||||
|
||||
pthread_once_t init_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static int init_l = 0;
|
||||
|
||||
static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct);
|
||||
static inline void get_chain_data(proxy_chain_list *pc_list);
|
||||
static inline int get_chain_type(char *buff, chain_type *ct);
|
||||
int proxy_chain_load_pdata(proxy_chain *pc, proxy_data *pd_list, int count);
|
||||
|
||||
static void* load_sym(char* symname, void* proxyfunc) {
|
||||
|
||||
|
@ -104,9 +96,26 @@ static void do_init(void) {
|
|||
core_initialize();
|
||||
at_init();
|
||||
|
||||
/* Create global library data */
|
||||
proxychains_chain_list = (proxy_chain_list*)malloc(sizeof(proxy_chain_list));
|
||||
if (proxychains_chain_list == NULL) {
|
||||
proxychains_write_log(LOG_PREFIX "Error failed to allocate proxy list object\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Initialize proxychain library data */
|
||||
proxychains_chain_list->remote_dns_subnet = -1; // -1 means no remote dns
|
||||
//~ proxychains_chain_list->pc = NULL;
|
||||
proxychains_chain_list->count = 0;
|
||||
//~ proxychains_chain_list->localnet_addr = NULL;
|
||||
proxychains_chain_list->num_localnet_addr = 0;
|
||||
proxychains_chain_list->tcp_read_time_out = 4 * 1000;
|
||||
proxychains_chain_list->tcp_connect_time_out = 10 * 1000;
|
||||
|
||||
/* read the config file */
|
||||
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
||||
DUMP_PROXY_CHAIN(proxychains_pd, proxychains_proxy_count);
|
||||
get_chain_data(proxychains_chain_list);
|
||||
PDEBUG("Finished loading chain data\n");
|
||||
DUMP_PROXY_CHAIN(proxychains_chain_list->pc[0]);
|
||||
|
||||
proxychains_write_log(LOG_PREFIX "DLL init\n");
|
||||
|
||||
|
@ -153,21 +162,19 @@ static void gcc_init(void) {
|
|||
#endif
|
||||
|
||||
/* get configuration from config file */
|
||||
static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct) {
|
||||
static void get_chain_data(proxy_chain_list *pc_list) {
|
||||
static int got_chain_data = 0;
|
||||
int count = 0, port_n = 0, list = 0;
|
||||
char buff[1024], type[1024], host[1024], user[1024];
|
||||
char buff[1024], type[1024], host[1024], label[1024];
|
||||
char *env;
|
||||
char local_in_addr_port[32];
|
||||
char local_in_addr[32], local_in_port[32], local_netmask[32];
|
||||
FILE *file = NULL;
|
||||
proxy_chain *pc_curr = NULL;
|
||||
proxy_data pd_list[MAX_CHAIN];
|
||||
|
||||
if(proxychains_got_chain_data)
|
||||
if(got_chain_data)
|
||||
return;
|
||||
|
||||
//Some defaults
|
||||
tcp_read_time_out = 4 * 1000;
|
||||
tcp_connect_time_out = 10 * 1000;
|
||||
*ct = DYNAMIC_TYPE;
|
||||
|
||||
env = get_config_path(getenv(PROXYCHAINS_CONF_FILE_ENV_VAR), buff, sizeof(buff));
|
||||
if( ( file = fopen(env, "r") ) == NULL )
|
||||
|
@ -183,60 +190,106 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||
while(fgets(buff, sizeof(buff), file)) {
|
||||
if(buff[0] != '\n' && buff[strspn(buff, " ")] != '#') {
|
||||
/* proxylist has to come last */
|
||||
if(list) {
|
||||
if(list && (buff[0] != '[')) {
|
||||
if(count >= MAX_CHAIN)
|
||||
break;
|
||||
|
||||
memset(&pd[count], 0, sizeof(proxy_data));
|
||||
memset(&pd_list[count], 0, sizeof(proxy_data));
|
||||
|
||||
pd[count].ps = PLAY_STATE;
|
||||
pd_list[count].ps = PLAY_STATE;
|
||||
pc_curr->ct = DYNAMIC_TYPE;
|
||||
pc_curr->tcp_read_time_out = pc_list->tcp_read_time_out;
|
||||
pc_curr->tcp_connect_time_out = pc_list->tcp_connect_time_out;
|
||||
port_n = 0;
|
||||
|
||||
if(strstr(buff, "tcp_read_time_out")) {
|
||||
sscanf(buff, "%s %d", label, &pc_curr->tcp_read_time_out);
|
||||
} else if(strstr(buff, "tcp_connect_time_out")) {
|
||||
sscanf(buff, "%s %d", label, &pc_curr->tcp_connect_time_out);
|
||||
} else if(strstr(buff, "chain_len")) {
|
||||
char *pc;
|
||||
int len;
|
||||
pc = strchr(buff, '=');
|
||||
len = atoi(++pc);
|
||||
pc_curr->max_chain = (len ? len : 1);
|
||||
} else if(!get_chain_type(buff, &pc_curr->ct)) {
|
||||
;
|
||||
} else {
|
||||
pd_list[count].user[0] = pd_list[count].pass[0] = '\0';
|
||||
sscanf(buff, "%s %s %d %s %s", type, host, &port_n, pd_list[count].user, pd_list[count].pass);
|
||||
|
||||
sscanf(buff, "%s %s %d %s %s", type, host, &port_n, pd[count].user, pd[count].pass);
|
||||
in_addr_t host_ip = inet_addr(host);
|
||||
if(host_ip == INADDR_NONE) {
|
||||
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
|
||||
exit(1);
|
||||
}
|
||||
pd_list[count].ip.as_int = (uint32_t) host_ip;
|
||||
pd_list[count].port = htons((unsigned short) port_n);
|
||||
|
||||
in_addr_t host_ip = inet_addr(host);
|
||||
if(host_ip == INADDR_NONE) {
|
||||
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
|
||||
exit(1);
|
||||
if(!strcmp(type, "http")) {
|
||||
pd_list[count].pt = HTTP_TYPE;
|
||||
} else if(!strcmp(type, "socks4")) {
|
||||
pd_list[count].pt = SOCKS4_TYPE;
|
||||
} else if(!strcmp(type, "socks5")) {
|
||||
pd_list[count].pt = SOCKS5_TYPE;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
pd[count].ip.as_int = (uint32_t) host_ip;
|
||||
pd[count].port = htons((unsigned short) port_n);
|
||||
|
||||
if(!strcmp(type, "http")) {
|
||||
pd[count].pt = HTTP_TYPE;
|
||||
} else if(!strcmp(type, "socks4")) {
|
||||
pd[count].pt = SOCKS4_TYPE;
|
||||
} else if(!strcmp(type, "socks5")) {
|
||||
pd[count].pt = SOCKS5_TYPE;
|
||||
} else
|
||||
continue;
|
||||
|
||||
if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) - 1)
|
||||
if(pd_list[count].ip.as_int && port_n && pd_list[count].ip.as_int != (uint32_t) - 1)
|
||||
count++;
|
||||
} else {
|
||||
if(strstr(buff, "[ProxyList]")) {
|
||||
char *s1, *s2;
|
||||
if((s1=strstr(buff, "[")) && (s1 < (s2=strstr(buff, "]")))) {
|
||||
/* If have a previous chain stored in the temp chain, copy
|
||||
to global lists. */
|
||||
if (count) {
|
||||
proxy_chain_load_pdata(pc_curr, pd_list, count);
|
||||
count = 0;
|
||||
}
|
||||
|
||||
PDEBUG("Parsing chain: %s\n", buff);
|
||||
if (pc_list->count >= MAX_CHAIN_LISTS) {
|
||||
proxychains_write_log(LOG_PREFIX "Warning more than %d lists defined in configfile, skipping any more list definitions.\n", MAX_CHAIN_LISTS);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create new proxy list */
|
||||
pc_curr = pc_list->pc[pc_list->count++] = (proxy_chain*)malloc(sizeof(proxy_chain));
|
||||
if (pc_curr == NULL) {
|
||||
proxychains_write_log(LOG_PREFIX "Error failed to allocate proxy chain object\n");
|
||||
exit(1);
|
||||
}
|
||||
pc_curr->count = 0;
|
||||
pc_curr->offset = 0;
|
||||
pc_curr->max_chain = 1;
|
||||
pc_curr->tcp_read_time_out = pc_list->tcp_read_time_out;
|
||||
pc_curr->tcp_connect_time_out = pc_list->tcp_connect_time_out;
|
||||
|
||||
pc_curr->name = (char*)malloc(sizeof(char)*(s2-s1));
|
||||
if (pc_curr->name == NULL) {
|
||||
proxychains_write_log(LOG_PREFIX "Error failed to allocate proxy chain name string\n");
|
||||
exit(1);
|
||||
}
|
||||
strncpy(pc_curr->name, s1, s2-s1);
|
||||
|
||||
list = 1;
|
||||
} else if(strstr(buff, "random_chain")) {
|
||||
*ct = RANDOM_TYPE;
|
||||
} else if(strstr(buff, "strict_chain")) {
|
||||
*ct = STRICT_TYPE;
|
||||
} else if(strstr(buff, "dynamic_chain")) {
|
||||
*ct = DYNAMIC_TYPE;
|
||||
} else if(strstr(buff, "round_robin_chain")) {
|
||||
*ct = ROUND_ROBIN_TYPE;
|
||||
} else if(!get_chain_type(buff, &pc_list->ct)) {
|
||||
;
|
||||
} else if(strstr(buff, "tcp_read_time_out")) {
|
||||
sscanf(buff, "%s %d", user, &tcp_read_time_out);
|
||||
sscanf(buff, "%s %d", label, &pc_list->tcp_read_time_out);
|
||||
} else if(strstr(buff, "tcp_connect_time_out")) {
|
||||
sscanf(buff, "%s %d", user, &tcp_connect_time_out);
|
||||
sscanf(buff, "%s %d", label, &pc_list->tcp_connect_time_out);
|
||||
} else if(strstr(buff, "remote_dns_subnet")) {
|
||||
sscanf(buff, "%s %d", user, &remote_dns_subnet);
|
||||
if(remote_dns_subnet >= 256) {
|
||||
sscanf(buff, "%s %d", label, &pc_list->remote_dns_subnet);
|
||||
if(pc_list->remote_dns_subnet >= 256) {
|
||||
fprintf(stderr,
|
||||
"remote_dns_subnet: invalid value. requires a number between 0 and 255.\n");
|
||||
exit(1);
|
||||
}
|
||||
} else if(strstr(buff, "localnet")) {
|
||||
if(sscanf(buff, "%s %21[^/]/%15s", user, local_in_addr_port, local_netmask) < 3) {
|
||||
localaddr_arg *laddr_a = &pc_list->localnet_addr[pc_list->num_localnet_addr];
|
||||
if(sscanf(buff, "%s %21[^/]/%15s", label, local_in_addr_port, local_netmask) < 3) {
|
||||
fprintf(stderr, "localnet format error");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -250,38 +303,27 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||
PDEBUG("added localnet: netaddr=%s, port=%s, netmask=%s\n",
|
||||
local_in_addr, local_in_port, local_netmask);
|
||||
}
|
||||
if(num_localnet_addr < MAX_LOCALNET) {
|
||||
if(pc_list->num_localnet_addr < MAX_LOCALNET) {
|
||||
int error;
|
||||
error =
|
||||
inet_pton(AF_INET, local_in_addr,
|
||||
&localnet_addr[num_localnet_addr].in_addr);
|
||||
error = inet_pton(AF_INET, local_in_addr, &laddr_a->in_addr);
|
||||
if(error <= 0) {
|
||||
fprintf(stderr, "localnet address error\n");
|
||||
exit(1);
|
||||
}
|
||||
error =
|
||||
inet_pton(AF_INET, local_netmask,
|
||||
&localnet_addr[num_localnet_addr].netmask);
|
||||
error = inet_pton(AF_INET, local_netmask, &laddr_a->netmask);
|
||||
if(error <= 0) {
|
||||
fprintf(stderr, "localnet netmask error\n");
|
||||
exit(1);
|
||||
}
|
||||
if(local_in_port[0]) {
|
||||
localnet_addr[num_localnet_addr].port =
|
||||
(short) atoi(local_in_port);
|
||||
laddr_a->port = (short) atoi(local_in_port);
|
||||
} else {
|
||||
localnet_addr[num_localnet_addr].port = 0;
|
||||
laddr_a->port = 0;
|
||||
}
|
||||
++num_localnet_addr;
|
||||
++pc_list->num_localnet_addr;
|
||||
} else {
|
||||
fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET);
|
||||
}
|
||||
} else if(strstr(buff, "chain_len")) {
|
||||
char *pc;
|
||||
int len;
|
||||
pc = strchr(buff, '=');
|
||||
len = atoi(++pc);
|
||||
proxychains_max_chain = (len ? len : 1);
|
||||
} else if(strstr(buff, "quiet_mode")) {
|
||||
proxychains_quiet_mode = 1;
|
||||
} else if(strstr(buff, "proxy_dns")) {
|
||||
|
@ -290,9 +332,43 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If have a previous chain stored in the temp chain, copy
|
||||
to global lists. This is needed for the last defined chain. */
|
||||
if (count) {
|
||||
proxy_chain_load_pdata(pc_curr, pd_list, count);
|
||||
count = 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
*proxy_count = count;
|
||||
proxychains_got_chain_data = 1;
|
||||
//~ *proxy_count = count;
|
||||
got_chain_data = 1;
|
||||
}
|
||||
|
||||
int get_chain_type(char *buff, chain_type *ct) {
|
||||
if(strstr(buff, "random_chain"))
|
||||
*ct = RANDOM_TYPE;
|
||||
else if(strstr(buff, "strict_chain"))
|
||||
*ct = STRICT_TYPE;
|
||||
else if(strstr(buff, "dynamic_chain"))
|
||||
*ct = DYNAMIC_TYPE;
|
||||
else if(strstr(buff, "round_robin_chain"))
|
||||
*ct = ROUND_ROBIN_TYPE;
|
||||
else
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proxy_chain_load_pdata(proxy_chain *pc, proxy_data *pd_list, int count) {
|
||||
pc->count = count;
|
||||
pc->pd = (proxy_data*)malloc(sizeof(proxy_data)*count);
|
||||
if (pc->pd == NULL) {
|
||||
proxychains_write_log(LOG_PREFIX "Error failed to allocate proxy data list for \"%s\" chain\n", pc->name);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(pc->pd, pd_list, sizeof(proxy_data)*count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******* HOOK FUNCTIONS *******/
|
||||
|
@ -336,12 +412,12 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||
#endif
|
||||
|
||||
// check if connect called from proxydns
|
||||
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
||||
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == proxychains_chain_list->remote_dns_subnet);
|
||||
|
||||
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
|
||||
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr)
|
||||
== (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
||||
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
|
||||
for(i = 0; i < proxychains_chain_list->num_localnet_addr && !remote_dns_connect; i++) {
|
||||
if((proxychains_chain_list->localnet_addr[i].in_addr.s_addr & proxychains_chain_list->localnet_addr[i].netmask.s_addr)
|
||||
== (p_addr_in->s_addr & proxychains_chain_list->localnet_addr[i].netmask.s_addr)) {
|
||||
if(!proxychains_chain_list->localnet_addr[i].port || proxychains_chain_list->localnet_addr[i].port == port) {
|
||||
PDEBUG("accessing localnet using true_connect\n");
|
||||
return true_connect(sock, addr, len);
|
||||
}
|
||||
|
@ -357,7 +433,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||
ret = connect_proxy_chain(sock,
|
||||
dest_ip,
|
||||
SOCKPORT(*addr),
|
||||
proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
|
||||
proxychains_chain_list->pc[0]);
|
||||
|
||||
fcntl(sock, F_SETFL, flags);
|
||||
if(ret != SUCCESS)
|
||||
|
|
Loading…
Reference in New Issue