diff --git a/src/core.c b/src/core.c index 4450c0d..e0b3767 100644 --- a/src/core.c +++ b/src/core.c @@ -46,15 +46,15 @@ extern int tcp_connect_time_out; extern int proxychains_quiet_mode; extern unsigned int remote_dns_subnet; -internal_ip_lookup_table internal_ips = {0, 0, NULL}; +internal_ip_lookup_table internal_ips = { 0, 0, NULL }; -uint32_t dalias_hash(char* s0) { - unsigned char* s = (void*) s0; +uint32_t dalias_hash(char *s0) { + unsigned char *s = (void *) s0; uint_fast32_t h = 0; - while (*s) { - h = 16*h + *s++; - h ^= h>>24 & 0xf0; + while(*s) { + h = 16 * h + *s++; + h ^= h >> 24 & 0xf0; } return h & 0xfffffff; } @@ -67,8 +67,8 @@ uint32_t index_from_internal_ip(ip_type internalip) { return ret; } -char* string_from_internal_ip(ip_type internalip) { - char* res = NULL; +char *string_from_internal_ip(ip_type internalip) { + char *res = NULL; #ifdef THREAD_SAFE pthread_mutex_lock(&internal_ips_lock); #endif @@ -83,8 +83,9 @@ char* string_from_internal_ip(ip_type internalip) { in_addr_t make_internal_ip(uint32_t index) { ip_type ret; - index++; // so we can start at .0.0.1 - if(index > 0xFFFFFF) return (in_addr_t) -1; + index++; // so we can start at .0.0.1 + if(index > 0xFFFFFF) + return (in_addr_t) - 1; ret.octet[0] = remote_dns_subnet & 0xFF; ret.octet[1] = (index & 0xFF0000) >> 16; ret.octet[2] = (index & 0xFF00) >> 8; @@ -94,8 +95,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; int time_elapsed = 0; @@ -109,10 +109,10 @@ static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) //printf("Retry %d\n", time_remain); ret = poll(fds, nfsd, time_remain); gettimeofday(&tv, NULL); - time_elapsed = ((tv.tv_sec - start_time.tv_sec) * 1000 + (tv.tv_usec - start_time.tv_usec) / 1000); + time_elapsed = ((tv.tv_sec - start_time.tv_sec) * 1000 + (tv.tv_usec - start_time.tv_usec) / 1000); //printf("Time elapsed %d\n", time_elapsed); time_remain = timeout - time_elapsed; - } while (ret == -1 && errno == EINTR && time_remain > 0); + } while(ret == -1 && errno == EINTR && time_remain > 0); //if (ret == -1) //printf("Return %d %d %s\n", ret, errno, strerror(errno)); @@ -120,128 +120,126 @@ static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) } -static void encode_base_64(char* src,char* dest,int max_len) -{ - int n,l,i; - l=strlen(src); - max_len=(max_len-1)/4; - for ( i=0;i> 18) & 077]; - *dest++=base64[(n >> 12) & 077]; - *dest++='='; - *dest++='='; - break; - case 2: - n=src[0] << 16 | src[1] << 8; - *dest++=base64[(n >> 18) & 077]; - *dest++=base64[(n >> 12) & 077]; - *dest++=base64[(n >> 6) & 077]; - *dest++='='; - break; - default: - n=src[0] << 16 | src[1] << 8 | src[2]; - *dest++=base64[(n >> 18) & 077]; - *dest++=base64[(n >> 12) & 077]; - *dest++=base64[(n >> 6) & 077]; - *dest++=base64[n & 077]; + case 0: + break; + case 1: + n = src[0] << 16; + *dest++ = base64[(n >> 18) & 077]; + *dest++ = base64[(n >> 12) & 077]; + *dest++ = '='; + *dest++ = '='; + break; + case 2: + n = src[0] << 16 | src[1] << 8; + *dest++ = base64[(n >> 18) & 077]; + *dest++ = base64[(n >> 12) & 077]; + *dest++ = base64[(n >> 6) & 077]; + *dest++ = '='; + break; + default: + n = src[0] << 16 | src[1] << 8 | src[2]; + *dest++ = base64[(n >> 18) & 077]; + *dest++ = base64[(n >> 12) & 077]; + *dest++ = base64[(n >> 6) & 077]; + *dest++ = base64[n & 077]; } - if (l<3) break; + if(l < 3) + break; } - *dest++=0; + *dest++ = 0; } #define LOG_BUFF 1024*20 -int proxychains_write_log(char *str,...) -{ +int proxychains_write_log(char *str, ...) { char buff[LOG_BUFF]; va_list arglist; - FILE * log_file; - log_file=stderr; - if (!proxychains_quiet_mode) { - va_start(arglist,str); - vsprintf(buff,str,arglist); + FILE *log_file; + log_file = stderr; + if(!proxychains_quiet_mode) { + va_start(arglist, str); + vsprintf(buff, str, arglist); va_end(arglist); - fprintf(log_file,"%s",buff); + fprintf(log_file, "%s", buff); fflush(log_file); } return EXIT_SUCCESS; } -static int write_n_bytes(int fd,char *buff,size_t size) -{ - int i=0; - size_t wrote=0; - for(;;) { - i = write(fd,&buff[wrote],size-wrote); - if(i<=0) +static int write_n_bytes(int fd, char *buff, size_t size) { + int i = 0; + size_t wrote = 0; + for(;;) { + i = write(fd, &buff[wrote], size - wrote); + if(i <= 0) return i; wrote += i; - if(wrote==size) + if(wrote == size) return wrote; } } -static int read_n_bytes(int fd,char *buff, size_t size) -{ +static int read_n_bytes(int fd, char *buff, size_t size) { int ready; size_t i; struct pollfd pfd[1]; - pfd[0].fd=fd; - pfd[0].events=POLLIN; - for(i=0; i < size; i++) { + pfd[0].fd = fd; + pfd[0].events = POLLIN; + 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)) + if(ready != 1 || !(pfd[0].revents & POLLIN) || 1 != read(fd, &buff[i], 1)) return -1; } return (int) size; } -static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) -{ +static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) { int ret, value; socklen_t value_len; - struct pollfd pfd[1]; + struct pollfd pfd[1]; - pfd[0].fd=sock; - pfd[0].events=POLLOUT; + pfd[0].fd = sock; + pfd[0].events = POLLOUT; fcntl(sock, F_SETFL, O_NONBLOCK); - ret = true_connect(sock, addr, len); + ret = true_connect(sock, addr, len); #ifdef DEBUG - if(ret == -1) perror("true_connect"); - printf("\nconnect ret=%d\n",ret); + if(ret == -1) + perror("true_connect"); + printf("\nconnect ret=%d\n", ret); fflush(stdout); #endif - if(ret==-1 && errno==EINPROGRESS) { - ret=poll_retry(pfd,1,tcp_connect_time_out); + if(ret == -1 && errno == EINPROGRESS) { + ret = poll_retry(pfd, 1, tcp_connect_time_out); #ifdef DEBUG - printf("\npoll ret=%d\n",ret);fflush(stdout); + printf("\npoll ret=%d\n", ret); + fflush(stdout); #endif - if(ret == 1) { - value_len=sizeof(socklen_t); - getsockopt(sock,SOL_SOCKET,SO_ERROR,&value,&value_len) ; + if(ret == 1) { + value_len = sizeof(socklen_t); + getsockopt(sock, SOL_SOCKET, SO_ERROR, &value, &value_len); #ifdef DEBUG - printf("\nvalue=%d\n",value);fflush(stdout); + printf("\nvalue=%d\n", value); + fflush(stdout); #endif - if(!value) - ret=0; + if(!value) + ret = 0; else - ret=-1; + ret = -1; } else { - ret=-1; + ret = -1; } } else { - if (ret != 0) - ret=-1; + if(ret != 0) + ret = -1; } fcntl(sock, F_SETFL, !O_NONBLOCK); @@ -250,12 +248,11 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) #define INVALID_INDEX 0xFFFFFFFFU -static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,char *user,char *pass) -{ +static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) { #ifdef DEBUG PDEBUG("tunnel_to()\n"); #endif - char* dns_name = NULL; + 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 @@ -264,9 +261,11 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch // the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127 if(ip.octet[0] == remote_dns_subnet) { dns_name = string_from_internal_ip(ip); - if(!dns_name) goto err; + if(!dns_name) + goto err; dns_len = strlen(dns_name); - if(!dns_len) goto err; + if(!dns_len) + goto err; } size_t ulen = strlen(user); @@ -277,82 +276,76 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch goto err; } - int len; - unsigned char buff[BUFF_SIZE]; - //memset (buff, 0, sizeof(buff)); + 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); + 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)); + 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)]; + 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; + 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); - strcat((char*)buff, "\r\n\r\n"); - } - else - strcat((char*)buff, "\r\n"); + encode_base_64(src, dst, sizeof(dst)); + strcat((char *) buff, "Proxy-Authorization: Basic "); + strcat((char *) buff, dst); + strcat((char *) buff, "\r\n\r\n"); + } else + strcat((char *) buff, "\r\n"); - len = strlen((char*)buff); + len = strlen((char *) buff); - if(len != send(sock, buff, len, 0)) - goto err; - - len = 0 ; - // read header byte by byte. - while(len < BUFF_SIZE) { - if(1 == read_n_bytes(sock, (char*) (buff + len), 1)) - len++; - else + if(len != send(sock, buff, len, 0)) goto err; - if (len > 4 && - buff[len-1]=='\n' && - buff[len-2]=='\r' && - buff[len-3]=='\n' && - buff[len-4]=='\r' ) - break; + + len = 0; + // read header byte by byte. + while(len < BUFF_SIZE) { + if(1 == read_n_bytes(sock, (char *) (buff + len), 1)) + len++; + else + goto err; + if(len > 4 && + buff[len - 1] == '\n' && + buff[len - 2] == '\r' && buff[len - 3] == '\n' && buff[len - 4] == '\r') + break; + } + + // if not ok (200) or response greather than BUFF_SIZE return BLOCKED; + if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0')) + return BLOCKED; + + return SUCCESS; } + break; - // if not ok (200) or response greather than BUFF_SIZE return BLOCKED; - if (len == BUFF_SIZE || - !( buff[9] =='2' && - buff[10]=='0' && - buff[11]=='0' )) - return BLOCKED; - - return SUCCESS; - } - break; - - case SOCKS4_TYPE: { - buff[0] = 4; // socks version - buff[1] = 1; // connect command - memcpy(&buff[2],&port,2); // dest port + case SOCKS4_TYPE:{ + buff[0] = 4; // socks version + buff[1] = 1; // connect command + memcpy(&buff[2], &port, 2); // dest port if(dns_len) { ip.octet[0] = 0; ip.octet[1] = 0; ip.octet[2] = 0; ip.octet[3] = 1; } - memcpy(&buff[4], &ip, 4); // dest host - len = ulen + 1; // username - if(len > 1) - memcpy(&buff[8], user, len); + memcpy(&buff[4], &ip, 4); // dest host + len = ulen + 1; // username + if(len > 1) + memcpy(&buff[8], user, len); else { buff[8] = 0; } @@ -363,120 +356,125 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch len += dns_len + 1; } - if((len + 8) != write_n_bytes(sock, (char*) buff, (8+len))) + if((len + 8) != write_n_bytes(sock, (char *) buff, (8 + len))) goto err; - if(8 != read_n_bytes(sock, (char*)buff, 8)) + if(8 != read_n_bytes(sock, (char *) buff, 8)) goto err; - if (buff[0] != 0 || buff[1] != 90) + if(buff[0] != 0 || buff[1] != 90) return BLOCKED; return SUCCESS; - } - break; - case SOCKS5_TYPE: { - if(user) { - buff[0]=5; //version - buff[1]=2; //nomber of methods - buff[2]=0; // no auth method - buff[3]=2; /// auth method -> username / password - if(4!=write_n_bytes(sock, (char*)buff, 4)) - goto err; - } - else { - buff[0]=5; //version - buff[1]=1; //nomber of methods - buff[2]=0; // no auth method - if(3 != write_n_bytes(sock, (char*) buff, 3)) - goto err; - } - - 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]; - char out[515]; char* cur=out; - int c; - *cur++=1; // version - c = ulen & 0xFF; - *cur++ = c; - memcpy(cur, user, c); - cur += c; - c = passlen & 0xFF; - *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) { - if(in[0] != 1) + } + break; + case SOCKS5_TYPE:{ + if(user) { + buff[0] = 5; //version + buff[1] = 2; //nomber of methods + buff[2] = 0; // no auth method + buff[3] = 2; /// auth method -> username / password + if(4 != write_n_bytes(sock, (char *) buff, 4)) goto err; - else + } else { + buff[0] = 5; //version + buff[1] = 1; //nomber of methods + buff[2] = 0; // no auth method + if(3 != write_n_bytes(sock, (char *) buff, 3)) + goto err; + } + + 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; - } - } - int buff_iter = 0; - 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 - buff_iter += 4; - } else { - buff[buff_iter++] = 3; //dns - buff[buff_iter++] = dns_len & 0xFF; - 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; - - if (buff[0] != 5 || buff[1] != 0) - goto err; - - switch (buff[3]) { - - case 1: len = 4; break; - case 4: len = 16; break; - case 3: len = 0; - if(1 != read_n_bytes(sock, (char*) &len, 1)) + else goto err; - break; - default: + } + + if(buff[1] == 2) { + // authentication + char in[2]; + char out[515]; + char *cur = out; + int c; + *cur++ = 1; // version + c = ulen & 0xFF; + *cur++ = c; + memcpy(cur, user, c); + cur += c; + c = passlen & 0xFF; + *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) { + if(in[0] != 1) + goto err; + else + return BLOCKED; + } + } + int buff_iter = 0; + 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 + buff_iter += 4; + } else { + buff[buff_iter++] = 3; //dns + buff[buff_iter++] = dns_len & 0xFF; + 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; + + if(buff[0] != 5 || buff[1] != 0) + goto err; + + switch (buff[3]) { + + case 1: + len = 4; + break; + case 4: + len = 16; + break; + case 3: + len = 0; + if(1 != read_n_bytes(sock, (char *) &len, 1)) + goto err; + break; + default: + goto err; + } + + if(len + 2 != read_n_bytes(sock, (char *) buff, len + 2)) + goto err; + + return SUCCESS; } - - if(len + 2 != read_n_bytes(sock, (char*) buff, len+2)) - goto err; - - return SUCCESS; - } - break; + break; } err: @@ -488,129 +486,116 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch #define ST "Strict chain" #define RT "Random chain" -static int start_chain(int *fd, proxy_data *pd, char* begin_mark) -{ +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) + *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), - htons(pd->port)); - pd->ps=PLAY_STATE; + proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ", + begin_mark, inet_ntoa(*(struct in_addr *) &pd->ip), htons(pd->port)); + pd->ps = PLAY_STATE; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = (in_addr_t) pd->ip.as_int; addr.sin_port = pd->port; - if (timed_connect (*fd ,(struct sockaddr*)&addr,sizeof(addr))) { - pd->ps=DOWN_STATE; + if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr))) { + pd->ps = DOWN_STATE; goto error1; } - pd->ps=BUSY_STATE; + pd->ps = BUSY_STATE; return SUCCESS; -error1: - proxychains_write_log(TP" timeout\n"); -error: - if(*fd!=-1) + error1: + proxychains_write_log(TP " timeout\n"); + error: + if(*fd != -1) close(*fd); return SOCKET_ERROR; } -static proxy_data * select_proxy(select_type how, - proxy_data *pd, unsigned int proxy_count, unsigned int *offset) -{ - unsigned int i=0, k=0; +static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int proxy_count, unsigned int *offset) { + unsigned int i = 0, k = 0; if(*offset >= proxy_count) return NULL; - switch(how) { + switch (how) { case RANDOMLY: srand(time(NULL)); do { k++; - i = 0 + (unsigned int) (proxy_count * 1.0 * rand()/ - (RAND_MAX + 1.0)); - } while (pd[i].ps != PLAY_STATE && k < proxy_count*100 ); - break; + i = 0 + (unsigned int) (proxy_count * 1.0 * rand() / (RAND_MAX + 1.0)); + } while(pd[i].ps != PLAY_STATE && k < proxy_count * 100); + break; case FIFOLY: - for(i=*offset; i= proxy_count) + if(i >= proxy_count) i = 0; - return (pd[i].ps == PLAY_STATE)? &pd[i] : NULL; + return (pd[i].ps == PLAY_STATE) ? &pd[i] : NULL; } -static void release_all(proxy_data *pd, unsigned int proxy_count) -{ +static void release_all(proxy_data * pd, unsigned int proxy_count) { unsigned int i; - for(i=0; iip.octet[0] == remote_dns_subnet) { hostname = string_from_internal_ip(pto->ip); - if(!hostname) goto usenumericip; + if(!hostname) + goto usenumericip; } else { - usenumericip: - hostname = inet_ntoa(*(struct in_addr*)&pto->ip); + usenumericip: + hostname = inet_ntoa(*(struct in_addr *) &pto->ip); } - proxychains_write_log(TP" %s:%d ", - hostname, - htons(pto->port)); - retcode = - tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, - pfrom->pass); - switch(retcode) { + proxychains_write_log(TP " %s:%d ", hostname, htons(pto->port)); + retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass); + switch (retcode) { case SUCCESS: - pto->ps=BUSY_STATE; + pto->ps = BUSY_STATE; break; case BLOCKED: - pto->ps=BLOCKED_STATE; + pto->ps = BLOCKED_STATE; proxychains_write_log("<--denied\n"); close(ns); break; case SOCKET_ERROR: - pto->ps=DOWN_STATE; + pto->ps = DOWN_STATE; proxychains_write_log("<--timeout\n"); close(ns); break; @@ -618,130 +603,129 @@ 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, - 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) { proxy_data p4; - proxy_data *p1,*p2,*p3; - int ns=-1; - unsigned int offset=0; - unsigned int alive_count=0; - unsigned int curr_len=0; + proxy_data *p1, *p2, *p3; + int ns = -1; + unsigned int offset = 0; + unsigned int alive_count = 0; + unsigned int curr_len = 0; - p3=&p4; + p3 = &p4; #ifdef DEBUG PDEBUG("connect_proxy_chain\n"); #endif -again: + again: - switch(ct) { + switch (ct) { case DYNAMIC_TYPE: - alive_count = calc_alive(pd,proxy_count); - offset = 0; - do { - if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset))) - goto error_more; - } while(SUCCESS!=start_chain(&ns,p1,DT) && offset < proxy_count); - for(;;) { - p2=select_proxy(FIFOLY,pd,proxy_count,&offset); - if(!p2) - break; - if(SUCCESS!=chain_step(ns,p1,p2)) { - #ifdef DEBUG - PDEBUG("GOTO AGAIN 1\n"); - #endif - goto again; + alive_count = calc_alive(pd, proxy_count); + offset = 0; + do { + if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) + goto error_more; + } while(SUCCESS != start_chain(&ns, p1, DT) && offset < proxy_count); + for(;;) { + p2 = select_proxy(FIFOLY, pd, proxy_count, &offset); + if(!p2) + break; + if(SUCCESS != chain_step(ns, p1, p2)) { +#ifdef DEBUG + PDEBUG("GOTO AGAIN 1\n"); +#endif + goto again; + } + p1 = p2; } - p1=p2; - } - //proxychains_write_log(TP); - p3->ip = target_ip; - p3->port = target_port; - if(SUCCESS != chain_step(ns, p1, p3)) - goto error; - break; + //proxychains_write_log(TP); + p3->ip = target_ip; + p3->port = target_port; + if(SUCCESS != chain_step(ns, p1, p3)) + goto error; + break; - case STRICT_TYPE: - alive_count = calc_alive(pd, proxy_count); - offset = 0; - if(!(p1=select_proxy(FIFOLY, pd, proxy_count, &offset))) { - #ifdef DEBUG - PDEBUG("select_proxy failed\n"); - #endif - goto error_strict; - } - if(SUCCESS!=start_chain(&ns, p1, ST)) { - #ifdef DEBUG - PDEBUG("start_chain failed\n"); - #endif - goto error_strict; - } - while(offset < proxy_count) { - if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset))) - break; - if(SUCCESS!=chain_step(ns, p1, p2)) { - #ifdef DEBUG - PDEBUG("chain_step failed\n"); - #endif + case STRICT_TYPE: + alive_count = calc_alive(pd, proxy_count); + offset = 0; + if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) { +#ifdef DEBUG + PDEBUG("select_proxy failed\n"); +#endif goto error_strict; } - p1 = p2; - } - //proxychains_write_log(TP); - p3->ip = target_ip; - p3->port = target_port; - if(SUCCESS!=chain_step(ns, p1, p3)) - goto error; - break; - - case RANDOM_TYPE: - alive_count=calc_alive(pd,proxy_count); - if(alive_countip = target_ip; - p3->port = target_port; - if(SUCCESS!=chain_step(ns,p1,p3)) - goto error; + while(offset < proxy_count) { + if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset))) + break; + if(SUCCESS != chain_step(ns, p1, p2)) { +#ifdef DEBUG + PDEBUG("chain_step failed\n"); +#endif + goto error_strict; + } + p1 = p2; + } + //proxychains_write_log(TP); + p3->ip = target_ip; + p3->port = target_port; + if(SUCCESS != chain_step(ns, p1, p3)) + goto error; + break; + + case RANDOM_TYPE: + alive_count = calc_alive(pd, proxy_count); + if(alive_count < max_chain) + goto error_more; + curr_len = offset = 0; + do { + if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset))) + goto error_more; + } while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain); + while(++curr_len < max_chain) { + if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset))) + goto error_more; + if(SUCCESS != chain_step(ns, p1, p2)) { +#ifdef DEBUG + PDEBUG("GOTO AGAIN 2\n"); +#endif + goto again; + } + p1 = p2; + } + //proxychains_write_log(TP); + p3->ip = target_ip; + p3->port = target_port; + if(SUCCESS != chain_step(ns, p1, p3)) + goto error; } - proxychains_write_log(TP" OK\n"); - dup2(ns,sock); + proxychains_write_log(TP " OK\n"); + dup2(ns, sock); close(ns); return 0; -error: - if(ns!=-1) + error: + if(ns != -1) close(ns); - errno = ECONNREFUSED; // for nmap ;) + errno = ECONNREFUSED; // for nmap ;) return -1; -error_more: + error_more: proxychains_write_log("\n!!!need more proxies!!!\n"); -error_strict: - #ifdef DEBUG + error_strict: +#ifdef DEBUG PDEBUG("error\n"); - #endif - release_all(pd,proxy_count); - if(ns!=-1) +#endif + release_all(pd, proxy_count); + if(ns != -1) close(ns); errno = ETIMEDOUT; return -1; @@ -750,43 +734,42 @@ error_strict: // TODO: all those buffers aren't threadsafe, but since no memory allocation happens there shouldnt be any segfaults static struct hostent hostent_space; static in_addr_t resolved_addr; -static char* resolved_addr_p[2]; -static char addr_name[1024*8]; -static const ip_type local_host = {{127, 0, 0, 1}}; -struct hostent* proxy_gethostbyname(const char *name) -{ +static char *resolved_addr_p[2]; +static char addr_name[1024 * 8]; +static const ip_type local_host = { {127, 0, 0, 1} }; +struct hostent *proxy_gethostbyname(const char *name) { char buff[256]; uint32_t i, hash; // yep, new_mem never gets freed. once you passed a fake ip to the client, you can't "retreat" it - void* new_mem; + void *new_mem; size_t l; - struct hostent* hp; + struct hostent *hp; - resolved_addr_p[0] = (char*) &resolved_addr; + 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)); + gethostname(buff, sizeof(buff)); if(!strcmp(buff, name)) { resolved_addr = inet_addr(buff); - if (resolved_addr == (in_addr_t) (-1)) + 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)) + while((hp = gethostent())) + if(!strcmp(hp->h_name, name)) return hp; - hash = dalias_hash((char*) name); + hash = dalias_hash((char *) name); #ifdef THREAD_SAFE pthread_mutex_lock(&internal_ips_lock); @@ -794,7 +777,7 @@ struct hostent* proxy_gethostbyname(const char *name) // see if we already have this dns entry saved. if(internal_ips.counter) { - for( i = 0; i < internal_ips.counter; i++) { + for(i = 0; i < internal_ips.counter; i++) { if(internal_ips.list[i]->hash == hash && !strcmp(name, internal_ips.list[i]->string)) { resolved_addr = make_internal_ip(i); PDEBUG("got cached ip for %s\n", name); @@ -802,23 +785,23 @@ struct hostent* proxy_gethostbyname(const char *name) } } } - // grow list if needed. if(internal_ips.capa < internal_ips.counter + 1) { PDEBUG("realloc\n"); - new_mem = realloc(internal_ips.list, (internal_ips.capa + 16) * sizeof(void*)); + new_mem = realloc(internal_ips.list, (internal_ips.capa + 16) * sizeof(void *)); if(new_mem) { internal_ips.capa += 16; internal_ips.list = new_mem; } else { - oom: + oom: proxychains_write_log("out of mem\n"); goto err_plus_unlock; } } resolved_addr = make_internal_ip(internal_ips.counter); - if(resolved_addr == (in_addr_t) -1) goto err_plus_unlock; + if(resolved_addr == (in_addr_t) - 1) + goto err_plus_unlock; l = strlen(name); new_mem = malloc(sizeof(string_hash_tuple) + l + 1); @@ -829,7 +812,7 @@ struct hostent* proxy_gethostbyname(const char *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); + 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); @@ -845,25 +828,22 @@ struct hostent* proxy_gethostbyname(const char *name) strncpy(addr_name, name, sizeof(addr_name)); hostent_space.h_name = addr_name; - hostent_space.h_length = sizeof (in_addr_t); + hostent_space.h_length = sizeof(in_addr_t); return &hostent_space; -err_plus_unlock: + err_plus_unlock: #ifdef THREAD_SAFE pthread_mutex_unlock(&internal_ips_lock); #endif return NULL; } -int proxy_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ +int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct servent *se = NULL; struct hostent *hp = NULL; - struct sockaddr* sockaddr_space = NULL; - struct addrinfo* addrinfo_space = NULL; + struct sockaddr *sockaddr_space = NULL; + struct addrinfo *addrinfo_space = NULL; -// printf("proxy_getaddrinfo node %s service %s\n",node,service); +// printf("proxy_getaddrinfo node %s service %s\n",node,service); addrinfo_space = malloc(sizeof(struct addrinfo)); if(!addrinfo_space) goto err1; @@ -872,28 +852,25 @@ int proxy_getaddrinfo(const char *node, const char *service, goto err2; memset(sockaddr_space, 0, sizeof(*sockaddr_space)); memset(addrinfo_space, 0, sizeof(*addrinfo_space)); - if (node && - !inet_aton(node,&((struct sockaddr_in*)sockaddr_space)->sin_addr)) { + if(node && !inet_aton(node, &((struct sockaddr_in *) sockaddr_space)->sin_addr)) { hp = proxy_gethostbyname(node); - if (hp) - memcpy(&((struct sockaddr_in*)sockaddr_space)->sin_addr, - *(hp->h_addr_list), - sizeof(in_addr_t)); + if(hp) + memcpy(&((struct sockaddr_in *) sockaddr_space)->sin_addr, + *(hp->h_addr_list), sizeof(in_addr_t)); else goto err3; } - if (service) + if(service) se = getservbyname(service, NULL); - if (!se) { - ((struct sockaddr_in*)sockaddr_space)->sin_port = - htons(atoi(service?:"0")); + if(!se) { + ((struct sockaddr_in *) sockaddr_space)->sin_port = htons(atoi(service ? : "0")); } else - ((struct sockaddr_in*)sockaddr_space)->sin_port = se->s_port; + ((struct sockaddr_in *) sockaddr_space)->sin_port = se->s_port; *res = addrinfo_space; (*res)->ai_addr = sockaddr_space; - if (node) + if(node) strcpy(addr_name, node); (*res)->ai_canonname = addr_name; (*res)->ai_next = NULL; @@ -903,12 +880,12 @@ int proxy_getaddrinfo(const char *node, const char *service, (*res)->ai_protocol = hints->ai_protocol; (*res)->ai_addrlen = sizeof(*sockaddr_space); goto out; -err3: + err3: free(sockaddr_space); -err2: + err2: free(addrinfo_space); -err1: + err1: return 1; -out: + out: return 0; } diff --git a/src/libproxychains.c b/src/libproxychains.c index c1f8c15..4e15319 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -57,12 +57,10 @@ localaddr_arg localnet_addr[MAX_LOCALNET]; size_t num_localnet_addr = 0; unsigned int remote_dns_subnet = 224; -static inline void get_chain_data(proxy_data *pd, unsigned int *proxy_count, - chain_type *ct); +static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct); static void init_lib(void); -static void init_lib(void) -{ +static void init_lib(void) { #ifdef THREAD_SAFE pthread_mutex_init(&internal_ips_lock, NULL); #endif @@ -73,114 +71,96 @@ static void init_lib(void) true_connect = (connect_t) dlsym(RTLD_NEXT, "connect"); - if (!true_connect) { + if(!true_connect) { fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'connect'" - " real addr %p wrapped addr %p\n", - true_connect, connect); - #endif +#ifdef DEBUG + PDEBUG("loaded symbol 'connect'" " real addr %p wrapped addr %p\n", true_connect, connect); +#endif } - if(connect==true_connect) { - #ifdef DEBUG + if(connect == true_connect) { +#ifdef DEBUG PDEBUG("circular reference detected, aborting!\n"); - #endif +#endif abort(); } true_gethostbyname = (gethostbyname_t) - dlsym(RTLD_NEXT, "gethostbyname"); + dlsym(RTLD_NEXT, "gethostbyname"); - if (!true_gethostbyname) { - fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", - dlerror()); + if(!true_gethostbyname) { + fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'gethostbyname'" - " real addr %p wrapped addr %p\n", - true_gethostbyname, gethostbyname); - #endif +#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"); + dlsym(RTLD_NEXT, "getaddrinfo"); - if (!true_getaddrinfo) { - fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", - dlerror()); + if(!true_getaddrinfo) { + fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'getaddrinfo'" - " real addr %p wrapped addr %p\n", - true_getaddrinfo, getaddrinfo); - #endif +#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"); + dlsym(RTLD_NEXT, "freeaddrinfo"); - if (!true_freeaddrinfo) { - fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", - dlerror()); + if(!true_freeaddrinfo) { + fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'freeaddrinfo'" - " real addr %p wrapped addr %p\n", - true_freeaddrinfo, freeaddrinfo); - #endif +#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"); + dlsym(RTLD_NEXT, "gethostbyaddr"); - if (!true_gethostbyaddr) { - fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", - dlerror()); + if(!true_gethostbyaddr) { + fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'gethostbyaddr'" - " real addr %p wrapped addr %p\n", - true_gethostbyaddr, gethostbyaddr); - #endif +#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"); + dlsym(RTLD_NEXT, "getnameinfo"); - if (!true_getnameinfo) { - fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", - dlerror()); + if(!true_getnameinfo) { + fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", dlerror()); exit(1); } else { - #ifdef DEBUG - PDEBUG( "loaded symbol 'getnameinfo'" - " real addr %p wrapped addr %p\n", - true_getnameinfo, getnameinfo); - #endif +#ifdef DEBUG + PDEBUG("loaded symbol 'getnameinfo'" " real addr %p wrapped addr %p\n", true_getnameinfo, getnameinfo); +#endif } init_l = 1; } -static inline 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]; +static inline 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; char local_in_addr_port[32]; char local_in_addr[32], local_in_port[32], local_netmask[32]; - FILE* file; + FILE *file; if(proxychains_got_chain_data) - return; + return; //Some defaults - tcp_read_time_out = 4*1000; - tcp_connect_time_out = 10*1000; + tcp_read_time_out = 4 * 1000; + tcp_connect_time_out = 10 * 1000; *ct = DYNAMIC_TYPE; /* @@ -189,119 +169,116 @@ static inline void get_chain_data( */ env = getenv(PROXYCHAINS_CONF_FILE_ENV_VAR); - snprintf(buff,256,"%s/.proxychains/proxychains.conf",getenv("HOME")); + snprintf(buff, 256, "%s/.proxychains/proxychains.conf", getenv("HOME")); - if(!env || (!(file=fopen(env,"r")))) - if(!(file=fopen("./proxychains.conf","r"))) - if(!(file=fopen(buff,"r"))) - if(!(file=fopen("/etc/proxychains.conf","r"))) - { - perror("Can't locate proxychains.conf"); - exit(1); - } + if(!env || (!(file = fopen(env, "r")))) + if(!(file = fopen("./proxychains.conf", "r"))) + if(!(file = fopen(buff, "r"))) + if(!(file = fopen("/etc/proxychains.conf", "r"))) { + perror("Can't locate proxychains.conf"); + exit(1); + } env = getenv(PROXYCHAINS_QUIET_MODE_ENV_VAR); - if(env && *env == '1') proxychains_quiet_mode = 1; + if(env && *env == '1') + proxychains_quiet_mode = 1; - while(fgets(buff,sizeof(buff),file)) { - if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') { + while(fgets(buff, sizeof(buff), file)) { + 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); + 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); + pd[count].port = htons((unsigned short) port_n); - if(!strcmp(type,"http")) { + if(!strcmp(type, "http")) { pd[count].pt = HTTP_TYPE; - } else if(!strcmp(type,"socks4")) { + } else if(!strcmp(type, "socks4")) { pd[count].pt = SOCKS4_TYPE; - } else if(!strcmp(type,"socks5")) { + } else if(!strcmp(type, "socks5")) { pd[count].pt = SOCKS5_TYPE; } else continue; - if(pd[count].ip.as_int && port_n && - pd[count].ip.as_int != (uint32_t) -1) - if(++count==MAX_CHAIN) + if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) - 1) + if(++count == MAX_CHAIN) break; - } else { - if(strstr(buff,"[ProxyList]")) { - list=1; + } else { + if(strstr(buff, "[ProxyList]")) { + list = 1; } else if(strstr(buff, "random_chain")) { - *ct=RANDOM_TYPE; + *ct = RANDOM_TYPE; } else if(strstr(buff, "strict_chain")) { - *ct=STRICT_TYPE; + *ct = STRICT_TYPE; } else if(strstr(buff, "dynamic_chain")) { - *ct=DYNAMIC_TYPE; - } else if(strstr(buff,"tcp_read_time_out")){ + *ct = DYNAMIC_TYPE; + } else if(strstr(buff, "tcp_read_time_out")) { sscanf(buff, "%s %d", user, &tcp_read_time_out); - } else if(strstr(buff,"tcp_connect_time_out")){ + } else if(strstr(buff, "tcp_connect_time_out")) { sscanf(buff, "%s %d", user, &tcp_connect_time_out); - } else if(strstr(buff,"remote_dns_subnet")){ + } else if(strstr(buff, "remote_dns_subnet")) { sscanf(buff, "%s %d", user, &remote_dns_subnet); if(remote_dns_subnet >= 256) { - fprintf(stderr, "remote_dns_subnet: invalid value. requires a number between 0 and 255.\n"); + fprintf(stderr, + "remote_dns_subnet: invalid value. requires a number between 0 and 255.\n"); exit(1); } } else if(strstr(buff, "localnet")) { - if (sscanf(buff, "%s %21[^/]/%15s", user, - local_in_addr_port, local_netmask) < 3) { + if(sscanf(buff, "%s %21[^/]/%15s", user, local_in_addr_port, local_netmask) < 3) { fprintf(stderr, "localnet format error"); exit(1); } /* clean previously used buffer */ - memset(local_in_port, 0, - sizeof(local_in_port) / sizeof(local_in_port[0])); + memset(local_in_port, 0, sizeof(local_in_port) / sizeof(local_in_port[0])); - if (sscanf(local_in_addr_port, "%15[^:]:%5s", - local_in_addr, local_in_port) < 2) { - PDEBUG("added localnet: netaddr=%s, port=%s\n", - local_in_addr, local_netmask); + if(sscanf(local_in_addr_port, "%15[^:]:%5s", local_in_addr, local_in_port) < 2) { + PDEBUG("added localnet: netaddr=%s, port=%s\n", + local_in_addr, local_netmask); } else { - PDEBUG("added localnet: netaddr=%s, port=%s, netmask=%s\n", - local_in_addr, local_in_port, local_netmask); + PDEBUG("added localnet: netaddr=%s, port=%s, netmask=%s\n", + local_in_addr, local_in_port, local_netmask); } - if (num_localnet_addr < MAX_LOCALNET) - { + if(num_localnet_addr < MAX_LOCALNET) { int error; - error = inet_pton(AF_INET, local_in_addr, &localnet_addr[num_localnet_addr].in_addr); - if (error <= 0) - { + error = + inet_pton(AF_INET, local_in_addr, + &localnet_addr[num_localnet_addr].in_addr); + if(error <= 0) { fprintf(stderr, "localnet address error\n"); exit(1); } - error = inet_pton(AF_INET, local_netmask, &localnet_addr[num_localnet_addr].netmask); - if (error <= 0) - { + error = + inet_pton(AF_INET, local_netmask, + &localnet_addr[num_localnet_addr].netmask); + if(error <= 0) { fprintf(stderr, "localnet netmask error\n"); exit(1); } - if (local_in_port[0]) { - localnet_addr[num_localnet_addr].port = (short)atoi(local_in_port); + if(local_in_port[0]) { + localnet_addr[num_localnet_addr].port = + (short) atoi(local_in_port); } else { localnet_addr[num_localnet_addr].port = 0; } ++num_localnet_addr; - } - else - { + } else { fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET); } - } else if(strstr(buff,"chain_len")){ - char *pc;int len; - pc=strchr(buff,'='); - len=atoi(++pc); - proxychains_max_chain=(len?len:1); - } else if(strstr(buff,"quiet_mode")){ - proxychains_quiet_mode=1; - } else if(strstr(buff,"proxy_dns")){ - proxychains_resolver=1; + } else if(strstr(buff, "chain_len")) { + char *pc; + int len; + pc = strchr(buff, '='); + len = atoi(++pc); + proxychains_max_chain = (len ? len : 1); + } else if(strstr(buff, "quiet_mode")) { + proxychains_quiet_mode = 1; + } else if(strstr(buff, "proxy_dns")) { + proxychains_resolver = 1; } } } @@ -313,9 +290,8 @@ static inline void get_chain_data( -int connect (int sock, const struct sockaddr *addr, unsigned int len) -{ - int socktype=0, flags=0, ret=0; +int connect(int sock, const struct sockaddr *addr, unsigned int len) { + int socktype = 0, flags = 0, ret = 0; socklen_t optlen = 0; ip_type dest_ip; #ifdef DEBUG @@ -327,58 +303,52 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len) if(!init_l) init_lib(); - optlen=sizeof(socktype); - getsockopt(sock,SOL_SOCKET,SO_TYPE,&socktype,&optlen); - if (! (SOCKFAMILY(*addr)==AF_INET && socktype==SOCK_STREAM)) - return true_connect(sock,addr,len); + optlen = sizeof(socktype); + getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen); + if(!(SOCKFAMILY(*addr) == AF_INET && socktype == SOCK_STREAM)) + return true_connect(sock, addr, len); - p_addr_in = &((struct sockaddr_in *)addr)->sin_addr; - port = ntohs(((struct sockaddr_in *)addr)->sin_port); + p_addr_in = &((struct sockaddr_in *) addr)->sin_addr; + port = ntohs(((struct sockaddr_in *) addr)->sin_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("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)) - { - if (localnet_addr[i].port || localnet_addr[i].port == port) { + 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)) { + if(localnet_addr[i].port || localnet_addr[i].port == port) { PDEBUG("accessing localnet using true_connect\n"); - return true_connect(sock,addr,len); + return true_connect(sock, addr, len); } } } flags = fcntl(sock, F_GETFL, 0); if(flags & O_NONBLOCK) - fcntl(sock, F_SETFL, !O_NONBLOCK); + fcntl(sock, F_SETFL, !O_NONBLOCK); dest_ip.as_int = SOCKADDR(*addr); - ret = connect_proxy_chain( - sock, - dest_ip, - SOCKPORT(*addr), - proxychains_pd, - proxychains_proxy_count, - proxychains_ct, - proxychains_max_chain ); + ret = connect_proxy_chain(sock, + dest_ip, + SOCKPORT(*addr), + proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain); fcntl(sock, F_SETFL, flags); if(ret != SUCCESS) - errno = ECONNREFUSED; + errno = ECONNREFUSED; return ret; } -struct hostent *gethostbyname(const char *name) -{ +struct hostent *gethostbyname(const char *name) { if(!init_l) init_lib(); - PDEBUG("gethostbyname: %s\n",name); + PDEBUG("gethostbyname: %s\n", name); if(proxychains_resolver) return proxy_gethostbyname(name); @@ -388,16 +358,13 @@ struct hostent *gethostbyname(const char *name) return NULL; } -int getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ +int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { int ret = 0; if(!init_l) init_lib(); - PDEBUG("getaddrinfo: %s %s\n",node ,service); + PDEBUG("getaddrinfo: %s %s\n", node, service); if(proxychains_resolver) ret = proxy_getaddrinfo(node, service, hints, res); @@ -407,12 +374,11 @@ int getaddrinfo(const char *node, const char *service, return ret; } -void freeaddrinfo(struct addrinfo *res) -{ +void freeaddrinfo(struct addrinfo *res) { if(!init_l) init_lib(); - PDEBUG("freeaddrinfo %p \n",res); + PDEBUG("freeaddrinfo %p \n", res); if(!proxychains_resolver) true_freeaddrinfo(res); @@ -422,18 +388,15 @@ void freeaddrinfo(struct addrinfo *res) } return; } + // work around a buggy prototype in GLIBC. according to the bugtracker it has been fixed in git at 02 May 2011. // 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) +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) +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; @@ -444,44 +407,44 @@ int getnameinfo (const struct sockaddr * sa, PDEBUG("getnameinfo: %s %s\n", host, serv); if(!proxychains_resolver) { - ret = true_getnameinfo(sa,salen,host,hostlen, - serv,servlen,flags); + ret = true_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } else { if(hostlen) - strncpy(host, inet_ntoa(SOCKADDR_2(*sa)),hostlen); + strncpy(host, inet_ntoa(SOCKADDR_2(*sa)), hostlen); if(servlen) - snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa))); + 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; +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) -{ +struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) { static char buf[16]; static char ipv4[4]; - static char* list[2]; + static char *list[2]; static struct hostent he; if(!init_l) @@ -490,11 +453,12 @@ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) PDEBUG("TODO: proper gethostbyaddr hook\n"); if(!proxychains_resolver) - return true_gethostbyaddr(addr,len,type); + 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; @@ -503,9 +467,8 @@ 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); + pc_stringfromipv4((unsigned char *) addr, buf); return &he; } return NULL; } - diff --git a/src/main.c b/src/main.c index b5259f5..c104560 100644 --- a/src/main.c +++ b/src/main.c @@ -28,24 +28,24 @@ #include "common.h" -static int usage(char** argv) { - printf( "\nUsage:\t%s -q -f config_file program_name [arguments]\n" - "\t-q makes proxychains quiet - this overrides the config setting\n" - "\t-t allows to manually specify a configfile to use\n" - "\tfor example : proxychains telnet somehost.com\n" - "More help in README file\n\n", argv[0]); +static int usage(char **argv) { + printf("\nUsage:\t%s -q -f config_file program_name [arguments]\n" + "\t-q makes proxychains quiet - this overrides the config setting\n" + "\t-t allows to manually specify a configfile to use\n" + "\tfor example : proxychains telnet somehost.com\n" "More help in README file\n\n", argv[0]); return EXIT_FAILURE; } -int check_path(char* path) { - if(!path) return 0; +int check_path(char *path) { + if(!path) + return 0; return access(path, R_OK) != -1; } -static const char* dll_name = "libproxychains4.so"; +static const char *dll_name = "libproxychains4.so"; static char own_dir[256]; -static const char* dll_dirs[] = { +static const char *dll_dirs[] = { ".", own_dir, LIB_DIR, @@ -56,9 +56,10 @@ static const char* dll_dirs[] = { NULL }; -static void set_own_dir(const char* argv0) { +static void set_own_dir(const char *argv0) { size_t l = strlen(argv0); - while(l && argv0[l - 1] != '/') l--; + while(l && argv0[l - 1] != '/') + l--; if(l == 0) memcpy(own_dir, ".", 2); else { @@ -76,7 +77,7 @@ int main(int argc, char *argv[]) { int start_argv = 1; int quiet = 0; size_t i; - const char* prefix = NULL; + const char *prefix = NULL; for(i = 0; i < MAX_COMMANDLINE_FLAGS; i++) { if(start_argv < argc && argv[start_argv][0] == '-') { @@ -96,41 +97,48 @@ int main(int argc, char *argv[]) { break; } - if(start_argv >= argc) return usage(argv); + if(start_argv >= argc) + return usage(argv); /* check if path of config file has not been passed via command line */ if(!path) { // priority 1: env var PROXYCHAINS_CONF_FILE path = getenv(PROXYCHAINS_CONF_FILE_ENV_VAR); - if(check_path(path)) goto have; + 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; + 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; + if(check_path(path)) + goto have; // priority 4: /etc/proxychains.conf path = "/etc/proxychains.conf"; - if(check_path(path)) goto have; + 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); + 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); + if(quiet) + setenv(PROXYCHAINS_QUIET_MODE_ENV_VAR, "1", 1); // search DLL @@ -150,7 +158,8 @@ int main(int argc, char *argv[]) { fprintf(stderr, "couldnt locate %s\n", dll_name); return EXIT_FAILURE; } - if(!quiet) fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name); + if(!quiet) + fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name); snprintf(buf, sizeof(buf), "LD_PRELOAD=%s/%s", prefix, dll_name);