diff --git a/src/core.c b/src/core.c index ab5a78b..4450c0d 100644 --- a/src/core.c +++ b/src/core.c @@ -94,7 +94,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; @@ -113,7 +113,7 @@ static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) //printf("Time elapsed %d\n", time_elapsed); time_remain = timeout - time_elapsed; } while (ret == -1 && errno == EINTR && time_remain > 0); - + //if (ret == -1) //printf("Return %d %d %s\n", ret, errno, strerror(errno)); return ret; @@ -196,7 +196,7 @@ static int read_n_bytes(int fd,char *buff, size_t size) pfd[0].fd=fd; pfd[0].events=POLLIN; - for(i=0; i < size; i++) { + for(i=0; i < size; i++) { pfd[0].revents = 0; ready = poll_retry(pfd, 1, tcp_read_time_out); if(ready != 1 || !(pfd[0].revents&POLLIN) || 1 != read(fd,&buff[i],1)) @@ -212,13 +212,13 @@ 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 if(ret == -1) perror("true_connect"); printf("\nconnect ret=%d\n",ret); - + fflush(stdout); #endif if(ret==-1 && errno==EINPROGRESS) { @@ -242,7 +242,7 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) } else { if (ret != 0) ret=-1; - } + } fcntl(sock, F_SETFL, !O_NONBLOCK); return ret; @@ -254,10 +254,10 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch { #ifdef DEBUG PDEBUG("tunnel_to()\n"); -#endif +#endif char* dns_name = NULL; size_t dns_len = 0; - + // we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution // the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with // the results returned from gethostbyname et al.) @@ -268,38 +268,38 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch dns_len = strlen(dns_name); if(!dns_len) goto err; } - + size_t ulen = strlen(user); size_t passlen = strlen(pass); - + if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) { proxychains_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n"); goto err; } - + int len; unsigned char buff[BUFF_SIZE]; //memset (buff, 0, sizeof(buff)); - + switch(pt) { case HTTP_TYPE: { if(!dns_len) dns_name = inet_ntoa( * (struct in_addr *) &ip.as_int); - + snprintf((char*)buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n", dns_name, ntohs(port)); - + if (user[0]) { #define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1) // 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator. char src[HTTP_AUTH_MAX]; char dst[(4 * HTTP_AUTH_MAX)]; - + memcpy(src, user, ulen); memcpy(src + ulen, ":", 1); memcpy(src + ulen + 1, pass, passlen); src[ulen + 1 + passlen] = 0; - + encode_base_64(src, dst, sizeof(dst)); strcat((char*)buff,"Proxy-Authorization: Basic "); strcat((char*)buff, dst); @@ -307,12 +307,12 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch } else strcat((char*)buff, "\r\n"); - + len = strlen((char*)buff); if(len != send(sock, buff, len, 0)) goto err; - + len = 0 ; // read header byte by byte. while(len < BUFF_SIZE) { @@ -338,7 +338,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch return SUCCESS; } break; - + case SOCKS4_TYPE: { buff[0] = 4; // socks version buff[1] = 1; // connect command @@ -356,19 +356,19 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch else { buff[8] = 0; } - + // do socksv4a dns resolution on the server if(dns_len) { memcpy(&buff[8 + len], dns_name, dns_len + 1); len += dns_len + 1; } - + if((len + 8) != write_n_bytes(sock, (char*) buff, (8+len))) goto err; if(8 != read_n_bytes(sock, (char*)buff, 8)) goto err; - + if (buff[0] != 0 || buff[1] != 90) return BLOCKED; @@ -394,14 +394,14 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch if(2 != read_n_bytes(sock, (char*) buff, 2)) goto err; - + if (buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) { if(buff[0] == 5 && buff[1] == 0xFF) return BLOCKED; else goto err; } - + if (buff[1] == 2) { // authentication char in[2]; @@ -416,11 +416,11 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch *cur++ = c; memcpy(cur, pass, c); cur += c; - + if((cur-out) != write_n_bytes(sock, out, cur-out)) goto err; - - + + if(2 != read_n_bytes(sock,in,2)) goto err; if(in[0] != 1 || in[1] != 0) { @@ -434,7 +434,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch buff[buff_iter++] = 5; // version buff[buff_iter++] = 1; // connect buff[buff_iter++] = 0; // reserved - + if(!dns_len) { buff[buff_iter++] = 1; // ip v4 memcpy(buff + buff_iter, &ip, 4); // dest host @@ -445,14 +445,14 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch memcpy(buff + buff_iter, dns_name, dns_len); buff_iter += dns_len; } - + memcpy(buff + buff_iter, &port, 2); // dest port buff_iter += 2; - + if(buff_iter != write_n_bytes(sock, (char*)buff, buff_iter)) goto err; - + if(4 != read_n_bytes(sock, (char*)buff, 4)) goto err; @@ -460,7 +460,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch goto err; switch (buff[3]) { - + case 1: len = 4; break; case 4: len = 16; break; case 3: len = 0; @@ -491,11 +491,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), @@ -519,7 +519,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; @@ -593,12 +593,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: @@ -618,8 +618,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; @@ -628,12 +628,12 @@ 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; #ifdef DEBUG PDEBUG("connect_proxy_chain\n"); #endif - + again: switch(ct) { @@ -695,7 +695,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"); @@ -733,7 +733,7 @@ error: close(ns); errno = ECONNREFUSED; // for nmap ;) return -1; - + error_more: proxychains_write_log("\n!!!need more proxies!!!\n"); error_strict: @@ -762,36 +762,36 @@ 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); - + #ifdef THREAD_SAFE pthread_mutex_lock(&internal_ips_lock); #endif - + // see if we already have this dns entry saved. if(internal_ips.counter) { for( i = 0; i < internal_ips.counter; i++) { @@ -802,7 +802,7 @@ struct hostent* proxy_gethostbyname(const char *name) } } } - + // grow list if needed. if(internal_ips.capa < internal_ips.counter + 1) { PDEBUG("realloc\n"); @@ -816,34 +816,34 @@ 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: - + #ifdef THREAD_SAFE pthread_mutex_unlock(&internal_ips_lock); #endif - + strncpy(addr_name, name, sizeof(addr_name)); - + hostent_space.h_name = addr_name; hostent_space.h_length = sizeof (in_addr_t); return &hostent_space; @@ -862,7 +862,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) @@ -875,7 +875,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)); @@ -884,11 +884,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/core.h b/src/core.h index 1ec41c5..9fc9a1b 100644 --- a/src/core.h +++ b/src/core.h @@ -148,4 +148,4 @@ struct hostent* proxy_gethostbyname(const char *name); # define PDEBUG(fmt, args...) #endif -#endif +#endif diff --git a/src/libproxychains.c b/src/libproxychains.c index 2d94dbc..c1f8c15 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -68,9 +68,9 @@ static void init_lib(void) #endif /* 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) { @@ -89,12 +89,12 @@ static void init_lib(void) #endif 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 { @@ -104,11 +104,11 @@ static void init_lib(void) true_gethostbyname, gethostbyname); #endif } - 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 { @@ -118,11 +118,11 @@ static void init_lib(void) true_getaddrinfo, getaddrinfo); #endif } - 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 { @@ -132,11 +132,11 @@ static void init_lib(void) true_freeaddrinfo, freeaddrinfo); #endif } - 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 { @@ -146,11 +146,11 @@ static void init_lib(void) true_gethostbyaddr, gethostbyaddr); #endif } - 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 { @@ -199,7 +199,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; @@ -207,25 +207,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) @@ -355,9 +355,9 @@ int connect (int sock, const struct sockaddr *addr, unsigned int 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, @@ -366,7 +366,7 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len) proxychains_proxy_count, proxychains_ct, proxychains_max_chain ); - + fcntl(sock, F_SETFL, flags); if(ret != SUCCESS) errno = ECONNREFUSED; @@ -377,14 +377,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; } @@ -393,17 +393,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; } @@ -411,9 +411,9 @@ void freeaddrinfo(struct addrinfo *res) { if(!init_l) init_lib(); - + PDEBUG("freeaddrinfo %p \n",res); - + if(!proxychains_resolver) true_freeaddrinfo(res); else { @@ -437,19 +437,19 @@ 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; @@ -483,16 +483,16 @@ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) static char ipv4[4]; static char* list[2]; static struct hostent he; - + 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; he.h_name = buf; @@ -508,4 +508,4 @@ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) } return NULL; } - + diff --git a/src/main.c b/src/main.c index 6a39106..b5259f5 100644 --- a/src/main.c +++ b/src/main.c @@ -77,22 +77,22 @@ int main(int argc, char *argv[]) { int quiet = 0; size_t i; const char* prefix = NULL; - + for(i = 0; i < MAX_COMMANDLINE_FLAGS; i++) { if(start_argv < argc && argv[start_argv][0] == '-') { if(argv[start_argv][1] == 'q') { quiet = 1; start_argv++; } else if(argv[start_argv][1] == 'f') { - - if(start_argv + 1 < argc) + + if(start_argv + 1 < argc) path = argv[start_argv + 1]; - else + else return usage(argv); - + start_argv += 2; } - } else + } else break; } @@ -103,33 +103,33 @@ int main(int argc, char *argv[]) { // priority 1: env var PROXYCHAINS_CONF_FILE path = getenv(PROXYCHAINS_CONF_FILE_ENV_VAR); if(check_path(path)) goto have; - + // priority 2; proxychains conf in actual dir path = getcwd(buf, sizeof(buf)); snprintf(pbuf, sizeof(pbuf), "%s/%s", path, PROXYCHAINS_CONF_FILE); path = pbuf; if(check_path(path)) goto have; - + // priority 3; $HOME/.proxychains/proxychains.conf path = getenv("HOME"); snprintf(pbuf, sizeof(pbuf), "%s/.proxychains/%s", path, PROXYCHAINS_CONF_FILE); path = pbuf; if(check_path(path)) goto have; - + // priority 4: /etc/proxychains.conf path = "/etc/proxychains.conf"; if(check_path(path)) goto have; perror("couldnt find configuration file"); return 1; } - + have: if(!quiet) fprintf(stderr, LOG_PREFIX "config file found: %s\n", path); /* Set PROXYCHAINS_CONF_FILE to get proxychains lib to use new config file. */ setenv(PROXYCHAINS_CONF_FILE_ENV_VAR, path, 1); - + if(quiet) setenv(PROXYCHAINS_QUIET_MODE_ENV_VAR, "1", 1); @@ -151,7 +151,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } if(!quiet) fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name); - + snprintf(buf, sizeof(buf), "LD_PRELOAD=%s/%s", prefix, dll_name); putenv(buf);