From 9708d585207b9441a3254969a1978e69cc928f8b Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 14 Feb 2021 01:23:11 +0000 Subject: [PATCH] add support for a fixed number of proxies that are *always* used e.g. for having tor fixed as first proxy, then using the rest for random selection. --- src/core.c | 70 +++++++++++++++++++++++++++++++------------- src/core.h | 6 ++-- src/libproxychains.c | 21 ++++++++++++- src/proxychains.conf | 6 ++++ 4 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/core.c b/src/core.c index 18591ac..594ac3f 100644 --- a/src/core.c +++ b/src/core.c @@ -475,7 +475,8 @@ static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int p case RANDOMLY: do { k++; - i = rand() % proxy_count; + i = rand() % (proxy_count-proxychains_fixed_chain); + i += proxychains_fixed_chain; } while(pd[i].ps != PLAY_STATE && k < proxy_count * 100); break; case FIFOLY: @@ -563,9 +564,38 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) { return retcode; } +static int strict_connect( + unsigned *alive_count, + unsigned *offset, + int *ns, + proxy_data **p1, proxy_data **p2, + unsigned proxy_count, proxy_data * pd) +{ + *alive_count = calc_alive(pd, proxy_count); + *offset = 0; + if(!(*p1 = select_proxy(FIFOLY, pd, proxy_count, offset))) { + PDEBUG("select_proxy failed\n"); + return 0; + } + if(SUCCESS != start_chain(ns, *p1, ST)) { + PDEBUG("start_chain failed\n"); + return 0; + } + while(*offset < proxy_count) { + if(!(*p2 = select_proxy(FIFOLY, pd, proxy_count, offset))) + break; + if(SUCCESS != chain_step(*ns, *p1, *p2)) { + PDEBUG("chain_step failed\n"); + return 0; + } + *p1 = *p2; + } + return 1; +} + 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 int proxy_count, chain_type ct) { proxy_data p4; proxy_data *p1, *p2, *p3; int ns = -1; @@ -575,6 +605,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, unsigned int curr_len = 0; unsigned int looped = 0; // went back to start of list in RR mode unsigned int rr_loop_max = 14; + unsigned int max_chain = proxychains_max_chain; p3 = &p4; @@ -583,9 +614,14 @@ int connect_proxy_chain(int sock, ip_type target_ip, again: rc = -1; DUMP_PROXY_CHAIN(pd, proxy_count); + if(proxychains_fixed_chain) { + if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxychains_fixed_chain, pd)) + goto error_strict; + } switch (ct) { case DYNAMIC_TYPE: + if(proxychains_fixed_chain) goto dyn_fixed_resume; alive_count = calc_alive(pd, proxy_count); offset = 0; do { @@ -601,6 +637,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, goto again; } p1 = p2; + dyn_fixed_resume:; } //proxychains_write_log(TP); p3->ip = target_ip; @@ -610,6 +647,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, break; case ROUND_ROBIN_TYPE: + // FIXME: add support for fixed_len alive_count = calc_alive(pd, proxy_count); offset = proxychains_proxy_offset; if(alive_count < max_chain) @@ -660,25 +698,8 @@ int connect_proxy_chain(int sock, ip_type target_ip, break; case STRICT_TYPE: - alive_count = calc_alive(pd, proxy_count); - offset = 0; - if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) { - PDEBUG("select_proxy failed\n"); + if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxy_count, pd)) goto error_strict; - } - if(SUCCESS != start_chain(&ns, p1, ST)) { - 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)) { - PDEBUG("chain_step failed\n"); - goto error_strict; - } - p1 = p2; - } //proxychains_write_log(TP); p3->ip = target_ip; p3->port = target_port; @@ -687,6 +708,12 @@ int connect_proxy_chain(int sock, ip_type target_ip, break; case RANDOM_TYPE: + if(proxychains_fixed_chain) { + if(alive_count < max_chain) + goto error_more; + curr_len = proxychains_fixed_chain - 1; + goto random_fixed_resume; + } alive_count = calc_alive(pd, proxy_count); if(alive_count < max_chain) goto error_more; @@ -695,6 +722,9 @@ int connect_proxy_chain(int sock, ip_type target_ip, if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset))) goto error_more; } while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain); + + random_fixed_resume:; + while(++curr_len < max_chain) { if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset))) goto error_more; diff --git a/src/core.h b/src/core.h index 5f446e9..36cf45b 100644 --- a/src/core.h +++ b/src/core.h @@ -84,8 +84,7 @@ typedef struct { } proxy_data; 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_data * pd, unsigned int proxy_count, chain_type ct ); void proxychains_write_log(char *str, ...); @@ -130,6 +129,9 @@ void proxy_freeaddrinfo(struct addrinfo *res); void core_initialize(void); void core_unload(void); +extern unsigned int proxychains_max_chain; +extern unsigned int proxychains_fixed_chain; + #include "debug.h" #endif diff --git a/src/libproxychains.c b/src/libproxychains.c index a3509c9..b9c2a88 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -71,6 +71,7 @@ unsigned int proxychains_proxy_count = 0; unsigned int proxychains_proxy_offset = 0; int proxychains_got_chain_data = 0; unsigned int proxychains_max_chain = 1; +unsigned int proxychains_fixed_chain = 0; int proxychains_quiet_mode = 0; enum dns_lookup_flavor proxychains_resolver = DNSLF_LIBC; localaddr_arg localnet_addr[MAX_LOCALNET]; @@ -438,6 +439,16 @@ inv_host: } len = atoi(++pc); proxychains_max_chain = (len ? len : 1); + } else if(STR_STARTSWITH(buff, "fixed_len")) { + char *pc; + int len; + pc = strchr(buff, '='); + if(!pc) { + fprintf(stderr, "error: missing equals sign '=' in fixed_len directive.\n"); + exit(1); + } + len = atoi(++pc); + proxychains_fixed_chain = (len ? len : 1); } else if(!strcmp(buff, "quiet_mode")) { proxychains_quiet_mode = 1; } else if(!strcmp(buff, "proxy_dns_old")) { @@ -520,6 +531,14 @@ inv_host: fprintf(stderr, "error: no valid proxy found in config\n"); exit(1); } + if(proxychains_max_chain <= proxychains_fixed_chain) { + fprintf(stderr, "error: fixed_len needs to be smaller than chain_len\n"); + exit(1); + } + if(proxychains_fixed_chain > count) { + fprintf(stderr, "error: fixed_len > proxycount\n"); + exit(1); + } *proxy_count = count; proxychains_got_chain_data = 1; PDEBUG("proxy_dns: %s\n", rdns_resolver_string(proxychains_resolver)); @@ -630,7 +649,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) { ret = connect_proxy_chain(sock, dest_ip, htons(port), - proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain); + proxychains_pd, proxychains_proxy_count, proxychains_ct); fcntl(sock, F_SETFL, flags); if(ret != SUCCESS) diff --git a/src/proxychains.conf b/src/proxychains.conf index dc66400..6a4f4d7 100644 --- a/src/proxychains.conf +++ b/src/proxychains.conf @@ -45,6 +45,12 @@ strict_chain # Make sense only if random_chain or round_robin_chain #chain_len = 2 +# use this if you want to use e.g. random_chain but always have +# e.g. tor as first proxy. in that case only chain_len - fixed_len proxies +# will be used for random chain. +# currently only implemented for dynamic_chain and random_chain. +#fixed_len = 1 + # Quiet mode (no output from library) #quiet_mode