diff --git a/Makefile b/Makefile index 3320904..11d0df8 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ prefix = /usr/local/ includedir = $(prefix)/include libdir = $(prefix)/lib sysconfdir = $(prefix)/etc -zshcompletiondir = $(prefix)/share/zsh/site_functions +zshcompletiondir = $(prefix)/share/zsh/site-functions OBJS = src/common.o src/main.o diff --git a/README b/README index 94c4891..da413eb 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -ProxyChains-NG ver 4.16 README +ProxyChains-NG ver 4.17 README ============================= ProxyChains is a UNIX program, that hooks network-related libc functions @@ -52,6 +52,15 @@ ProxyChains-NG ver 4.16 README Changelog: ---------- +Version 4.17 +- add hook for close_range function, fixing newer versions of openssh +- fat-binary-m1 option for mac +- fix DNS error handling in proxy_dns_old +- simplify init code +- fix openbsd preloading +- fix double-close in multithreaded apps +- various improvements to configure script + Version 4.16 - fix regression in configure script linker flag detection - remove 10 year old workaround for wrong glibc getnameinfo signature diff --git a/VERSION b/VERSION index e95590c..13bf3fd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.16 +4.17 diff --git a/configure b/configure index 7ceb122..273f657 100755 --- a/configure +++ b/configure @@ -87,6 +87,7 @@ usage() { echo " to preload from current dir (possibly insecure, but handy)" echo "--fat-binary : build for both i386 and x86_64 architectures on 64-bit Macs" echo "--fat-binary-m1 : build for both arm64e and x86_64 architectures on M1 Macs" + echo "--fat-binary-m2 : build for arm64, arm64e and x86_64 architectures on M2+ Macs" echo "--hookmethod=dlsym|dyld hook method for osx. default: auto" echo " if OSX >= 12 is detected, dyld method will be used if auto." echo "--help : show this text" @@ -102,6 +103,7 @@ spliteq() { fat_binary= fat_binary_m1= +fat_binary_m2= ignore_cve=no hookmethod=auto @@ -118,6 +120,7 @@ parsearg() { --hookmethod=*) hookmethod=`spliteq $1`;; --fat-binary) fat_binary=1;; --fat-binary-m1) fat_binary_m1=1;; + --fat-binary-m2) fat_binary_m2=1;; --help) usage;; esac } @@ -289,6 +292,12 @@ if ismac ; then echo "FAT_LDFLAGS=-arch arm64 -arch arm64e -arch x86_64">>config.mak echo "FAT_BIN_LDFLAGS=-arch arm64 -arch x86_64">>config.mak fi + if [ "$fat_binary_m2" = 1 ] ; then + echo "Configuring a fat binary for arm64[e] and x86_64" + echo "MAC_CFLAGS+=-arch arm64 -arch arm64e -arch x86_64">>config.mak + echo "FAT_LDFLAGS=-arch arm64 -arch arm64e -arch x86_64">>config.mak + echo "FAT_BIN_LDFLAGS=-arch arm64 -arch arm64e -arch x86_64">>config.mak + fi elif isbsd ; then echo LIBDL=>>config.mak echo "CFLAGS+=-DIS_BSD">>config.mak @@ -302,3 +311,6 @@ elif ishaiku ; then fi echo "Done, now run $make_cmd && $make_cmd install" +if [ "$fat_binary_m2" = 1 ] ; then +echo "Don't forget to run csrutil disable and sudo nvram boot-args=-arm64e_preview_abi" +fi diff --git a/src/core.c b/src/core.c index 5caea7e..f8777df 100644 --- a/src/core.c +++ b/src/core.c @@ -985,8 +985,10 @@ static int start_chain(int *fd, proxy_data * pd, char *begin_mark) { error1: proxychains_write_log(TP " timeout\n"); error: - if(*fd != -1) - true_close(*fd); + if(*fd != -1) { + close(*fd); + *fd = -1; + } return SOCKET_ERROR; } @@ -1044,9 +1046,9 @@ 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 retcode = -1; - char *hostname; + char *hostname, *errmsg = 0; char hostname_buf[MSG_LEN_MAX]; char ip_buf[INET6_ADDRSTRLEN]; int v6 = pto->ip.is_v6; @@ -1060,31 +1062,34 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) { usenumericip: if(!inet_ntop(v6?AF_INET6:AF_INET,pto->ip.addr.v6,ip_buf,sizeof ip_buf)) { pto->ps = DOWN_STATE; - proxychains_write_log("<--ip conversion error!\n"); - true_close(ns); - return SOCKET_ERROR; + errmsg = "<--ip conversion error!\n"; + retcode = SOCKET_ERROR; + goto err; } hostname = ip_buf; } 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); switch (retcode) { case SUCCESS: pto->ps = BUSY_STATE; break; case BLOCKED: pto->ps = BLOCKED_STATE; - proxychains_write_log("<--denied\n"); - true_close(ns); - break; + errmsg = "<--denied\n"; + goto err; case SOCKET_ERROR: pto->ps = DOWN_STATE; - proxychains_write_log("<--socket error or timeout!\n"); - true_close(ns); - break; + errmsg = "<--socket error or timeout!\n"; + goto err; } return retcode; +err: + if(errmsg) proxychains_write_log(errmsg); + if(*ns != -1) close(*ns); + *ns = -1; + return retcode; } int connect_proxy_chain(int sock, ip_type target_ip, @@ -1120,7 +1125,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, 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)) { PDEBUG("GOTO AGAIN 1\n"); goto again; } @@ -1129,7 +1134,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)) goto error; break; @@ -1167,7 +1172,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, /* Try from the beginning to where we started */ offset = 0; continue; - } else if(SUCCESS != chain_step(ns, p1, p2)) { + } else if(SUCCESS != chain_step(&ns, p1, p2)) { PDEBUG("GOTO AGAIN 1\n"); goto again; } else @@ -1179,7 +1184,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, p3->port = target_port; proxychains_proxy_offset = offset+1; PDEBUG("pd_offset = %d, curr_len = %d\n", proxychains_proxy_offset, curr_len); - if(SUCCESS != chain_step(ns, p1, p3)) + if(SUCCESS != chain_step(&ns, p1, p3)) goto error; break; @@ -1197,7 +1202,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, 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)) { PDEBUG("chain_step failed\n"); goto error_strict; } @@ -1206,7 +1211,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)) goto error; break; @@ -1222,7 +1227,7 @@ int connect_proxy_chain(int sock, ip_type target_ip, 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)) { PDEBUG("GOTO AGAIN 2\n"); goto again; } @@ -1231,7 +1236,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)) goto error; } diff --git a/src/core.h b/src/core.h index 59e4ab1..e05dac6 100644 --- a/src/core.h +++ b/src/core.h @@ -155,7 +155,7 @@ typedef int (*close_range_t)(unsigned, unsigned, int); typedef void (*uv_close_t)(uv_handle_t* , uv_close_cb); typedef int (*connect_t)(int, const struct sockaddr *, socklen_t); typedef struct hostent* (*gethostbyname_t)(const char *); -typedef int (*freeaddrinfo_t)(struct addrinfo *); +typedef void (*freeaddrinfo_t)(struct addrinfo *); typedef struct hostent *(*gethostbyaddr_t) (const void *, socklen_t, int); typedef int (*getaddrinfo_t)(const char *, const char *, const struct addrinfo *, diff --git a/src/main.c b/src/main.c index af78ef2..381c71c 100644 --- a/src/main.c +++ b/src/main.c @@ -135,16 +135,20 @@ int main(int argc, char *argv[]) { if(!quiet) fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name); +#if defined(IS_MAC) || defined(IS_OPENBSD) +#define LD_PRELOAD_SEP ":" +#else +/* Dynlinkers for Linux and most BSDs seem to support space + as LD_PRELOAD separator, with colon added only recently. + We use the old syntax for maximum compat */ +#define LD_PRELOAD_SEP " " +#endif + #ifdef IS_MAC putenv("DYLD_FORCE_FLAT_NAMESPACE=1"); #define LD_PRELOAD_ENV "DYLD_INSERT_LIBRARIES" -#define LD_PRELOAD_SEP ":" #else #define LD_PRELOAD_ENV "LD_PRELOAD" -/* all historic implementations of BSD and linux dynlinkers seem to support - space as LD_PRELOAD separator, with colon added only recently. - we use the old syntax for maximum compat */ -#define LD_PRELOAD_SEP " " #endif char *old_val = getenv(LD_PRELOAD_ENV); snprintf(buf, sizeof(buf), LD_PRELOAD_ENV "=%s/%s%s%s",