diff --git a/.gitignore b/.gitignore index 1133bf1..a8110b5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ # Autoconf stuff libtool config.* -Makefile stamp-h diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..3e1a27a --- /dev/null +++ b/Makefile @@ -0,0 +1,76 @@ +# +# Makefile for proxychains (requires GNU make), stolen from musl +# +# Use config.mak to override any of the following variables. +# Do not make changes here. +# + +exec_prefix = /usr/local +bindir = $(exec_prefix)/bin + +prefix = /usr/local/ +includedir = $(prefix)/include +libdir = $(prefix)/lib +syslibdir = /lib + +SRCS = $(sort $(wildcard src/*.c)) +OBJS = $(SRCS:.c=.o) +LOBJS = $(OBJS:.o=.lo) + +CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe +LDFLAGS = -shared -fPIC -ldl +INC = +PIC = -fPIC -O0 +AR = $(CROSS_COMPILE)ar +RANLIB = $(CROSS_COMPILE)ranlib + +SHARED_LIBS = lib/libproxychains.so +ALL_LIBS = $(SHARED_LIBS) +ALL_TOOLS = proxychains + +LDSO_PATHNAME = libproxychains.so.3 + +-include config.mak + +CFLAGS_MAIN=-DLIB_DIR=\"$(libdir)\" + + +all: $(ALL_LIBS) $(ALL_TOOLS) + +#install: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(DESTDIR)$(LDSO_PATHNAME) +install: + install -D -m 644 proxychains $(bindir) + install -D -m 644 src/proxyresolv $(bindir) + install -D -m 644 lib/libproxychains.so $(libdir) + ln -sf $(libdir)/libproxychains.so $(libdir)/libproxychains.so.3 + +clean: + rm -f $(OBJS) + rm -f $(LOBJS) + rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so + +%.o: %.c + $(CC) $(CFLAGS) $(CFLAGS_MAIN) $(INC) -c -o $@ $< + +%.lo: %.c + $(CC) $(CFLAGS) $(CFLAGS_MAIN) $(INC) $(PIC) -c -o $@ $< + +lib/libproxychains.so: $(LOBJS) + $(CC) $(LDFLAGS) -Wl,-soname=libproxychains.so -o $@ $(LOBJS) -lgcc + +lib/%.o: + cp $< $@ + +$(ALL_TOOLS): $(OBJS) + $(CC) src/main.o -o proxychains + +$(DESTDIR)$(libdir)/%.so: lib/%.so + install -D -m 755 $< $@ + +$(DESTDIR)$(libdir)/%: lib/% + install -D -m 644 $< $@ + +$(DESTDIR)$(LDSO_PATHNAME): lib/libproxychains.so + ln -sf $(libdir)/libproxychains.so $@ || true + +.PHONY: all clean install diff --git a/src/core.c b/src/core.c index 5e22a5b..e5bc3aa 100644 --- a/src/core.c +++ b/src/core.c @@ -126,57 +126,36 @@ int proxychains_write_log(char *str,...) static int write_n_bytes(int fd,char *buff,size_t size) { - int i=0,wrote=0; - for(;;) - { - i=write(fd,&buff[wrote],size-wrote); - if(i<=0) - return i; - wrote+=i; - if(wrote==size) - return wrote; - } -} - -static int read_line(int fd, char *buff, size_t size) -{ - int i,ready; - struct pollfd pfd[1]; - - pfd[0].fd=fd; - pfd[0].events=POLLIN; - for(i=0;i=proxy_count) + unsigned int i=0, k=0; + if(*offset >= proxy_count) return NULL; switch(how) { case RANDOMLY: srand(time(NULL)); do { k++; - i = 0 + (int) (proxy_count*1.0*rand()/ - (RAND_MAX+1.0)); - } while (pd[i].ps!=PLAY_STATE && k=proxy_count) - i=0; - return pd[i].ps==PLAY_STATE?&pd[i]:NULL; + if (i >= proxy_count) + i = 0; + return (pd[i].ps == PLAY_STATE)? &pd[i] : NULL; } -static void release_all(proxy_data *pd, int proxy_count) +static void release_all(proxy_data *pd, unsigned int proxy_count) { - int i; - for(i=0;i-%s:%d-", inet_ntoa(*(struct in_addr*)&pto->ip), @@ -517,14 +511,14 @@ static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto) int connect_proxy_chain( int sock, unsigned int target_ip, unsigned short target_port, proxy_data *pd, - unsigned int proxy_count, chain_type ct, int max_chain ) + unsigned int proxy_count, chain_type ct, unsigned int max_chain ) { proxy_data p4; proxy_data *p1,*p2,*p3; int ns=-1; - int offset=0; - int alive_count=0; - int curr_len=0; + unsigned int offset=0; + unsigned int alive_count=0; + unsigned int curr_len=0; #define TP "<>" #define DT "|D-chain|" @@ -532,8 +526,12 @@ int connect_proxy_chain( int sock, unsigned int target_ip, #define RT "|R-chain|" p3=&p4; - +#ifdef DEBUG + PDEBUG("connect_proxy_chain\n"); +#endif + again: + switch(ct) { case DYNAMIC_TYPE: alive_count=calc_alive(pd,proxy_count); @@ -541,13 +539,17 @@ again: do { if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset))) goto error_more; - } while(SUCCESS!=start_chain(&ns,p1,DT) && offset<>-OK\n"); dup2(ns,sock); close(ns); @@ -616,6 +633,9 @@ error: error_more: proxychains_write_log("\n!!!need more proxies!!!\n"); error_strict: + #ifdef DEBUG + PDEBUG("error\n"); + #endif release_all(pd,proxy_count); if(ns!=-1) close(ns); @@ -648,7 +668,7 @@ struct hostent* proxy_gethostbyname(const char *name) // TODO: this works only once, so cache it ... // later - while (hp=gethostent()) + while ((hp=gethostent())) if (!strcmp(hp->h_name,name)) return hp; @@ -679,7 +699,7 @@ struct hostent* proxy_gethostbyname(const char *name) close(pipe_fd[0]); got_buff: addr = inet_addr(buff); - if (addr == -1) + if (addr == (in_addr_t) (-1)) goto err_dns; memcpy(*(hostent_space.h_addr_list), &addr ,sizeof(struct in_addr)); @@ -690,7 +710,8 @@ got_buff: name, inet_ntoa(*(struct in_addr*)&addr)); return &hostent_space; err_dns: - proxychains_write_log("|DNS-response|: %s is not exist\n", name); + proxychains_write_log("|DNS-response|: %s does not exist\n", name); + perror("err_dns"); err: return NULL; } diff --git a/src/core.h b/src/core.h index 6375bba..e8d0d4e 100644 --- a/src/core.h +++ b/src/core.h @@ -41,18 +41,16 @@ typedef struct unsigned short port; } localaddr_arg; -typedef struct -{ -unsigned int ip; -unsigned short port; -proxy_type pt; -proxy_state ps; -char user[256]; -char pass[256]; +typedef struct { + unsigned int ip; + unsigned short port; + proxy_type pt; + proxy_state ps; + char user[256]; + char pass[256]; } proxy_data; -typedef struct -{ +typedef struct { proxy_data *pd; chain_type ct; unsigned int proxy_count; @@ -68,7 +66,7 @@ int connect_proxy_chain ( proxy_data * pd, unsigned int proxy_count, chain_type ct, - int max_chain ); + unsigned int max_chain ); int proxychains_write_log(char *str,...); struct hostent* proxy_gethostbyname(const char *name); @@ -103,10 +101,10 @@ int proxy_getaddrinfo(const char *node, const char *service, struct hostent* proxy_gethostbyname(const char *name); -#if 0 -#define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args) +#ifdef DEBUG +# define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args) #else -#define PDEBUG(fmt, args...) +# define PDEBUG(fmt, args...) #endif #endif diff --git a/src/libproxychains.c b/src/libproxychains.c index 57309c6..787e046 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -14,10 +14,10 @@ * (at your option) any later version. * * * ***************************************************************************/ + +#undef _GNU_SOURCE #define _GNU_SOURCE -#ifdef HAVE_CONFIG_H -#include -#endif + #include #include #include @@ -46,9 +46,9 @@ int tcp_read_time_out; int tcp_connect_time_out; chain_type proxychains_ct; proxy_data proxychains_pd[MAX_CHAIN]; -int proxychains_proxy_count = 0; +unsigned int proxychains_proxy_count = 0; int proxychains_got_chain_data = 0; -int proxychains_max_chain = 1; +unsigned int proxychains_max_chain = 1; int proxychains_quiet_mode = 0; int proxychains_resolver = 0; static int init_l = 0; @@ -61,20 +61,28 @@ static void init_lib(void); static void init_lib(void) { -// proxychains_write_log("ProxyChains-"VERSION -// " (http://proxychains.sf.net)\n"); + proxychains_write_log("ProxyChains-3.1 (http://proxychains.sf.net)\n"); - get_chain_data(proxychains_pd,&proxychains_proxy_count,&proxychains_ct); + get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct); 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); + #ifdef DEBUG + PDEBUG( "loaded symbol 'connect'" + " real addr %p wrapped addr %p\n", + true_connect, connect); + #endif } + if(connect==true_connect) { + #ifdef DEBUG + PDEBUG("circular reference detected, aborting!\n"); + #endif + abort(); + } + true_gethostbyname = (gethostbyname_t) dlsym(RTLD_NEXT, "gethostbyname"); @@ -83,9 +91,11 @@ static void init_lib(void) dlerror()); exit(1); } else { -// PDEBUG( "loaded symbol 'gethostbyname'" -// " real addr %p wrapped addr %p\n", -// true_gethostbyname, gethostbyname); + #ifdef DEBUG + PDEBUG( "loaded symbol 'gethostbyname'" + " real addr %p wrapped addr %p\n", + true_gethostbyname, gethostbyname); + #endif } true_getaddrinfo = (getaddrinfo_t) dlsym(RTLD_NEXT, "getaddrinfo"); @@ -95,9 +105,11 @@ static void init_lib(void) dlerror()); exit(1); } else { -// PDEBUG( "loaded symbol 'getaddrinfo'" -// " real addr %p wrapped addr %p\n", -// true_getaddrinfo, getaddrinfo); + #ifdef DEBUG + PDEBUG( "loaded symbol 'getaddrinfo'" + " real addr %p wrapped addr %p\n", + true_getaddrinfo, getaddrinfo); + #endif } true_freeaddrinfo = (freeaddrinfo_t) dlsym(RTLD_NEXT, "freeaddrinfo"); @@ -107,9 +119,11 @@ static void init_lib(void) dlerror()); exit(1); } else { -// PDEBUG( "loaded symbol 'freeaddrinfo'" -// " real addr %p wrapped addr %p\n", -// true_freeaddrinfo, freeaddrinfo); + #ifdef DEBUG + PDEBUG( "loaded symbol 'freeaddrinfo'" + " real addr %p wrapped addr %p\n", + true_freeaddrinfo, freeaddrinfo); + #endif } true_gethostbyaddr = (gethostbyaddr_t) dlsym(RTLD_NEXT, "gethostbyaddr"); @@ -119,9 +133,11 @@ static void init_lib(void) dlerror()); exit(1); } else { -// PDEBUG( "loaded symbol 'gethostbyaddr'" -// " real addr %p wrapped addr %p\n", -// true_gethostbyaddr, gethostbyaddr); + #ifdef DEBUG + PDEBUG( "loaded symbol 'gethostbyaddr'" + " real addr %p wrapped addr %p\n", + true_gethostbyaddr, gethostbyaddr); + #endif } true_getnameinfo = (getnameinfo_t) dlsym(RTLD_NEXT, "getnameinfo"); @@ -131,9 +147,11 @@ static void init_lib(void) dlerror()); exit(1); } else { -// PDEBUG( "loaded symbol 'getnameinfo'" -// " real addr %p wrapped addr %p\n", -// true_getnameinfo, getnameinfo); + #ifdef DEBUG + PDEBUG( "loaded symbol 'getnameinfo'" + " real addr %p wrapped addr %p\n", + true_getnameinfo, getnameinfo); + #endif } init_l = 1; } @@ -160,9 +178,9 @@ static inline void get_chain_data( return; //Some defaults - tcp_read_time_out=4*1000; - tcp_connect_time_out=10*1000; - *ct=DYNAMIC_TYPE; + tcp_read_time_out = 4*1000; + tcp_connect_time_out = 10*1000; + *ct = DYNAMIC_TYPE; env = NULL; @@ -184,7 +202,7 @@ static inline void get_chain_data( } while(fgets(buff,sizeof(buff),file)) { - if(buff[strspn(buff," ")]!='#') { + if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') { if(list) { memset(&pd[count], 0, sizeof(proxy_data)); pd[count].ps=PLAY_STATE; @@ -201,7 +219,7 @@ static inline void get_chain_data( pd[count].pt=SOCKS5_TYPE; }else continue; - if( pd[count].ip && pd[count].ip!=-1 && port_n) + if( pd[count].ip && (int) pd[count].ip != -1 && port_n) if(++count==MAX_CHAIN) break; } else { @@ -278,16 +296,19 @@ static inline void get_chain_data( } } fclose(file); - *proxy_count=count; - proxychains_got_chain_data=1; + *proxy_count = count; + proxychains_got_chain_data = 1; } int connect (int sock, const struct sockaddr *addr, unsigned int len) { - int socktype=0,optlen=0,flags=0,ret=0; + int socktype=0, flags=0, ret=0; + socklen_t optlen = 0; +#ifdef DEBUG char str[256]; +#endif struct in_addr *p_addr_in; unsigned short port; size_t i; @@ -302,10 +323,12 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len) p_addr_in = &((struct sockaddr_in *)addr)->sin_addr; port = ntohs(((struct sockaddr_in *)addr)->sin_port); - //PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str))); - //PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str))); - //PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str))); - //PDEBUG("port: %d\n", port); +#ifdef DEBUG +// PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str))); +// PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str))); + PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str))); + PDEBUG("port: %d\n", port); +#endif for (i = 0; i < num_localnet_addr; 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)) @@ -327,7 +350,7 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len) proxychains_pd, proxychains_proxy_count, proxychains_ct, - proxychains_max_chain ); + proxychains_max_chain ); fcntl(sock, F_SETFL, flags); if(ret!=SUCCESS) errno=ECONNREFUSED; @@ -346,6 +369,7 @@ struct hostent *gethostbyname(const char *name) return NULL; } + int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) @@ -361,6 +385,7 @@ int getaddrinfo(const char *node, const char *service, return ret; } + void freeaddrinfo(struct addrinfo *res) { PDEBUG("freeaddrinfo %p \n",res); @@ -375,12 +400,20 @@ void freeaddrinfo(struct addrinfo *res) return; } +#ifdef __GLIBC__ +int getnameinfo (const struct sockaddr * sa, + socklen_t salen, char * host, + socklen_t hostlen, char * serv, + socklen_t servlen, unsigned int flags) +#else int getnameinfo (const struct sockaddr * sa, socklen_t salen, char * host, socklen_t hostlen, char * serv, socklen_t servlen, int flags) +#endif { int ret = 0; + PDEBUG("getnameinfo: %s %s\n", host, serv); if(!init_l) init_lib(); if(!proxychains_resolver) { @@ -392,17 +425,55 @@ int getnameinfo (const struct sockaddr * sa, if(servlen) snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa))); } - PDEBUG("getnameinfo: %s %s\n", host, serv); return ret; } +// stolen from libulz (C) rofl0r +static void pc_stringfromipv4(unsigned char* ip_buf_4_bytes, char* outbuf_16_bytes) { + unsigned char* p; + char *o = outbuf_16_bytes; + unsigned char n; + for(p = ip_buf_4_bytes; p < ip_buf_4_bytes + 4; p++) { + n = *p; + if(*p >= 100) { + if(*p >= 200) *(o++) = '2'; + else *(o++) = '1'; + n %= 100; + } + if(*p >= 10) { + *(o++) = (n / 10) + '0'; + n %= 10; + } + *(o++) = n + '0'; + *(o++) = '.'; + } + o[-1] = 0; +} + struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) { - PDEBUG("TODO: gethostbyaddr hook\n"); + static char buf[16]; + static char ipv4[4]; + static char* list[2]; + static struct hostent he; + PDEBUG("TODO: proper gethostbyaddr hook\n"); if(!init_l) init_lib(); if(!proxychains_resolver) return true_gethostbyaddr(addr,len,type); + else { + if(len != 4) return NULL; + he.h_name = buf; + memcpy(ipv4, addr, 4); + list[0] = ipv4; + list[1] = NULL; + he.h_addr_list = list; + he.h_addrtype = AF_INET; + he.h_aliases = NULL; + he.h_length = 4; + pc_stringfromipv4((unsigned char*)addr, buf); + return &he; + } return NULL; } diff --git a/src/main.c b/src/main.c index 50a5ffe..4ec6ac2 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,9 @@ /*************************************************************************** main.c - description - q ------------------- + begin : Tue May 14 2002 - copyright : netcreature (C) 2002 - email : netcreature@users.sourceforge.net + copyright : netcreature (C) 2002 + email : netcreature@users.sourceforge.net ***************************************************************************/ /* GPL */ /*************************************************************************** @@ -15,71 +15,73 @@ * * ***************************************************************************/ - -/* -* well ... actually this file could be a shell script ... but C rulez :). -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include -#include +#include #include #include #include extern char *optarg; -extern int optind, opterr, optopt +extern int optind, opterr, optopt; -/* - * XXX. Same thing is defined in proxychains main.c it - * needs to be changed, too. - */ -#define PROXYCHAINS_CONF_FILE "PROXYCHAINS_CONF_FILE" +#define PROXYCHAINS_CONF_FILE "proxychains.conf" -static usage(void) -{ - - printf("\nUsage: %s [h] [f] config_file program_name [arguments]\n" - "\t for example : proxychains telnet somehost.com\n" - "More help in README file\n", argv[0], ); +static void usage(char** argv) { + printf("\nUsage: %s [h] [f] config_file program_name [arguments]\n" + "\t for example : proxychains telnet somehost.com\n" + "More help in README file\n", argv[0]); } -int main(int argc, char *argv[]) -{ - char *path; +int main(int argc, char *argv[]) { + char *path = NULL; + char buf[256]; + char pbuf[256]; + int opt; - path = NULL; + while ((opt = getopt(argc, argv, "fh:")) != -1) { + switch (opt) { + case 'h': + usage(argv); + break; + case 'f': + path = (char *)optarg; + break; + default: /* '?' */ + usage(argv); + exit(EXIT_FAILURE); + } + } - while ((opt = getopt(argc, argv, "fh:")) != -1) { - switch (opt) { - case 'h': - usage(); - break; - case 'f': - path = (char *)optarg; - break; - default: /* '?' */ - usage(); - exit(EXIT_FAILURE); - } - } + if(!path) { + if(!(path = getenv("PROXYCHAINS_CONF_FILE"))) + path = getcwd(buf, sizeof(buf)); + else if(access(path, R_OK) != -1) goto have; + if(!path || + !snprintf(pbuf, sizeof(pbuf), "%s/%s", path, PROXYCHAINS_CONF_FILE) || + access(pbuf, R_OK) == -1 + ) + path = "/etc/proxychains.conf"; + else + path = pbuf; + } + if(access(path, R_OK) == -1) { + perror("couldnt find configuration file"); + return 1; + } + have: - printf("Proxychains are going to use %s as config file.\n", path); - printf("argv = %s\n", argv[1]); + printf("Proxychains is going to use %s as config file.\n", path); + printf("argv = %s\n", argv[1]); - /* Set PROXYCHAINS_CONF_FILE to get proxychains lib to - use new config file. */ - setenv(PROXYCHAINS_CONF_FILE, path, 1); + /* Set PROXYCHAINS_CONF_FILE to get proxychains lib to use new config file. */ + setenv("PROXYCHAINS_CONF_FILE", path, 1); + + snprintf(buf, sizeof(buf), "LD_PRELOAD=%s/libproxychains.so", LIB_DIR); + putenv(buf); + execvp(argv[1], &argv[1]); + perror("proxychains can't load process...."); - /*XXX. proxychains might be installed in some different location */ - putenv("LD_PRELOAD=/usr/lib/libproxychains.so"); - execvp(argv[1],&argv[1]); - perror("proxychains can't load process...."); - - return EXIT_SUCCESS; + return EXIT_SUCCESS; }