Merge 7d60f55c60
into b9ca1cdefd
commit
fd81555ad9
2
Makefile
2
Makefile
|
@ -18,7 +18,7 @@ OBJS = $(SRCS:.c=.o)
|
|||
LOBJS = src/nameinfo.o \
|
||||
src/core.o src/common.o src/libproxychains.o src/shm.o \
|
||||
src/allocator_thread.o src/ip_type.o src/stringdump.o \
|
||||
src/hostentdb.o src/hash.o
|
||||
src/hostentdb.o src/hash.o src/debug.o
|
||||
|
||||
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
|
||||
NO_AS_NEEDED = -Wl,--no-as-needed
|
||||
|
|
|
@ -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;
|
||||
|
|
20
src/common.c
20
src/common.c
|
@ -3,6 +3,26 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
const char *proxy_type_strmap[] = {
|
||||
"http",
|
||||
"socks4",
|
||||
"socks5",
|
||||
};
|
||||
|
||||
const char *chain_type_strmap[] = {
|
||||
"dynamic_chain",
|
||||
"strict_chain",
|
||||
"random_chain",
|
||||
"round_robin_chain",
|
||||
};
|
||||
|
||||
const char *proxy_state_strmap[] = {
|
||||
"play",
|
||||
"down",
|
||||
"blocked",
|
||||
"busy",
|
||||
};
|
||||
|
||||
// stolen from libulz (C) rofl0r
|
||||
void pc_stringfromipv4(unsigned char *ip_buf_4_bytes, char *outbuf_16_bytes) {
|
||||
unsigned char *p;
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
#define COMMON_H
|
||||
|
||||
#define PROXYCHAINS_CONF_FILE_ENV_VAR "PROXYCHAINS_CONF_FILE"
|
||||
#define PROXYCHAINS_CHAIN_ENV_VAR "PROXYCHAINS_CHAIN"
|
||||
#define PROXYCHAINS_QUIET_MODE_ENV_VAR "PROXYCHAINS_QUIET_MODE"
|
||||
#define PROXYCHAINS_CONF_FILE "proxychains.conf"
|
||||
#define PROXYCHAINS_DEFAULT_CHAIN "ProxyList"
|
||||
#define LOG_PREFIX "[proxychains] "
|
||||
#ifndef SYSCONFDIR
|
||||
#define SYSCONFDIR "/etc"
|
||||
|
@ -11,6 +13,10 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
extern const char *proxy_type_strmap[];
|
||||
extern const char *chain_type_strmap[];
|
||||
extern const char *proxy_state_strmap[];
|
||||
|
||||
char *get_config_path(char* default_path, char* pbuf, size_t bufsize);
|
||||
void pc_stringfromipv4(unsigned char *ip_buf_4_bytes, char *outbuf_16_bytes);
|
||||
|
||||
|
|
138
src/core.c
138
src/core.c
|
@ -40,10 +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 remote_dns_subnet;
|
||||
extern proxy_chain_list *proxychains_chain_list;
|
||||
|
||||
static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) {
|
||||
int ret;
|
||||
|
@ -130,7 +128,7 @@ static int write_n_bytes(int fd, char *buff, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
static int read_n_bytes(int fd, char *buff, size_t size) {
|
||||
static int read_n_bytes(int fd, char *buff, size_t size, int read_time_out) {
|
||||
int ready;
|
||||
size_t i;
|
||||
struct pollfd pfd[1];
|
||||
|
@ -139,14 +137,14 @@ 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, read_time_out);
|
||||
if(ready != 1 || !(pfd[0].revents & POLLIN) || 1 != read(fd, &buff[i], 1))
|
||||
return -1;
|
||||
}
|
||||
return (int) size;
|
||||
}
|
||||
|
||||
static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
||||
static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len, int connect_time_out) {
|
||||
int ret, value;
|
||||
socklen_t value_len;
|
||||
struct pollfd pfd[1];
|
||||
|
@ -159,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, connect_time_out);
|
||||
PDEBUG("\npoll ret=%d\n", ret);
|
||||
if(ret == 1) {
|
||||
value_len = sizeof(socklen_t);
|
||||
|
@ -187,7 +185,7 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
|||
|
||||
|
||||
#define INVALID_INDEX 0xFFFFFFFFU
|
||||
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) {
|
||||
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass, int read_time_out) {
|
||||
char *dns_name = NULL;
|
||||
char hostnamebuf[MSG_LEN_MAX];
|
||||
size_t dns_len = 0;
|
||||
|
@ -198,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;
|
||||
|
@ -206,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");
|
||||
|
@ -230,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];
|
||||
|
@ -256,7 +254,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
len = 0;
|
||||
// read header byte by byte.
|
||||
while(len < BUFF_SIZE) {
|
||||
if(1 == read_n_bytes(sock, (char *) (buff + len), 1))
|
||||
if(1 == read_n_bytes(sock, (char *) (buff + len), 1, read_time_out))
|
||||
len++;
|
||||
else
|
||||
goto err;
|
||||
|
@ -267,8 +265,10 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
}
|
||||
|
||||
// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
|
||||
if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0'))
|
||||
if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0')) {
|
||||
PDEBUG("HTTP proxy blocked: buff=\"%s\"\n", buff);
|
||||
return BLOCKED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
if((len + 8) != write_n_bytes(sock, (char *) buff, (8 + len)))
|
||||
goto err;
|
||||
|
||||
if(8 != read_n_bytes(sock, (char *) buff, 8))
|
||||
if(8 != read_n_bytes(sock, (char *) buff, 8, read_time_out))
|
||||
goto err;
|
||||
|
||||
if(buff[0] != 0 || buff[1] != 90)
|
||||
|
@ -311,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))
|
||||
|
@ -326,7 +326,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
goto err;
|
||||
}
|
||||
|
||||
if(2 != read_n_bytes(sock, (char *) buff, 2))
|
||||
if(2 != read_n_bytes(sock, (char *) buff, 2, read_time_out))
|
||||
goto err;
|
||||
|
||||
if(buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) {
|
||||
|
@ -356,7 +356,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
goto err;
|
||||
|
||||
|
||||
if(2 != read_n_bytes(sock, in, 2))
|
||||
if(2 != read_n_bytes(sock, in, 2, read_time_out))
|
||||
goto err;
|
||||
if(in[0] != 1 || in[1] != 0) {
|
||||
if(in[0] != 1)
|
||||
|
@ -388,7 +388,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
if(buff_iter != write_n_bytes(sock, (char *) buff, buff_iter))
|
||||
goto err;
|
||||
|
||||
if(4 != read_n_bytes(sock, (char *) buff, 4))
|
||||
if(4 != read_n_bytes(sock, (char *) buff, 4, read_time_out))
|
||||
goto err;
|
||||
|
||||
if(buff[0] != 5 || buff[1] != 0)
|
||||
|
@ -404,14 +404,14 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
break;
|
||||
case 3:
|
||||
len = 0;
|
||||
if(1 != read_n_bytes(sock, (char *) &len, 1))
|
||||
if(1 != read_n_bytes(sock, (char *) &len, 1, read_time_out))
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(len + 2 != read_n_bytes(sock, (char *) buff, len + 2))
|
||||
if(len + 2 != read_n_bytes(sock, (char *) buff, len + 2, read_time_out))
|
||||
goto err;
|
||||
|
||||
return SUCCESS;
|
||||
|
@ -427,8 +427,9 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||
#define DT "Dynamic chain"
|
||||
#define ST "Strict chain"
|
||||
#define RT "Random chain"
|
||||
#define RRT "Round Robin chain"
|
||||
|
||||
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
||||
static int start_chain(int *fd, proxy_data * pd, char *begin_mark, int connect_time_out) {
|
||||
struct sockaddr_in addr;
|
||||
char ip_buf[16];
|
||||
|
||||
|
@ -444,7 +445,7 @@ static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
|||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = (in_addr_t) pd->ip.as_int;
|
||||
addr.sin_port = pd->port;
|
||||
if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr))) {
|
||||
if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr), connect_time_out)) {
|
||||
pd->ps = DOWN_STATE;
|
||||
goto error1;
|
||||
}
|
||||
|
@ -511,7 +512,7 @@ static unsigned int calc_alive(proxy_data * pd, unsigned int proxy_count) {
|
|||
}
|
||||
|
||||
|
||||
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto, int read_time_out) {
|
||||
int retcode = -1;
|
||||
char *hostname;
|
||||
char hostname_buf[MSG_LEN_MAX];
|
||||
|
@ -519,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 {
|
||||
|
@ -529,7 +530,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||
}
|
||||
|
||||
proxychains_write_log(TP " %s:%d ", hostname, htons(pto->port));
|
||||
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
|
||||
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass, read_time_out);
|
||||
switch (retcode) {
|
||||
case SUCCESS:
|
||||
pto->ps = BUSY_STATE;
|
||||
|
@ -549,20 +550,30 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||
}
|
||||
|
||||
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;
|
||||
int rc = -1;
|
||||
unsigned int offset = 0;
|
||||
unsigned int alive_count = 0;
|
||||
unsigned int curr_len = 0;
|
||||
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(pc);
|
||||
|
||||
switch (ct) {
|
||||
case DYNAMIC_TYPE:
|
||||
|
@ -571,12 +582,12 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
do {
|
||||
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
||||
goto error_more;
|
||||
} while(SUCCESS != start_chain(&ns, p1, DT) && offset < proxy_count);
|
||||
} while(SUCCESS != start_chain(&ns, p1, DT, pc->tcp_connect_time_out) && offset < proxy_count);
|
||||
for(;;) {
|
||||
p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
|
||||
if(!p2)
|
||||
break;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(ns, p1, p2, pc->tcp_read_time_out)) {
|
||||
PDEBUG("GOTO AGAIN 1\n");
|
||||
goto again;
|
||||
}
|
||||
|
@ -585,7 +596,53 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(ns, p1, p3, pc->tcp_read_time_out))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
case ROUND_ROBIN_TYPE:
|
||||
alive_count = calc_alive(pd, proxy_count);
|
||||
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);
|
||||
/* Check from current RR offset til end */
|
||||
for (;rc != SUCCESS;) {
|
||||
if (!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
|
||||
/* We've receached the end of the list, go to the start */
|
||||
offset = 0;
|
||||
looped++;
|
||||
continue;
|
||||
} 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 */
|
||||
pc->offset = 0;
|
||||
goto error_more;
|
||||
}
|
||||
PDEBUG("2:rr_offset = %d\n", offset);
|
||||
rc=start_chain(&ns, p1, RRT, pc->tcp_connect_time_out);
|
||||
}
|
||||
/* Create rest of chain using RR */
|
||||
for(curr_len = 1; curr_len < max_chain;) {
|
||||
PDEBUG("3:rr_offset = %d, curr_len = %d, max_chain = %d\n", offset, curr_len, max_chain);
|
||||
p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
|
||||
if(!p2) {
|
||||
/* Try from the beginning to where we started */
|
||||
offset = 0;
|
||||
continue;
|
||||
} else if(SUCCESS != chain_step(ns, p1, p2, pc->tcp_read_time_out)) {
|
||||
PDEBUG("GOTO AGAIN 1\n");
|
||||
goto again;
|
||||
} else
|
||||
p1 = p2;
|
||||
curr_len++;
|
||||
}
|
||||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
pc->offset = offset+1;
|
||||
PDEBUG("pd_offset = %d, curr_len = %d\n", pc->offset, curr_len);
|
||||
if(SUCCESS != chain_step(ns, p1, p3, pc->tcp_read_time_out))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
|
@ -596,14 +653,14 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
PDEBUG("select_proxy failed\n");
|
||||
goto error_strict;
|
||||
}
|
||||
if(SUCCESS != start_chain(&ns, p1, ST)) {
|
||||
if(SUCCESS != start_chain(&ns, p1, ST, pc->tcp_connect_time_out)) {
|
||||
PDEBUG("start_chain failed\n");
|
||||
goto error_strict;
|
||||
}
|
||||
while(offset < proxy_count) {
|
||||
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
||||
break;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(ns, p1, p2, pc->tcp_read_time_out)) {
|
||||
PDEBUG("chain_step failed\n");
|
||||
goto error_strict;
|
||||
}
|
||||
|
@ -612,7 +669,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(ns, p1, p3, pc->tcp_read_time_out))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
|
@ -624,11 +681,11 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
do {
|
||||
if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||
goto error_more;
|
||||
} while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain);
|
||||
} while(SUCCESS != start_chain(&ns, p1, RT, pc->tcp_connect_time_out) && offset < max_chain);
|
||||
while(++curr_len < max_chain) {
|
||||
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||
goto error_more;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(ns, p1, p2, pc->tcp_read_time_out)) {
|
||||
PDEBUG("GOTO AGAIN 2\n");
|
||||
goto again;
|
||||
}
|
||||
|
@ -637,9 +694,12 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(ns, p1, p3, pc->tcp_read_time_out))
|
||||
goto error;
|
||||
|
||||
default:
|
||||
/* This should never happen */
|
||||
proxychains_write_log("\nUnhandled chain type %d. This should never happen!\n", ct);
|
||||
goto error;
|
||||
}
|
||||
|
||||
proxychains_write_log(TP " OK\n");
|
||||
|
|
34
src/core.h
34
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"
|
||||
|
||||
|
@ -47,8 +49,10 @@ typedef enum {
|
|||
typedef enum {
|
||||
DYNAMIC_TYPE,
|
||||
STRICT_TYPE,
|
||||
RANDOM_TYPE}
|
||||
chain_type;
|
||||
RANDOM_TYPE,
|
||||
ROUND_ROBIN_TYPE,
|
||||
MAX_CHAIN_TYPE
|
||||
} chain_type;
|
||||
|
||||
typedef enum {
|
||||
PLAY_STATE,
|
||||
|
@ -76,9 +80,31 @@ 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 *selected;
|
||||
} 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, ...);
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
# include <string.h>
|
||||
# include "core.h"
|
||||
# include "common.h"
|
||||
# include "debug.h"
|
||||
|
||||
|
||||
void DUMP_PROXY_DATA_LIST_PREFIX(proxy_data *plist, unsigned int count, const char* prefix) {
|
||||
char ip_buf[16], buff[48] = {'\0'};
|
||||
strcat(strcat(buff, prefix), "PDATA:");
|
||||
for (; count; plist++, count--) {
|
||||
pc_stringfromipv4(&plist->ip.octet[0], ip_buf);
|
||||
PDEBUG("%s[%s] %s %s:%d", buff, 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_DATA_LIST(proxy_data *plist, unsigned int count) {
|
||||
DUMP_PROXY_DATA_LIST_PREFIX(plist, count, "PDATA:");
|
||||
}
|
||||
|
||||
void DUMP_PROXY_CHAIN_PREFIX(proxy_chain *pchain, const char* prefix) {
|
||||
char buff[32] = {'\0'};
|
||||
strcat(strcat(buff, prefix), "PCHAIN:");
|
||||
prefix = buff;
|
||||
PDEBUG("%s[name: \"%s\"]\n", prefix, pchain->name);
|
||||
PDEBUG("%schain type: %s\n", prefix, chain_type_strmap[pchain->ct]);
|
||||
PDEBUG("%stcp_read_time_out: %d\n", prefix, pchain->tcp_read_time_out);
|
||||
PDEBUG("%stcp_connect_time_out: %d\n", prefix, pchain->tcp_connect_time_out);
|
||||
PDEBUG("%smax_chain: %d\n", prefix, pchain->max_chain);
|
||||
PDEBUG("%soffset: %d\n", prefix, pchain->offset);
|
||||
PDEBUG("%scount: %d\n", prefix, pchain->count);
|
||||
DUMP_PROXY_DATA_LIST_PREFIX(pchain->pd, pchain->count, prefix);
|
||||
}
|
||||
|
||||
void DUMP_PROXY_CHAIN(proxy_chain *pchain) {
|
||||
DUMP_PROXY_CHAIN_PREFIX(pchain, "");
|
||||
}
|
||||
|
||||
void DUMP_PROXY_CHAIN_LIST(proxy_chain_list *pc_list) {
|
||||
const char *prefix = "PCLIST:";
|
||||
int i = 0;
|
||||
PDEBUG("%schain type (default): %s\n", prefix, chain_type_strmap[pc_list->ct]);
|
||||
PDEBUG("%stcp_read_time_out: %d\n", prefix, pc_list->tcp_read_time_out);
|
||||
PDEBUG("%stcp_connect_time_out: %d\n", prefix, pc_list->tcp_connect_time_out);
|
||||
PDEBUG("%sremote_dns_subnet: %d\n", prefix, pc_list->remote_dns_subnet);
|
||||
PDEBUG("%sselected chain: %s\n", prefix, (pc_list->selected)?pc_list->selected->name:NULL);
|
||||
PDEBUG("%snum_localnet_addr: %u\n", prefix, (unsigned int)pc_list->num_localnet_addr);
|
||||
PDEBUG("%schain list count: %d\n", prefix, pc_list->count);
|
||||
for (; i < pc_list->count; i++) {
|
||||
//~ DUMP_PROXY_CHAIN(pc_list->pc[i]);
|
||||
DUMP_PROXY_CHAIN_PREFIX(pc_list->pc[i], prefix);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
12
src/debug.h
12
src/debug.h
|
@ -3,9 +3,19 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
# define PDEBUG(fmt, args...) do { dprintf(2,"DEBUG:"fmt, ## args); } while(0)
|
||||
# define PSTDERR(fmt, args...) do { dprintf(2,fmt, ## args); } while(0)
|
||||
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
|
||||
|
||||
# include "core.h"
|
||||
void DUMP_PROXY_DATA_LIST(proxy_data *plist, unsigned int count);
|
||||
void DUMP_PROXY_CHAIN(proxy_chain *pchain);
|
||||
void DUMP_PROXY_CHAIN_LIST(proxy_chain_list *pc_list);
|
||||
|
||||
#else
|
||||
# define PDEBUG(fmt, args...) do {} while (0)
|
||||
# define DUMP_PROXY_DATA_LIST(args...) do {} while (0)
|
||||
# define DUMP_PROXY_CHAIN(args...) do {} while (0)
|
||||
# define DUMP_PROXY_CHAIN_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,24 +52,20 @@ 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;
|
||||
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_list_load(proxy_chain_list *pc_list);
|
||||
int proxy_chain_load_pdata(proxy_chain *pc, proxy_data *pd_list, int count);
|
||||
proxy_chain* proxy_chain_list_set_selected(proxy_chain_list *pc_list, const char *chain_name);
|
||||
|
||||
static void* load_sym(char* symname, void* proxyfunc) {
|
||||
|
||||
|
@ -103,8 +98,7 @@ static void do_init(void) {
|
|||
core_initialize();
|
||||
at_init();
|
||||
|
||||
/* read the config file */
|
||||
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
||||
proxy_chain_list_load(proxychains_chain_list);
|
||||
|
||||
proxychains_write_log(LOG_PREFIX "DLL init\n");
|
||||
|
||||
|
@ -151,21 +145,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 )
|
||||
|
@ -181,58 +173,107 @@ 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;
|
||||
port_n = 0;
|
||||
|
||||
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[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)
|
||||
count++;
|
||||
} else {
|
||||
if(strstr(buff, "[ProxyList]")) {
|
||||
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, "tcp_read_time_out")) {
|
||||
sscanf(buff, "%s %d", user, &tcp_read_time_out);
|
||||
|
||||
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", user, &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 = 1;
|
||||
pc = strchr(buff, '=');
|
||||
if ((pc=strchr(buff, '=')) == NULL) {
|
||||
fprintf(stderr, "Warning: chain_len must use '='\n");
|
||||
} else
|
||||
len = atoi(++pc);
|
||||
pc_curr->max_chain = len;
|
||||
} 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);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
if(pd_list[count].ip.as_int && port_n && pd_list[count].ip.as_int != (uint32_t) - 1)
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
char *s1, *s2;
|
||||
if((s1=(strstr(buff, "["))+1) && (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->ct = DYNAMIC_TYPE;
|
||||
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(!get_chain_type(buff, &pc_list->ct)) {
|
||||
;
|
||||
} else if(strstr(buff, "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", 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);
|
||||
}
|
||||
|
@ -246,38 +287,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")) {
|
||||
|
@ -286,9 +316,88 @@ 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) {
|
||||
int i = 0;
|
||||
for (; i < MAX_CHAIN_TYPE; i++) {
|
||||
if (strstr(buff, chain_type_strmap[i])) {
|
||||
*ct = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int proxy_chain_list_load(proxy_chain_list *pc_list) {
|
||||
char *env = NULL;
|
||||
|
||||
/* 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;
|
||||
//~ proxychains_chain_list->chain_selection = PROXYCHAINS_DEFAULT_CHAIN;
|
||||
proxychains_chain_list->selected = NULL;
|
||||
|
||||
/* read the config file */
|
||||
get_chain_data(proxychains_chain_list);
|
||||
PDEBUG("Finished loading chain data\n");
|
||||
DUMP_PROXY_CHAIN_LIST(proxychains_chain_list);
|
||||
//~ DUMP_PROXY_CHAIN(proxychains_chain_list->pc[0]);
|
||||
|
||||
env = getenv(PROXYCHAINS_CHAIN_ENV_VAR);
|
||||
if(!env)
|
||||
env = PROXYCHAINS_DEFAULT_CHAIN;
|
||||
if (!proxy_chain_list_set_selected(proxychains_chain_list, env)) {
|
||||
proxychains_write_log(LOG_PREFIX "Error chain list \"%s\" not found\n", env);
|
||||
exit(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;
|
||||
}
|
||||
|
||||
proxy_chain* proxy_chain_list_set_selected(proxy_chain_list *pc_list, const char *chain_name) {
|
||||
int i = 0;
|
||||
for (; i < pc_list->count; i++) {
|
||||
if (!strcmp(chain_name, pc_list->pc[i]->name)) {
|
||||
pc_list->selected = pc_list->pc[i];
|
||||
return pc_list->pc[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******* HOOK FUNCTIONS *******/
|
||||
|
@ -332,12 +441,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);
|
||||
}
|
||||
|
@ -353,7 +462,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->selected);
|
||||
|
||||
fcntl(sock, F_SETFL, flags);
|
||||
if(ret != SUCCESS)
|
||||
|
|
|
@ -22,13 +22,27 @@ strict_chain
|
|||
# all proxies must be online to play in chain
|
||||
# otherwise EINTR is returned to the app
|
||||
#
|
||||
#round_robin_chain
|
||||
#
|
||||
# Round Robin - Each connection will be done via chained proxies
|
||||
# of chain_len length
|
||||
# all proxies chained in the order as they appear in the list
|
||||
# at least one proxy must be online to play in chain
|
||||
# (dead proxies are skipped).
|
||||
# the start of the current proxy chain is the proxy after the last
|
||||
# proxy in the previously invoked proxy chain.
|
||||
# if the end of the proxy chain is reached while looking for proxies
|
||||
# start at the beginning again.
|
||||
# otherwise EINTR is returned to the app
|
||||
# These semantics are not guaranteed in a multithreaded environment.
|
||||
#
|
||||
#random_chain
|
||||
#
|
||||
# Random - Each connection will be done via random proxy
|
||||
# (or proxy chain, see chain_len) from the list.
|
||||
# this option is good to test your IDS :)
|
||||
|
||||
# Make sense only if random_chain
|
||||
# Make sense only if random_chain or round_robin_chain
|
||||
#chain_len = 2
|
||||
|
||||
# Quiet mode (no output from library)
|
||||
|
@ -93,7 +107,59 @@ tcp_connect_time_out 8000
|
|||
#
|
||||
# proxy types: http, socks4, socks5
|
||||
# ( auth types supported: "basic"-http "user/pass"-socks )
|
||||
|
||||
# Select the list you want to use by setting the PROXYCHAINS_CHAIN envvar to
|
||||
# the name of the list. If the envvar is not set, the default chain is
|
||||
# "ProxyList".
|
||||
#
|
||||
# Example 1: Your corporate network admin is the BOFH. You're not officially
|
||||
# allowed access to the internet. But you've found a sequence of proxies
|
||||
# setup to connect the various internal networks, with one of them having
|
||||
# internet access.
|
||||
# [LetMeOut]
|
||||
# strict_chain
|
||||
# socks5 192.168.89.2 1080
|
||||
# http 172.16.30.10 8080
|
||||
# http 10.10.5.4 80
|
||||
#
|
||||
# Example 2: Suppose you have access to several fast caching proxies and you
|
||||
# want to load balance connections across them. Since they're fast, they
|
||||
# shouldn't need large timeouts. If one of them happens to go down, it will
|
||||
# be removed from the active list and each connect() will use the next proxy,
|
||||
# going back to the beginning once the end is reached.
|
||||
# [LoadBalanceList]
|
||||
# round_robin_chain
|
||||
# max_chain = 1
|
||||
# tcp_read_time_out 2000
|
||||
# tcp_connect_time_out 1000
|
||||
# http 192.168.89.2 8080
|
||||
# http 192.168.89.3 8080
|
||||
# http 192.168.89.4 8080
|
||||
# http 192.168.89.5 8080
|
||||
#
|
||||
# Example 3: We're doing some scraping again the wishes of our target, so we
|
||||
# come at him from all sides. But since we're using random free proxies found
|
||||
# on the web, many of the proxies are slow an unreliable. Give a larger
|
||||
# timeout to account for this. The broken/dead ones will be removed as they
|
||||
# are encountered and we'll cycle through each live proxy sequentially per
|
||||
# connect().
|
||||
# [AvoidDetection]
|
||||
# round_robin_chain
|
||||
# max_chain = 1
|
||||
# tcp_read_time_out 20000
|
||||
# tcp_connect_time_out 10000
|
||||
# http 91.106.83.204 80
|
||||
# http 178.237.184.222 3128
|
||||
# http 109.207.61.164 8090
|
||||
# http 190.75.178.219 8080
|
||||
# http 168.63.43.185 3128
|
||||
# http 193.95.90.194 3128
|
||||
# http 54.214.237.232 80
|
||||
# http 81.169.166.83 80
|
||||
# http 201.85.50.249 80
|
||||
# http 173.192.81.137 8080
|
||||
# http 79.127.101.96 8080
|
||||
|
||||
[ProxyList]
|
||||
# add proxy here ...
|
||||
# meanwile
|
||||
|
|
Loading…
Reference in New Issue