From f512779539f20d6cc2a9ade700ddb70105f3d5b5 Mon Sep 17 00:00:00 2001 From: Adam Hamsik Date: Fri, 27 Jan 2012 14:35:00 +0100 Subject: [PATCH] Replace homegrown pc_stringfromipv4 standard libc inet_ntoa, this should be available on all libcs (musl checked). Reenable accidentaly disabled THREAD_SAFE. --- Makefile | 2 +- src/core.c | 90 ++++++++++++++--------------- src/libproxychains.c | 132 +++++++++++++++++++------------------------ 3 files changed, 103 insertions(+), 121 deletions(-) diff --git a/Makefile b/Makefile index d0f8a37..a0ee259 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ SRCS = $(sort $(wildcard src/*.c)) OBJS = $(SRCS:.c=.o) LOBJS = src/core.o src/libproxychains.o -CCFLAGS = -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe #-DTHREAD_SAFE -Werror +CCFLAGS = -Wall -O0 -g -std=c99 -D_GNU_SOURCE -D_BSD_SOURCE -pipe -DTHREAD_SAFE -Werror LDFLAGS = -shared -fPIC -ldl -lpthread INC = PIC = -fPIC diff --git a/src/core.c b/src/core.c index bd7ec5a..a1f2f1d 100644 --- a/src/core.c +++ b/src/core.c @@ -89,7 +89,7 @@ in_addr_t make_internal_ip(uint32_t index) { static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) +static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) { int ret; int time_remain = timeout; @@ -207,7 +207,7 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) struct pollfd pfd[1]; pfd[0].fd=sock; - pfd[0].events=POLLOUT; + pfd[0].events=POLLOUT; fcntl(sock, F_SETFL, O_NONBLOCK); ret = true_connect(sock, addr, len); #ifdef DEBUG @@ -481,11 +481,11 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch static int start_chain(int *fd, proxy_data *pd, char* begin_mark) { struct sockaddr_in addr; - + *fd=socket(PF_INET,SOCK_STREAM,0); if(*fd==-1) goto error; - + proxychains_write_log(LOG_PREFIX "%s "TP" %s:%d ", begin_mark, inet_ntoa(*(struct in_addr*)&pd->ip), @@ -509,7 +509,7 @@ error: return SOCKET_ERROR; } -static proxy_data * select_proxy(select_type how, +static proxy_data * select_proxy(select_type how, proxy_data *pd, unsigned int proxy_count, unsigned int *offset) { unsigned int i=0, k=0; @@ -583,12 +583,12 @@ static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto) usenumericip: hostname = inet_ntoa(*(struct in_addr*)&pto->ip); } - - proxychains_write_log(TP" %s:%d ", + + proxychains_write_log(TP" %s:%d ", hostname, htons(pto->port)); - retcode = - tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, + retcode = + tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass); switch(retcode) { case SUCCESS: @@ -608,8 +608,8 @@ 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, +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 p4; @@ -618,10 +618,10 @@ int connect_proxy_chain( int sock, ip_type target_ip, unsigned int offset=0; unsigned int alive_count=0; unsigned int curr_len=0; - + p3=&p4; PDEBUG("connect_proxy_chain\n"); - + again: switch(ct) { @@ -675,7 +675,7 @@ again: if(SUCCESS!=chain_step(ns, p1, p3)) goto error; break; - + case RANDOM_TYPE: alive_count=calc_alive(pd,proxy_count); if(alive_countport = target_port; if(SUCCESS!=chain_step(ns,p1,p3)) goto error; - + } proxychains_write_log(TP" OK\n"); @@ -711,7 +711,7 @@ error: close(ns); errno = ECONNREFUSED; // for nmap ;) return -1; - + error_more: proxychains_write_log("\n!!!need more proxies!!!\n"); error_strict: @@ -738,34 +738,34 @@ struct hostent* proxy_gethostbyname(const char *name) size_t l; struct hostent* hp; - + resolved_addr_p[0] = (char*) &resolved_addr; resolved_addr_p[1] = NULL; - + hostent_space.h_addr_list = resolved_addr_p; resolved_addr = 0; - + gethostname(buff,sizeof(buff)); - + if(!strcmp(buff, name)) { resolved_addr = inet_addr(buff); if (resolved_addr == (in_addr_t) (-1)) resolved_addr = (in_addr_t) (local_host.as_int); return &hostent_space; } - + memset(buff, 0, sizeof(buff)); - + while ((hp=gethostent())) - if (!strcmp(hp->h_name,name)) - return hp; - - + if (!strcmp(hp->h_name,name)) + return hp; + + hash = dalias_hash((char*) name); - + proxychains_mutex_lock(&internal_ips_lock); - + // see if we already have this dns entry saved. if(internal_ips.counter) { for( i = 0; i < internal_ips.counter; i++) { @@ -776,7 +776,7 @@ struct hostent* proxy_gethostbyname(const char *name) } } } - + // grow list if needed. if(internal_ips.capa < internal_ips.counter + 1) { PDEBUG("realloc\n"); @@ -790,31 +790,31 @@ struct hostent* proxy_gethostbyname(const char *name) goto err_plus_unlock; } } - + resolved_addr = make_internal_ip(internal_ips.counter); if(resolved_addr == (in_addr_t) -1) goto err_plus_unlock; l = strlen(name); new_mem = malloc(sizeof(string_hash_tuple) + l + 1); - if(!new_mem) + if(!new_mem) goto oom; - + PDEBUG("creating new entry %d for ip of %s\n", (int) internal_ips.counter, name); - + internal_ips.list[internal_ips.counter] = new_mem; internal_ips.list[internal_ips.counter]->hash = hash; internal_ips.list[internal_ips.counter]->string = (char*) new_mem + sizeof(string_hash_tuple); - + memcpy(internal_ips.list[internal_ips.counter]->string, name, l + 1); - + internal_ips.counter += 1; - + have_ip: - + proxychains_mutex_unlock(&internal_ips_lock); - + strncpy(addr_name, name, sizeof(addr_name)); - + hostent_space.h_name = addr_name; hostent_space.h_length = sizeof (in_addr_t); return &hostent_space; @@ -831,7 +831,7 @@ int proxy_getaddrinfo(const char *node, const char *service, struct hostent *hp = NULL; struct sockaddr* sockaddr_space = NULL; struct addrinfo* addrinfo_space = NULL; - + // printf("proxy_getaddrinfo node %s service %s\n",node,service); addrinfo_space = malloc(sizeof(struct addrinfo)); if(!addrinfo_space) @@ -844,7 +844,7 @@ int proxy_getaddrinfo(const char *node, const char *service, if (node && !inet_aton(node,&((struct sockaddr_in*)sockaddr_space)->sin_addr)) { hp = proxy_gethostbyname(node); - if (hp) + if (hp) memcpy(&((struct sockaddr_in*)sockaddr_space)->sin_addr, *(hp->h_addr_list), sizeof(in_addr_t)); @@ -853,11 +853,11 @@ int proxy_getaddrinfo(const char *node, const char *service, } if (service) se = getservbyname(service, NULL); - + if (!se) { - ((struct sockaddr_in*)sockaddr_space)->sin_port = + ((struct sockaddr_in*)sockaddr_space)->sin_port = htons(atoi(service?:"0")); - } else + } else ((struct sockaddr_in*)sockaddr_space)->sin_port = se->s_port; *res = addrinfo_space; diff --git a/src/libproxychains.c b/src/libproxychains.c index acf82ca..3ac44a3 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -18,6 +18,9 @@ #undef _GNU_SOURCE #define _GNU_SOURCE +#undef _BSD_SOURCE +#define _BSD_SOURCE + #include #include @@ -70,14 +73,14 @@ static void init_lib(void); static void init_lib(void) { - /* Initialize mutex for internal ip list */ - proxychains_mutex_init(&internal_ips_lock); + /* Initialize mutex for internal ip list */ + proxychains_mutex_init(&internal_ips_lock); /* 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) { @@ -92,12 +95,12 @@ init_lib(void) PDEBUG("circular reference detected, aborting!\n"); abort(); } - - true_gethostbyname = (gethostbyname_t) + + true_gethostbyname = (gethostbyname_t) dlsym(RTLD_NEXT, "gethostbyname"); if (!true_gethostbyname) { - fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", + fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", dlerror()); exit(1); } else { @@ -105,11 +108,11 @@ init_lib(void) " real addr %p wrapped addr %p\n", true_gethostbyname, gethostbyname); } - true_getaddrinfo = (getaddrinfo_t) + true_getaddrinfo = (getaddrinfo_t) dlsym(RTLD_NEXT, "getaddrinfo"); if (!true_getaddrinfo) { - fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", + fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", dlerror()); exit(1); } else { @@ -117,11 +120,11 @@ init_lib(void) " real addr %p wrapped addr %p\n", true_getaddrinfo, getaddrinfo); } - true_freeaddrinfo = (freeaddrinfo_t) + true_freeaddrinfo = (freeaddrinfo_t) dlsym(RTLD_NEXT, "freeaddrinfo"); if (!true_freeaddrinfo) { - fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", + fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", dlerror()); exit(1); } else { @@ -129,11 +132,11 @@ init_lib(void) " real addr %p wrapped addr %p\n", true_freeaddrinfo, freeaddrinfo); } - true_gethostbyaddr = (gethostbyaddr_t) + true_gethostbyaddr = (gethostbyaddr_t) dlsym(RTLD_NEXT, "gethostbyaddr"); if (!true_gethostbyaddr) { - fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", + fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", dlerror()); exit(1); } else { @@ -141,11 +144,11 @@ init_lib(void) " real addr %p wrapped addr %p\n", true_gethostbyaddr, gethostbyaddr); } - true_getnameinfo = (getnameinfo_t) + true_getnameinfo = (getnameinfo_t) dlsym(RTLD_NEXT, "getnameinfo"); if (!true_getnameinfo) { - fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", + fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", dlerror()); exit(1); } else { @@ -156,9 +159,7 @@ init_lib(void) init_l = 1; } -static inline void get_chain_data( - proxy_data *pd, - unsigned int *proxy_count, +static inline void get_chain_data(proxy_data *pd, unsigned int *proxy_count, chain_type *ct) { int count=0,port_n=0,list=0; @@ -192,7 +193,7 @@ static inline void get_chain_data( perror("Can't locate proxychains.conf"); exit(1); } - + env = getenv(PROXYCHAINS_QUIET_MODE_ENV_VAR); if(env && *env == '1') proxychains_quiet_mode = 1; @@ -200,25 +201,25 @@ static inline void get_chain_data( if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') { if(list) { memset(&pd[count], 0, sizeof(proxy_data)); - + pd[count].ps = PLAY_STATE; port_n = 0; - + sscanf(buff,"%s %s %d %s %s", type, host, &port_n, pd[count].user, pd[count].pass); - + pd[count].ip.as_int = (uint32_t) inet_addr(host); 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 + } else continue; - + if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) -1) if(++count==MAX_CHAIN) @@ -304,8 +305,6 @@ static inline void get_chain_data( proxychains_got_chain_data = 1; } - - int connect (int sock, const struct sockaddr *addr, socklen_t len) { int socktype=0, flags=0, ret=0; @@ -348,9 +347,9 @@ int connect (int sock, const struct sockaddr *addr, socklen_t len) flags = fcntl(sock, F_GETFL, 0); if(flags & O_NONBLOCK) fcntl(sock, F_SETFL, !O_NONBLOCK); - + dest_ip.as_int = SOCKADDR(*addr); - + ret = connect_proxy_chain( sock, dest_ip, @@ -359,7 +358,7 @@ int connect (int sock, const struct sockaddr *addr, socklen_t len) proxychains_proxy_count, proxychains_ct, proxychains_max_chain ); - + fcntl(sock, F_SETFL, flags); if(ret != SUCCESS) errno = ECONNREFUSED; @@ -370,14 +369,14 @@ struct hostent *gethostbyname(const char *name) { if(!init_l) init_lib(); - + PDEBUG("gethostbyname: %s\n",name); - + if(proxychains_resolver) return proxy_gethostbyname(name); else return true_gethostbyname(name); - + return NULL; } @@ -386,17 +385,17 @@ int getaddrinfo(const char *node, const char *service, struct addrinfo **res) { int ret = 0; - + if(!init_l) init_lib(); - + PDEBUG("getaddrinfo: %s %s\n",node ,service); - + if(proxychains_resolver) ret = proxy_getaddrinfo(node, service, hints, res); else ret = true_getaddrinfo(node, service, hints, res); - + return ret; } @@ -404,9 +403,9 @@ void freeaddrinfo(struct addrinfo *res) { if(!init_l) init_lib(); - + PDEBUG("freeaddrinfo %p \n",res); - + if(!proxychains_resolver) true_freeaddrinfo(res); else { @@ -419,9 +418,9 @@ void freeaddrinfo(struct addrinfo *res) // 2.14 came out in June 2011 so that should be the first fixed version #if defined(__GLIBC__) && (__GLIBC__ < 3) && (__GLIBC_MINOR__ < 14) int getnameinfo (const struct sockaddr * sa, - socklen_t salen, char * host, - socklen_t hostlen, char * serv, - socklen_t servlen, unsigned int flags) + 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, @@ -430,64 +429,47 @@ int getnameinfo (const struct sockaddr * sa, #endif { int ret = 0; - + if(!init_l) init_lib(); - + PDEBUG("getnameinfo: %s %s\n", host, serv); - + if(!proxychains_resolver) { ret = true_getnameinfo(sa,salen,host,hostlen, serv,servlen,flags); } else { - if(hostlen) + if(hostlen) strncpy(host, inet_ntoa(SOCKADDR_2(*sa)),hostlen); - if(servlen) + if(servlen) snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa))); } 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; -} - +/* XXX Add proper gethostbyaddr hook */ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) { static char buf[16]; static char ipv4[4]; static char* list[2]; static struct hostent he; - + struct in_addr ip; + + memcpy((void *) &ip, addr, sizeof(struct in_addr)); + if(!init_l) init_lib(); - + PDEBUG("TODO: proper gethostbyaddr hook\n"); - + if(!proxychains_resolver) return true_gethostbyaddr(addr,len,type); else { - + PDEBUG("len %u\n", len); - if(len != 4) return NULL; + if(len != 4) + return NULL; he.h_name = buf; memcpy(ipv4, addr, 4); list[0] = ipv4; @@ -496,7 +478,7 @@ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) he.h_addrtype = AF_INET; he.h_aliases = NULL; he.h_length = 4; - pc_stringfromipv4((unsigned char*)addr, buf); + snprintf(buf, 16, "%s", inet_ntoa(ip)); return &he; } return NULL;