diff --git a/src/allocator_thread.c b/src/allocator_thread.c index 5ed6b13..91bf5a4 100644 --- a/src/allocator_thread.c +++ b/src/allocator_thread.c @@ -10,6 +10,7 @@ #include #include #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; diff --git a/src/core.c b/src/core.c index fb30671..0939a4c 100644 --- a/src/core.c +++ b/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 : ""); - 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; diff --git a/src/core.h b/src/core.h index c4dcf8f..fc1f7fe 100644 --- a/src/core.h +++ b/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, ...); diff --git a/src/debug.c b/src/debug.c index d867569..35f4926 100644 --- a/src/debug.c +++ b/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 diff --git a/src/debug.h b/src/debug.h index 8bcf2e9..5af5745 100644 --- a/src/debug.h +++ b/src/debug.h @@ -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) diff --git a/src/libproxychains.c b/src/libproxychains.c index 36f3623..0b85c16 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -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)