mirror of
https://github.com/rofl0r/proxychains-ng
synced 2025-01-09 23:02:52 +08:00
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.
This commit is contained in:
parent
71b7c8b7af
commit
a65f0f47a0
@ -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,28 @@ 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 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;
|
||||
//~ 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;
|
||||
//~ 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 +106,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 +172,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 +200,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 +313,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 +342,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 +422,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 +443,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
Block a user