diff --git a/Makefile b/Makefile index 33546b0..5845f94 100644 --- a/Makefile +++ b/Makefile @@ -65,5 +65,4 @@ $(LDSO_PATHNAME): $(LOBJS) $(ALL_TOOLS): $(OBJS) $(CC) src/main.o -o $(PXCHAINS) - .PHONY: all clean install diff --git a/configure b/configure index 35d2148..cc12fee 100755 --- a/configure +++ b/configure @@ -11,11 +11,12 @@ spliteq() { parsearg() { case "$1" in - --prefix=*) prefix=$(spliteq "$1");; + --prefix=*) prefix=`spliteq $1`;; --exec_prefix=*) exec_prefix=`spliteq $1`;; --bindir=*) bindir=`spliteq $1`;; --libdir=*) libdir=`spliteq $1`;; --includedir=*) includedir=`spliteq $1`;; + --sysconfdir=*) sysconfdir=`spliteq $1`;; esac } @@ -30,23 +31,27 @@ while true ; do esac done -if [ ! $exec_prefix ] ; then +if [ -z "$exec_prefix" ] ; then exec_prefix=$prefix fi -if [ ! $libdir ] ; then +if [ -z "$libdir" ] ; then libdir=$prefix/lib fi -if [ ! $includedir ] ; then +if [ -z "$includedir" ] ; then includedir=$prefix/include fi -if [ ! $bindir ] ; then +if [ -z "$sysconfdir" ] ; then + sysconfdir=$prefix/etc +fi + +if [ -z "$bindir" ] ; then bindir=$exec_prefix/bin fi -if [ ! $CC ] ; then +if [ -z "$CC" ] ; then CC=cc fi @@ -58,6 +63,7 @@ echo exec_prefix=$exec_prefix>>config.mak echo bindir=$bindir>>config.mak echo libdir=$libdir>>config.mak echo includedir=$includedir>>config.mak +echo sysconfdir=$sysconfdir>>config.mak if ismac ; then echo LDSO_SUFFIX=dylib>>config.mak echo MAC_CFLAGS+=-DIS_MAC=1 -arch x86_64 -arch i386 >>config.mak diff --git a/src/core.h b/src/core.h index 3ca8cdd..a51adb0 100644 --- a/src/core.h +++ b/src/core.h @@ -18,7 +18,7 @@ #ifndef __CORE_HEADER #define __CORE_HEADER #define BUFF_SIZE 8*1024 // used to read responses from proxies. -#define MAX_LOCALNET 1024 +#define MAX_LOCALNET 64 typedef union { unsigned char octet[4]; @@ -60,7 +60,6 @@ typedef enum { BLOCKED // target's port blocked on last proxy in the chain } ERR_CODE; - typedef enum { HTTP_TYPE, SOCKS4_TYPE, @@ -99,26 +98,11 @@ typedef struct { char pass[256]; } proxy_data; -typedef struct { - proxy_data *pd; - chain_type ct; - unsigned int proxy_count; - int sock; - struct sockaddr addr; - int flags; -} thread_arg; - -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 ); int proxychains_write_log(char *str,...); -struct hostent* proxy_gethostbyname(const char *name); typedef int (*connect_t)(int, const struct sockaddr *, socklen_t); connect_t true_connect; @@ -137,22 +121,23 @@ freeaddrinfo_t true_freeaddrinfo; typedef int (*getnameinfo_t) (const struct sockaddr *, socklen_t, char *, socklen_t, char *, - socklen_t, unsigned int); + socklen_t, int); getnameinfo_t true_getnameinfo; typedef struct hostent *(*gethostbyaddr_t) (const void *, socklen_t, int); gethostbyaddr_t true_gethostbyaddr; +struct hostent* proxy_gethostbyname(const char *name); + int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); -struct hostent* proxy_gethostbyname(const char *name); #ifdef DEBUG # define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args) #else -# define PDEBUG(fmt, args...) +# define PDEBUG(fmt, args...) do {} while (0) #endif #endif diff --git a/src/libproxychains.c b/src/libproxychains.c index 6727af5..22a419b 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -41,13 +41,14 @@ #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 30*1024 +#define MAX_CHAIN 512 int tcp_read_time_out; int tcp_connect_time_out; int proxychains_got_chain_data = 0; int proxychains_quiet_mode = 0; int proxychains_resolver = 0; + static int init_l = 0; unsigned int proxychains_proxy_count = 0; @@ -60,81 +61,87 @@ proxy_data proxychains_pd[MAX_CHAIN]; size_t num_localnet_addr = 0; -static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct); -static void init_lib(void); +#ifdef THREAD_SAFE +pthread_once_t init_once = PTHREAD_ONCE_INIT; +#endif +static int init_l = 0; -static void init_lib(void) { +static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct); + +static void load_sym(void** funcptr, char* symname, void* proxyfunc) { + + *funcptr = dlsym(RTLD_NEXT, symname); + + if(!(*funcptr)) { + fprintf(stderr, "Cannot load symbol '%s' %s\n", symname, dlerror()); + exit(1); + } else { + PDEBUG("loaded symbol '%s'" " real addr %p wrapped addr %p\n", symname, (*funcptr), proxyfunc); + } + if((*funcptr) == proxyfunc) { + PDEBUG("circular reference detected, aborting!\n"); + abort(); + } +} + +#define INIT() init_lib_wrapper(__FUNCTION__) + +static void do_init(void) { + static const struct override_info { + void* funcptr; + char* symname; + void* proxyfunc; + } override_symbols[] = { + #define SYM_ENTRY(X) { .funcptr = &true_ ## X, .symname = # X, .proxyfunc = X,} + SYM_ENTRY(connect), + SYM_ENTRY(gethostbyname), + SYM_ENTRY(getaddrinfo), + SYM_ENTRY(freeaddrinfo), + SYM_ENTRY(gethostbyaddr), + SYM_ENTRY(getnameinfo), + #undef SYM_ENTRY + }; + unsigned i; MUTEX_INIT(&internal_ips_lock, NULL); /* read the config file */ get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct); proxychains_write_log(LOG_PREFIX "DLL init\n"); - true_connect = (connect_t) dlsym(RTLD_NEXT, "connect"); - - if(!true_connect) { - fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'connect'" " real addr %p wrapped addr %p\n", true_connect, connect); - } - if(connect == true_connect) { - PDEBUG("circular reference detected, aborting!\n"); - abort(); - } - - true_gethostbyname = (gethostbyname_t) - dlsym(RTLD_NEXT, "gethostbyname"); - - if(!true_gethostbyname) { - fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'gethostbyname'" - " real addr %p wrapped addr %p\n", true_gethostbyname, gethostbyname); - } - true_getaddrinfo = (getaddrinfo_t) - dlsym(RTLD_NEXT, "getaddrinfo"); - - if(!true_getaddrinfo) { - fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'getaddrinfo'" " real addr %p wrapped addr %p\n", true_getaddrinfo, getaddrinfo); - } - true_freeaddrinfo = (freeaddrinfo_t) - dlsym(RTLD_NEXT, "freeaddrinfo"); - - if(!true_freeaddrinfo) { - fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'freeaddrinfo'" - " real addr %p wrapped addr %p\n", true_freeaddrinfo, freeaddrinfo); - } - true_gethostbyaddr = (gethostbyaddr_t) - dlsym(RTLD_NEXT, "gethostbyaddr"); - - if(!true_gethostbyaddr) { - fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'gethostbyaddr'" - " real addr %p wrapped addr %p\n", true_gethostbyaddr, gethostbyaddr); - } - true_getnameinfo = (getnameinfo_t) - dlsym(RTLD_NEXT, "getnameinfo"); - - if(!true_getnameinfo) { - fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", dlerror()); - exit(1); - } else { - PDEBUG("loaded symbol 'getnameinfo'" " real addr %p wrapped addr %p\n", true_getnameinfo, getnameinfo); + for (i = 0; i < (sizeof(override_symbols) / sizeof(override_symbols[0])); i++) { + load_sym(override_symbols[i].funcptr, override_symbols[i].symname, override_symbols[i].proxyfunc); } init_l = 1; } -static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct) { +static void init_lib_wrapper(const char* caller) { +#ifndef DEBUG + (void) caller; +#endif +#ifndef THREAD_SAFE + if(init_l) return; + PDEBUG("%s called from %s\n", __FUNCTION__, caller); + do_init(); +#else + if(!init_l) PDEBUG("%s called from %s\n", __FUNCTION__, caller); + pthread_once(&init_once, do_init); +#endif +} + +/* if we use gcc >= 3, we can instruct the dynamic loader + * to call init_lib at link time. otherwise it gets loaded + * lazily, which has the disadvantage that there's a potential + * race condition if 2 threads call it before init_l is set + * and PTHREAD support was disabled */ +#if __GNUC__ > 2 +__attribute__((constructor)) +static void gcc_init(void) { + INIT(); +} +#endif + +/* get configuration from config file */ +static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct) { int count = 0, port_n = 0, list = 0; char buff[1024], type[1024], host[1024], user[1024]; char *env; @@ -172,7 +179,11 @@ static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, ch while(fgets(buff, sizeof(buff), file)) { if(buff[0] != '\n' && buff[strspn(buff, " ")] != '#') { + /* proxylist has to come last */ if(list) { + if(count >= MAX_CHAIN) + break; + memset(&pd[count], 0, sizeof(proxy_data)); pd[count].ps = PLAY_STATE; @@ -193,8 +204,7 @@ static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, ch continue; if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) - 1) - if(++count == MAX_CHAIN) - break; + count++; } else { if(strstr(buff, "[ProxyList]")) { list = 1; @@ -275,6 +285,11 @@ static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, ch proxychains_got_chain_data = 1; } +<<<<<<< HEAD +======= +/******* HOOK FUNCTIONS *******/ + +>>>>>>> rofl0r/master int connect(int sock, const struct sockaddr *addr, unsigned int len) { int socktype = 0, flags = 0, ret = 0; socklen_t optlen = 0; @@ -287,8 +302,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) { size_t i; int remote_dns_connect = 0; - if(!init_l) - init_lib(); + INIT(); optlen = sizeof(socktype); getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen); if(!(SOCKFAMILY(*addr) == AF_INET && socktype == SOCK_STREAM)) @@ -335,8 +349,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) { } struct hostent *gethostbyname(const char *name) { - if(!init_l) - init_lib(); + INIT(); PDEBUG("gethostbyname: %s\n", name); @@ -351,8 +364,7 @@ struct hostent *gethostbyname(const char *name) { int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { int ret = 0; - if(!init_l) - init_lib(); + INIT(); PDEBUG("getaddrinfo: %s %s\n", node, service); @@ -365,8 +377,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi } void freeaddrinfo(struct addrinfo *res) { - if(!init_l) - init_lib(); + INIT(); PDEBUG("freeaddrinfo %p \n", res); @@ -394,9 +405,8 @@ int getnameinfo(const struct sockaddr *sa, char ip_buf[16]; int ret = 0; - if(!init_l) - init_lib(); - + INIT(); + PDEBUG("getnameinfo: %s %s\n", host, serv); if(!proxychains_resolver) { @@ -418,8 +428,7 @@ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) { static char *list[2]; static struct hostent he; - if(!init_l) - init_lib(); + INIT(); PDEBUG("TODO: proper gethostbyaddr hook\n");