mirror of
				https://github.com/rofl0r/proxychains-ng.git
				synced 2025-11-04 09:06:05 +00:00 
			
		
		
		
	implemented remote proxy dns lookup via use of reserved ip ranges and a lookup table
This commit is contained in:
		
							
								
								
									
										358
									
								
								src/core.c
									
									
									
									
									
								
							
							
						
						
									
										358
									
								
								src/core.c
									
									
									
									
									
								
							@@ -34,11 +34,41 @@
 | 
				
			|||||||
#include <sys/time.h>
 | 
					#include <sys/time.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include "core.h"
 | 
					#include "core.h"
 | 
				
			||||||
 | 
					#include "common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int tcp_read_time_out;
 | 
					extern int tcp_read_time_out;
 | 
				
			||||||
extern int tcp_connect_time_out;
 | 
					extern int tcp_connect_time_out;
 | 
				
			||||||
extern int proxychains_quiet_mode;
 | 
					extern int proxychains_quiet_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					internal_ip_lookup_table internal_ips = {0, 0, NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dalias_hash(char* s) {
 | 
				
			||||||
 | 
						uint_fast32_t h = 0;
 | 
				
			||||||
 | 
						while (*s) {
 | 
				
			||||||
 | 
							h = 16*h + *s++;
 | 
				
			||||||
 | 
							h ^= h>>24 & 0xf0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return h & 0xfffffff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t index_from_internal_ip(ip_type internalip) {
 | 
				
			||||||
 | 
						ip_type tmp = internalip;
 | 
				
			||||||
 | 
						uint32_t ret;
 | 
				
			||||||
 | 
						ret = tmp.octet[3] + tmp.octet[2] << 8 + tmp.octet[1] << 16;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in_addr_t make_internal_ip(uint32_t index) {
 | 
				
			||||||
 | 
						ip_type ret;
 | 
				
			||||||
 | 
						if(index > 0xFFFFFF) return (in_addr_t) -1;
 | 
				
			||||||
 | 
						ret.octet[0] = 224;
 | 
				
			||||||
 | 
						ret.octet[1] = (index & 0xFF0000) >> 16;
 | 
				
			||||||
 | 
						ret.octet[2] = (index & 0xFF00) >> 8;
 | 
				
			||||||
 | 
						ret.octet[3] = index & 0xFF;
 | 
				
			||||||
 | 
						return (in_addr_t) ret.as_int;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
					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) 
 | 
				
			||||||
@@ -52,16 +82,15 @@ static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	gettimeofday(&start_time, NULL);
 | 
						gettimeofday(&start_time, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  do 
 | 
						do {
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
		//printf("Retry %d\n", time_remain);
 | 
							//printf("Retry %d\n", time_remain);
 | 
				
			||||||
		ret = poll(fds, nfsd, time_remain);
 | 
							ret = poll(fds, nfsd, time_remain);
 | 
				
			||||||
		gettimeofday(&tv, NULL);
 | 
							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);
 | 
							//printf("Time elapsed %d\n", time_elapsed);
 | 
				
			||||||
		time_remain = timeout - 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)
 | 
						//if (ret == -1)
 | 
				
			||||||
	//printf("Return %d %d %s\n", ret, errno, strerror(errno));
 | 
						//printf("Return %d %d %s\n", ret, errno, strerror(errno));
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
@@ -112,15 +141,13 @@ int proxychains_write_log(char *str,...)
 | 
				
			|||||||
	va_list arglist;
 | 
						va_list arglist;
 | 
				
			||||||
	FILE * log_file;
 | 
						FILE * log_file;
 | 
				
			||||||
	log_file=stderr;
 | 
						log_file=stderr;
 | 
				
			||||||
    if (!proxychains_quiet_mode)
 | 
						if (!proxychains_quiet_mode) {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
		va_start(arglist,str);
 | 
							va_start(arglist,str);
 | 
				
			||||||
		vsprintf(buff,str,arglist);
 | 
							vsprintf(buff,str,arglist);
 | 
				
			||||||
		va_end(arglist);
 | 
							va_end(arglist);
 | 
				
			||||||
		fprintf(log_file,"%s",buff);
 | 
							fprintf(log_file,"%s",buff);
 | 
				
			||||||
		fflush(log_file);
 | 
							fflush(log_file);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return EXIT_SUCCESS;
 | 
						return EXIT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,28 +225,53 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len)
 | 
				
			|||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type pt,char *user,char *pass)
 | 
					
 | 
				
			||||||
 | 
					#define INVALID_INDEX 0xFFFFFFFFU
 | 
				
			||||||
 | 
					static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,char *user,char *pass)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	PDEBUG("tunnel_to()\n");
 | 
						PDEBUG("tunnel_to()\n");
 | 
				
			||||||
#endif	
 | 
					#endif	
 | 
				
			||||||
 | 
						uint32_t index = INVALID_INDEX;
 | 
				
			||||||
 | 
						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.)
 | 
				
			||||||
 | 
						if(ip.octet[0] == 224) {
 | 
				
			||||||
 | 
							index = index_from_internal_ip(ip);
 | 
				
			||||||
 | 
							if(index > internal_ips.counter) goto err;
 | 
				
			||||||
 | 
							dns_name = internal_ips.list[index]->string;
 | 
				
			||||||
 | 
							if(!dns_name) goto err;
 | 
				
			||||||
 | 
							dns_len = strlen(dns_name);
 | 
				
			||||||
 | 
							if(!dns_len) goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						size_t ulen = strlen(user);
 | 
				
			||||||
 | 
						size_t passlen = strlen(pass);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
        int len;
 | 
					        int len;
 | 
				
			||||||
        char buff[BUFF_SIZE];
 | 
					        unsigned char buff[BUFF_SIZE];
 | 
				
			||||||
        memset (buff, 0, sizeof(buff));
 | 
					        //memset (buff, 0, sizeof(buff));
 | 
				
			||||||
        switch(pt)
 | 
						
 | 
				
			||||||
        {
 | 
						switch(pt) {
 | 
				
			||||||
        	case HTTP_TYPE:
 | 
							case HTTP_TYPE: {
 | 
				
			||||||
         		{
 | 
								if(!dns_len)
 | 
				
			||||||
             		sprintf(buff,"CONNECT %s:%d HTTP/1.0\r\n",
 | 
									snprintf(buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n",
 | 
				
			||||||
			        inet_ntoa( * (struct in_addr *) &ip),
 | 
										inet_ntoa( * (struct in_addr *) &ip.as_int), ntohs(port));
 | 
				
			||||||
			        ntohs(port));
 | 
								else 
 | 
				
			||||||
 | 
									snprintf(buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n", dns_name, ntohs(port));
 | 
				
			||||||
 | 
								
 | 
				
			||||||
			if (user[0])
 | 
								if (user[0])
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				char src[256];
 | 
									char src[256];
 | 
				
			||||||
				char dst[512];
 | 
									char dst[512];
 | 
				
			||||||
					strcpy(src,user);
 | 
									memcpy(src, user, ulen);
 | 
				
			||||||
					strcat(src,":");
 | 
									memcpy(src + ulen, ":", 1);
 | 
				
			||||||
					strcat(src,pass);
 | 
									memcpy(src + ulen + 1, pass, passlen);
 | 
				
			||||||
 | 
									src[ulen + 1 + passlen] = 0;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
				encode_base_64(src,dst,512);
 | 
									encode_base_64(src,dst,512);
 | 
				
			||||||
				strcat(buff,"Proxy-Authorization: Basic ");
 | 
									strcat(buff,"Proxy-Authorization: Basic ");
 | 
				
			||||||
				strcat(buff,dst);
 | 
									strcat(buff,dst);
 | 
				
			||||||
@@ -231,17 +283,16 @@ static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type
 | 
				
			|||||||
			len = strlen(buff);
 | 
								len = strlen(buff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(len != send(sock, buff, len, 0))
 | 
								if(len != send(sock, buff, len, 0))
 | 
				
			||||||
			                return SOCKET_ERROR;
 | 
									goto err;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
			memset(buff, 0, sizeof(buff));
 | 
								memset(buff, 0, sizeof(buff));
 | 
				
			||||||
			len = 0 ;
 | 
								len = 0 ;
 | 
				
			||||||
			// read header byte by byte.
 | 
								// read header byte by byte.
 | 
				
			||||||
			       while(len<BUFF_SIZE)
 | 
								while(len < BUFF_SIZE) {
 | 
				
			||||||
			       {
 | 
					 | 
				
			||||||
				if(1 == read_n_bytes(sock, buff+len, 1))
 | 
									if(1 == read_n_bytes(sock, buff+len, 1))
 | 
				
			||||||
					len++;
 | 
										len++;
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
			                        return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
				if (len > 4 &&
 | 
									if (len > 4 &&
 | 
				
			||||||
					buff[len-1]=='\n'  &&
 | 
										buff[len-1]=='\n'  &&
 | 
				
			||||||
					buff[len-2]=='\r'  &&
 | 
										buff[len-2]=='\r'  &&
 | 
				
			||||||
@@ -251,29 +302,42 @@ static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
 | 
								// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
 | 
				
			||||||
			       if (     (len==BUFF_SIZE)  ||
 | 
								if (len == BUFF_SIZE ||
 | 
				
			||||||
				!( buff[9] =='2' &&
 | 
									!( buff[9] =='2' &&
 | 
				
			||||||
				buff[10]=='0' &&
 | 
									buff[10]=='0' &&
 | 
				
			||||||
				buff[11]=='0' ))
 | 
									buff[11]=='0' ))
 | 
				
			||||||
				return BLOCKED;
 | 
									return BLOCKED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return SUCCESS;
 | 
								return SUCCESS;
 | 
				
			||||||
           	}
 | 
					           	}
 | 
				
			||||||
            	break;
 | 
					            	break;
 | 
				
			||||||
            case SOCKS4_TYPE:
 | 
							
 | 
				
			||||||
            	{
 | 
							case SOCKS4_TYPE: {
 | 
				
			||||||
               		memset(buff,0,sizeof(buff));
 | 
					 | 
				
			||||||
                 		buff[0] = 4; // socks version
 | 
					                 		buff[0] = 4; // socks version
 | 
				
			||||||
  				buff[1] = 1; // connect command
 | 
					  				buff[1] = 1; // connect command
 | 
				
			||||||
				memcpy(&buff[2],&port,2); // dest port
 | 
									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
 | 
									memcpy(&buff[4], &ip, 4); // dest host
 | 
				
			||||||
				len=strlen(user)+1; // username
 | 
									len = ulen + 1; // username
 | 
				
			||||||
    				if(len > 1)
 | 
					    				if(len > 1)
 | 
				
			||||||
         				strcpy(&buff[8],user);
 | 
					         				memcpy(&buff[8], user, ulen + 1);
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									// 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, buff, (8+len)))
 | 
									if((len + 8) != write_n_bytes(sock, buff, (8+len)))
 | 
				
			||||||
					return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 				if(8 != read_n_bytes(sock,buff,8))
 | 
					 				if(8 != read_n_bytes(sock,buff,8))
 | 
				
			||||||
					return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
            	
 | 
					            	
 | 
				
			||||||
				if (buff[0] != 0 || buff[1] != 90)
 | 
									if (buff[0] != 0 || buff[1] != 90)
 | 
				
			||||||
					return BLOCKED;
 | 
										return BLOCKED;
 | 
				
			||||||
@@ -281,112 +345,119 @@ static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type
 | 
				
			|||||||
				return SUCCESS;
 | 
									return SUCCESS;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case SOCKS5_TYPE:
 | 
							case SOCKS5_TYPE: {
 | 
				
			||||||
            	{
 | 
								if(user) {
 | 
				
			||||||
               		if(user)
 | 
					 | 
				
			||||||
                 		{
 | 
					 | 
				
			||||||
                 		buff[0]=5;   //version
 | 
					                 		buff[0]=5;   //version
 | 
				
			||||||
				buff[1]=2;	//nomber of methods
 | 
									buff[1]=2;	//nomber of methods
 | 
				
			||||||
				buff[2]=0;   // no auth method
 | 
									buff[2]=0;   // no auth method
 | 
				
			||||||
	    			buff[3]=2;  /// auth method -> username / password
 | 
						    			buff[3]=2;  /// auth method -> username / password
 | 
				
			||||||
				if(4!=write_n_bytes(sock,buff,4))
 | 
									if(4!=write_n_bytes(sock,buff,4))
 | 
				
			||||||
					 	return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
       			}
 | 
					       			}
 | 
				
			||||||
            		else
 | 
					            		else {
 | 
				
			||||||
                		{
 | 
					 | 
				
			||||||
            			buff[0]=5;   //version
 | 
					            			buff[0]=5;   //version
 | 
				
			||||||
				buff[1]=1;	//nomber of methods
 | 
									buff[1]=1;	//nomber of methods
 | 
				
			||||||
				buff[2]=0;   // no auth method
 | 
									buff[2]=0;   // no auth method
 | 
				
			||||||
				if(3 != write_n_bytes(sock, buff, 3))
 | 
									if(3 != write_n_bytes(sock, buff, 3))
 | 
				
			||||||
					 	return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
       			}
 | 
					       			}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				memset(buff,0,sizeof(buff));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if(2 != read_n_bytes(sock, buff, 2))
 | 
								if(2 != read_n_bytes(sock, buff, 2))
 | 
				
			||||||
			 		return SOCKET_ERROR;
 | 
							 		goto err;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
      			if (buff[0]!=5||(buff[1]!=0&&buff[1]!=2))
 | 
					      			if (buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) {
 | 
				
			||||||
         			{
 | 
					        			if(buff[0] == 5 && buff[1] ==(char)0xFF)
 | 
				
			||||||
        				if((buff[0]==0x05)&&(buff[1]==(char)0xFF))
 | 
					 | 
				
			||||||
             				return BLOCKED;
 | 
					             				return BLOCKED;
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
							return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
          		}
 | 
					          		}
 | 
				
			||||||
          			
 | 
					          			
 | 
				
			||||||
          			if (buff[1]==2)
 | 
					          		if (buff[1] == 2) {
 | 
				
			||||||
               		{
 | 
					 | 
				
			||||||
				// authentication
 | 
									// authentication
 | 
				
			||||||
				char in[2];
 | 
									char in[2];
 | 
				
			||||||
				char out[515]; char* cur=out;
 | 
									char out[515]; char* cur=out;
 | 
				
			||||||
				int c;
 | 
									int c;
 | 
				
			||||||
				*cur++=1; // version
 | 
									*cur++=1; // version
 | 
				
			||||||
					c=strlen(user);
 | 
									c = ulen & 0xFF;
 | 
				
			||||||
				*cur++ = c;
 | 
									*cur++ = c;
 | 
				
			||||||
					strncpy(cur,user,c);
 | 
									memcpy(cur, user, c);
 | 
				
			||||||
				cur += c;
 | 
									cur += c;
 | 
				
			||||||
					c=strlen(pass);
 | 
									c = passlen & 0xFF;
 | 
				
			||||||
				*cur++ = c;
 | 
									*cur++ = c;
 | 
				
			||||||
					strncpy(cur,pass,c);
 | 
									memcpy(cur, pass, c);
 | 
				
			||||||
				cur += c;
 | 
									cur += c;
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				if((cur-out) != write_n_bytes(sock, out, cur-out))
 | 
									if((cur-out) != write_n_bytes(sock, out, cur-out))
 | 
				
			||||||
					 	return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				if(2 != read_n_bytes(sock,in,2))
 | 
									if(2 != read_n_bytes(sock,in,2))
 | 
				
			||||||
			 			return SOCKET_ERROR;
 | 
								 		goto err;
 | 
				
			||||||
					if(in[0]!=1||in[1]!=0)
 | 
									if(in[0] != 1 || in[1] != 0) {
 | 
				
			||||||
       				{
 | 
					 | 
				
			||||||
					if(in[0] != 1)
 | 
										if(in[0] != 1)
 | 
				
			||||||
      						return SOCKET_ERROR;
 | 
											goto err;
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
						return BLOCKED;
 | 
											return BLOCKED;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								int buff_iter = 0;
 | 
				
			||||||
 | 
								buff[buff_iter++] = 5;       // version
 | 
				
			||||||
 | 
								buff[buff_iter++] = 1;       // connect
 | 
				
			||||||
 | 
								buff[buff_iter++] = 0;       // reserved
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
     				buff[0]=5;       // version
 | 
								if(!dns_len) {
 | 
				
			||||||
				buff[1]=1;       // connect
 | 
									buff[buff_iter++] = 1;       // ip v4
 | 
				
			||||||
				buff[2]=0;       // reserved
 | 
									memcpy(buff + buff_iter, &ip, 4); // dest host
 | 
				
			||||||
				buff[3]=1;       // ip v4
 | 
									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[4],&ip,4); // dest host
 | 
								memcpy(buff + buff_iter, &port, 2); // dest port
 | 
				
			||||||
				memcpy(&buff[8],&port,2); // dest port
 | 
								buff_iter += 2;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			      if(10!=write_n_bytes(sock,buff,10))
 | 
								if(buff_iter != write_n_bytes(sock, buff, buff_iter))
 | 
				
			||||||
					return SOCKET_ERROR;
 | 
									goto err;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
			if(4 != read_n_bytes(sock,buff,4))
 | 
								if(4 != read_n_bytes(sock,buff,4))
 | 
				
			||||||
					return SOCKET_ERROR;
 | 
									goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (buff[0] != 5 || buff[1] != 0)
 | 
								if (buff[0] != 5 || buff[1] != 0)
 | 
				
			||||||
			      	return SOCKET_ERROR;
 | 
									goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								switch (buff[3]) {
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
			  	switch (buff[3])
 | 
					 | 
				
			||||||
			      {
 | 
					 | 
				
			||||||
				case 1: len = 4;  break;
 | 
									case 1: len = 4;  break;
 | 
				
			||||||
				case 4: len = 16; break;
 | 
									case 4: len = 16; break;
 | 
				
			||||||
				case 3: len = 0;
 | 
									case 3: len = 0;
 | 
				
			||||||
					if(1 != read_n_bytes(sock, (char*) &len, 1))
 | 
										if(1 != read_n_bytes(sock, (char*) &len, 1))
 | 
				
			||||||
			 				return SOCKET_ERROR;
 | 
											goto err;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
						return SOCKET_ERROR;
 | 
										goto err;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     				if((len+2)!=read_n_bytes(sock,buff,(len+2)))
 | 
								if(len + 2 != read_n_bytes(sock, buff, len+2))
 | 
				
			||||||
					return SOCKET_ERROR;
 | 
									goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return SUCCESS;
 | 
								return SUCCESS;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err:
 | 
				
			||||||
	return SOCKET_ERROR;
 | 
						return SOCKET_ERROR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TP " ... "
 | 
				
			||||||
 | 
					#define DT "Dynamic chain"
 | 
				
			||||||
 | 
					#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;
 | 
						struct sockaddr_in addr;
 | 
				
			||||||
@@ -395,14 +466,14 @@ static int start_chain(int *fd, proxy_data *pd, char* begin_mark)
 | 
				
			|||||||
	if(*fd==-1)
 | 
						if(*fd==-1)
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	proxychains_write_log("%s-<>-%s:%d-",
 | 
						proxychains_write_log(LOG_PREFIX "%s "TP" %s:%d ",
 | 
				
			||||||
				begin_mark,
 | 
									begin_mark,
 | 
				
			||||||
				inet_ntoa(*(struct in_addr*)&pd->ip),
 | 
									inet_ntoa(*(struct in_addr*)&pd->ip),
 | 
				
			||||||
				htons(pd->port));
 | 
									htons(pd->port));
 | 
				
			||||||
	pd->ps=PLAY_STATE;
 | 
						pd->ps=PLAY_STATE;
 | 
				
			||||||
	memset(&addr, 0, sizeof(addr));
 | 
						memset(&addr, 0, sizeof(addr));
 | 
				
			||||||
	addr.sin_family = AF_INET;
 | 
						addr.sin_family = AF_INET;
 | 
				
			||||||
	addr.sin_addr.s_addr = pd->ip;
 | 
						addr.sin_addr.s_addr = (in_addr_t) pd->ip.as_int;
 | 
				
			||||||
	addr.sin_port = pd->port;
 | 
						addr.sin_port = pd->port;
 | 
				
			||||||
	if (timed_connect (*fd ,(struct sockaddr*)&addr,sizeof(addr))) {
 | 
						if (timed_connect (*fd ,(struct sockaddr*)&addr,sizeof(addr))) {
 | 
				
			||||||
		pd->ps=DOWN_STATE;
 | 
							pd->ps=DOWN_STATE;
 | 
				
			||||||
@@ -411,7 +482,7 @@ static int start_chain(int *fd, proxy_data *pd, char* begin_mark)
 | 
				
			|||||||
	pd->ps=BUSY_STATE;
 | 
						pd->ps=BUSY_STATE;
 | 
				
			||||||
	return SUCCESS;
 | 
						return SUCCESS;
 | 
				
			||||||
error1:
 | 
					error1:
 | 
				
			||||||
	proxychains_write_log("<--timeout\n");
 | 
						proxychains_write_log(TP" timeout\n");
 | 
				
			||||||
error:
 | 
					error:
 | 
				
			||||||
	if(*fd!=-1)
 | 
						if(*fd!=-1)
 | 
				
			||||||
		close(*fd);
 | 
							close(*fd);
 | 
				
			||||||
@@ -481,12 +552,23 @@ static unsigned int calc_alive(proxy_data *pd, unsigned int proxy_count)
 | 
				
			|||||||
static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
 | 
					static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retcode=-1;
 | 
						int retcode=-1;
 | 
				
			||||||
 | 
						char* hostname;
 | 
				
			||||||
 | 
						uint32_t index;
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	PDEBUG("chain_step()\n");
 | 
						PDEBUG("chain_step()\n");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
						if(pto->ip.octet[0] == 224) {
 | 
				
			||||||
 | 
							index = index_from_internal_ip(pto->ip);
 | 
				
			||||||
 | 
							if(index < internal_ips.counter)
 | 
				
			||||||
 | 
								hostname = internal_ips.list[index]->string;
 | 
				
			||||||
 | 
							else goto usenumericip;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							usenumericip:
 | 
				
			||||||
 | 
							hostname = inet_ntoa(*(struct in_addr*)&pto->ip);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	proxychains_write_log("<>-%s:%d-", 
 | 
						proxychains_write_log(TP" %s:%d ",  
 | 
				
			||||||
			inet_ntoa(*(struct in_addr*)&pto->ip),
 | 
								hostname,
 | 
				
			||||||
			htons(pto->port));
 | 
								htons(pto->port));
 | 
				
			||||||
	retcode = 
 | 
						retcode = 
 | 
				
			||||||
		tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, 
 | 
							tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, 
 | 
				
			||||||
@@ -509,7 +591,7 @@ static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
 | 
				
			|||||||
	return retcode;
 | 
						return retcode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int connect_proxy_chain( int sock, unsigned int target_ip, 
 | 
					int connect_proxy_chain( int sock, ip_type target_ip, 
 | 
				
			||||||
		unsigned short target_port, proxy_data *pd, 
 | 
							unsigned short target_port, proxy_data *pd, 
 | 
				
			||||||
		unsigned int proxy_count, chain_type ct, unsigned int max_chain )
 | 
							unsigned int proxy_count, chain_type ct, unsigned int max_chain )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -520,11 +602,6 @@ int connect_proxy_chain( int sock, unsigned int target_ip,
 | 
				
			|||||||
	unsigned int alive_count=0;
 | 
						unsigned int alive_count=0;
 | 
				
			||||||
	unsigned int curr_len=0;
 | 
						unsigned int curr_len=0;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
#define TP "<>"
 | 
					 | 
				
			||||||
#define DT "|D-chain|"
 | 
					 | 
				
			||||||
#define ST "|S-chain|"
 | 
					 | 
				
			||||||
#define RT "|R-chain|"
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	p3=&p4;
 | 
						p3=&p4;
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	PDEBUG("connect_proxy_chain\n");
 | 
						PDEBUG("connect_proxy_chain\n");
 | 
				
			||||||
@@ -552,7 +629,7 @@ again:
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			p1=p2;
 | 
								p1=p2;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		proxychains_write_log(TP);
 | 
							//proxychains_write_log(TP);
 | 
				
			||||||
		p3->ip = target_ip;
 | 
							p3->ip = target_ip;
 | 
				
			||||||
		p3->port = target_port;
 | 
							p3->port = target_port;
 | 
				
			||||||
		if(SUCCESS != chain_step(ns, p1, p3))
 | 
							if(SUCCESS != chain_step(ns, p1, p3))
 | 
				
			||||||
@@ -585,7 +662,7 @@ again:
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			p1 = p2;
 | 
								p1 = p2;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		proxychains_write_log(TP);
 | 
							//proxychains_write_log(TP);
 | 
				
			||||||
		p3->ip = target_ip;
 | 
							p3->ip = target_ip;
 | 
				
			||||||
		p3->port = target_port;
 | 
							p3->port = target_port;
 | 
				
			||||||
		if(SUCCESS!=chain_step(ns, p1, p3))
 | 
							if(SUCCESS!=chain_step(ns, p1, p3))
 | 
				
			||||||
@@ -612,7 +689,7 @@ again:
 | 
				
			|||||||
			}	
 | 
								}	
 | 
				
			||||||
			p1 = p2;
 | 
								p1 = p2;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		proxychains_write_log(TP);
 | 
							//proxychains_write_log(TP);
 | 
				
			||||||
		p3->ip = target_ip;
 | 
							p3->ip = target_ip;
 | 
				
			||||||
		p3->port = target_port;
 | 
							p3->port = target_port;
 | 
				
			||||||
		if(SUCCESS!=chain_step(ns,p1,p3))
 | 
							if(SUCCESS!=chain_step(ns,p1,p3))
 | 
				
			||||||
@@ -620,7 +697,7 @@ again:
 | 
				
			|||||||
			
 | 
								
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proxychains_write_log("<><>-OK\n");
 | 
						proxychains_write_log(TP" OK\n");
 | 
				
			||||||
	dup2(ns,sock);
 | 
						dup2(ns,sock);
 | 
				
			||||||
	close(ns);
 | 
						close(ns);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@@ -643,72 +720,91 @@ error_strict:
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct hostent hostent_space;
 | 
					static struct hostent hostent_space;
 | 
				
			||||||
static in_addr_t resolved_addr;
 | 
					static in_addr_t resolved_addr;
 | 
				
			||||||
static char* resolved_addr_p;
 | 
					static char* resolved_addr_p[2];
 | 
				
			||||||
static char addr_name[1024*8];
 | 
					static char addr_name[1024*8];
 | 
				
			||||||
 | 
					static const ip_type local_host = {127, 0, 0, 1};
 | 
				
			||||||
struct hostent* proxy_gethostbyname(const char *name)
 | 
					struct hostent* proxy_gethostbyname(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int pipe_fd[2];
 | 
					 | 
				
			||||||
	char buff[256];
 | 
						char buff[256];
 | 
				
			||||||
	in_addr_t addr;
 | 
						uint32_t i, hash;
 | 
				
			||||||
	pid_t pid;
 | 
						void* new_mem;
 | 
				
			||||||
	int status;
 | 
						size_t l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct hostent* hp;
 | 
						struct hostent* hp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hostent_space.h_addr_list = &resolved_addr_p;
 | 
						resolved_addr_p[0] = (char*) &resolved_addr;
 | 
				
			||||||
	*hostent_space.h_addr_list = (char*)&resolved_addr;
 | 
						resolved_addr_p[1] = NULL;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						hostent_space.h_addr_list = resolved_addr_p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resolved_addr = 0;
 | 
						resolved_addr = 0;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	gethostname(buff,sizeof(buff));
 | 
						gethostname(buff,sizeof(buff));
 | 
				
			||||||
	if(!strcmp(buff,name))
 | 
						
 | 
				
			||||||
		goto got_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));
 | 
						memset(buff, 0, sizeof(buff));
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// TODO: this works only once, so cache it  ...
 | 
					 | 
				
			||||||
	// 	 later
 | 
					 | 
				
			||||||
	while ((hp=gethostent()))
 | 
						while ((hp=gethostent()))
 | 
				
			||||||
		if (!strcmp(hp->h_name,name)) 
 | 
							if (!strcmp(hp->h_name,name)) 
 | 
				
			||||||
			return hp; 
 | 
								return hp; 
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if(pipe(pipe_fd))
 | 
						
 | 
				
			||||||
 | 
						hash = dalias_hash((char*) name);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(internal_ips.counter) {
 | 
				
			||||||
 | 
							for( i = 0; i < internal_ips.counter; i++) {
 | 
				
			||||||
 | 
								if(internal_ips.list[i]->hash == hash) {
 | 
				
			||||||
 | 
									resolved_addr = make_internal_ip(i);
 | 
				
			||||||
 | 
									goto have_ip;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(internal_ips.capa < internal_ips.counter + 1) {
 | 
				
			||||||
 | 
							new_mem = realloc(internal_ips.list, internal_ips.capa + 16);
 | 
				
			||||||
 | 
							if(new_mem) {
 | 
				
			||||||
 | 
								internal_ips.capa += 16;
 | 
				
			||||||
 | 
								internal_ips.list = new_mem;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								oom:
 | 
				
			||||||
 | 
								proxychains_write_log("out of mem\n");
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
	pid = fork();
 | 
							}
 | 
				
			||||||
	switch(pid) {
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		case 0: // child
 | 
						resolved_addr = make_internal_ip(internal_ips.counter);
 | 
				
			||||||
			proxychains_write_log("|DNS-request| %s \n", name);
 | 
						if(resolved_addr == (in_addr_t) -1) goto err;
 | 
				
			||||||
			dup2(pipe_fd[1],1);
 | 
					 | 
				
			||||||
			//dup2(pipe_fd[1],2);
 | 
					 | 
				
			||||||
		//	putenv("LD_PRELOAD=");
 | 
					 | 
				
			||||||
			execlp("proxyresolv","proxyresolv",name,NULL);
 | 
					 | 
				
			||||||
			perror("can't exec proxyresolv");
 | 
					 | 
				
			||||||
			exit(2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case -1: //error
 | 
						l = strlen(name);
 | 
				
			||||||
			close(pipe_fd[0]);
 | 
						new_mem = malloc(sizeof(string_hash_tuple) + l + 1);
 | 
				
			||||||
			close(pipe_fd[1]);
 | 
						if(!new_mem) 
 | 
				
			||||||
			perror("can't fork");
 | 
							goto oom;
 | 
				
			||||||
			goto err;
 | 
						
 | 
				
			||||||
 | 
						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:
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						//strncpy(addr_name, name, sizeof(addr_name));
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			close(pipe_fd[1]);
 | 
					 | 
				
			||||||
			waitpid(pid, &status, 0);
 | 
					 | 
				
			||||||
			read(pipe_fd[0],&buff,sizeof(buff));
 | 
					 | 
				
			||||||
			close(pipe_fd[0]);
 | 
					 | 
				
			||||||
got_buff:
 | 
					 | 
				
			||||||
			addr = inet_addr(buff);
 | 
					 | 
				
			||||||
			if (addr == (in_addr_t) (-1))
 | 
					 | 
				
			||||||
				goto err_dns;
 | 
					 | 
				
			||||||
			memcpy(*(hostent_space.h_addr_list),
 | 
					 | 
				
			||||||
						&addr ,sizeof(struct in_addr));
 | 
					 | 
				
			||||||
	hostent_space.h_name = addr_name;
 | 
						hostent_space.h_name = addr_name;
 | 
				
			||||||
	hostent_space.h_length = sizeof (in_addr_t);
 | 
						hostent_space.h_length = sizeof (in_addr_t);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	proxychains_write_log("|DNS-response| %s is %s\n",
 | 
					 | 
				
			||||||
			name, inet_ntoa(*(struct in_addr*)&addr));
 | 
					 | 
				
			||||||
	return &hostent_space;
 | 
						return &hostent_space;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
err_dns:
 | 
					err_dns:
 | 
				
			||||||
	proxychains_write_log("|DNS-response|: %s does not exist\n", name);
 | 
						proxychains_write_log("|DNS-response|: %s does not exist\n", name);
 | 
				
			||||||
	perror("err_dns");
 | 
						perror("err_dns");
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								src/core.h
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/core.h
									
									
									
									
									
								
							@@ -5,6 +5,7 @@
 | 
				
			|||||||
    copyright          :  netcreature (C) 2002
 | 
					    copyright          :  netcreature (C) 2002
 | 
				
			||||||
    email                 : netcreature@users.sourceforge.net
 | 
					    email                 : netcreature@users.sourceforge.net
 | 
				
			||||||
 ***************************************************************************/
 | 
					 ***************************************************************************/
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 /*     GPL */
 | 
					 /*     GPL */
 | 
				
			||||||
/***************************************************************************
 | 
					/***************************************************************************
 | 
				
			||||||
 *                                                                         *
 | 
					 *                                                                         *
 | 
				
			||||||
@@ -19,9 +20,26 @@
 | 
				
			|||||||
#define BUFF_SIZE 8*1024  // used to read responses from proxies.
 | 
					#define BUFF_SIZE 8*1024  // used to read responses from proxies.
 | 
				
			||||||
#define     MAX_LOCALNET 1024
 | 
					#define     MAX_LOCALNET 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union {
 | 
				
			||||||
 | 
						unsigned char octet[4];
 | 
				
			||||||
 | 
						uint32_t as_int;
 | 
				
			||||||
 | 
					} ip_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						uint32_t hash;
 | 
				
			||||||
 | 
						char* string;
 | 
				
			||||||
 | 
					} string_hash_tuple;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						uint32_t counter;
 | 
				
			||||||
 | 
						uint32_t capa;
 | 
				
			||||||
 | 
						string_hash_tuple** list;
 | 
				
			||||||
 | 
					} internal_ip_lookup_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern internal_ip_lookup_table internal_ips;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*error codes*/
 | 
					/*error codes*/
 | 
				
			||||||
typedef enum
 | 
					typedef enum {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	SUCCESS=0,
 | 
						SUCCESS=0,
 | 
				
			||||||
	MEMORY_FAIL,        // malloc failed
 | 
						MEMORY_FAIL,        // malloc failed
 | 
				
			||||||
	SOCKET_ERROR,  // look errno for more
 | 
						SOCKET_ERROR,  // look errno for more
 | 
				
			||||||
@@ -31,19 +49,37 @@ typedef enum
 | 
				
			|||||||
} ERR_CODE;
 | 
					} ERR_CODE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {HTTP_TYPE,SOCKS4_TYPE,SOCKS5_TYPE} proxy_type;
 | 
					typedef enum {
 | 
				
			||||||
typedef enum {DYNAMIC_TYPE,STRICT_TYPE,RANDOM_TYPE} chain_type;
 | 
						HTTP_TYPE,
 | 
				
			||||||
typedef enum {PLAY_STATE,DOWN_STATE,BLOCKED_STATE,BUSY_STATE} proxy_state;
 | 
						SOCKS4_TYPE,
 | 
				
			||||||
typedef enum {RANDOMLY,FIFOLY} select_type;
 | 
						SOCKS5_TYPE
 | 
				
			||||||
 | 
					} proxy_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct
 | 
					typedef enum {
 | 
				
			||||||
{
 | 
						DYNAMIC_TYPE,
 | 
				
			||||||
 | 
						STRICT_TYPE,
 | 
				
			||||||
 | 
						RANDOM_TYPE}
 | 
				
			||||||
 | 
					chain_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						PLAY_STATE,
 | 
				
			||||||
 | 
						DOWN_STATE,
 | 
				
			||||||
 | 
						BLOCKED_STATE,
 | 
				
			||||||
 | 
						BUSY_STATE
 | 
				
			||||||
 | 
					} proxy_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						RANDOMLY,
 | 
				
			||||||
 | 
						FIFOLY
 | 
				
			||||||
 | 
					} select_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
	struct in_addr in_addr, netmask;
 | 
						struct in_addr in_addr, netmask;
 | 
				
			||||||
	unsigned short port;
 | 
						unsigned short port;
 | 
				
			||||||
} localaddr_arg;
 | 
					} localaddr_arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	unsigned int ip;
 | 
						ip_type ip;
 | 
				
			||||||
	unsigned short port;
 | 
						unsigned short port;
 | 
				
			||||||
	proxy_type pt;
 | 
						proxy_type pt;
 | 
				
			||||||
	proxy_state ps;
 | 
						proxy_state ps;
 | 
				
			||||||
@@ -62,7 +98,7 @@ typedef struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int connect_proxy_chain (
 | 
					int connect_proxy_chain (
 | 
				
			||||||
	int sock,
 | 
						int sock,
 | 
				
			||||||
		unsigned int target_ip,
 | 
						ip_type target_ip,
 | 
				
			||||||
	unsigned short target_port,
 | 
						unsigned short target_port,
 | 
				
			||||||
	proxy_data * pd,
 | 
						proxy_data * pd,
 | 
				
			||||||
	unsigned int proxy_count,
 | 
						unsigned int proxy_count,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,7 +62,7 @@ static void init_lib(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void init_lib(void)
 | 
					static void init_lib(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	proxychains_write_log("[proxychains v3.2] DLL init\n");
 | 
						proxychains_write_log(LOG_PREFIX "DLL init\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");
 | 
						true_connect = (connect_t) dlsym(RTLD_NEXT, "connect");
 | 
				
			||||||
@@ -200,21 +200,27 @@ static inline void get_chain_data(
 | 
				
			|||||||
		if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') {
 | 
							if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') {
 | 
				
			||||||
			if(list) {
 | 
								if(list) {
 | 
				
			||||||
				memset(&pd[count], 0, sizeof(proxy_data));
 | 
									memset(&pd[count], 0, sizeof(proxy_data));
 | 
				
			||||||
 | 
									
 | 
				
			||||||
				pd[count].ps = PLAY_STATE;
 | 
									pd[count].ps = PLAY_STATE;
 | 
				
			||||||
				port_n = 0;
 | 
									port_n = 0;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
				sscanf(buff,"%s %s %d %s %s", type, host, &port_n,
 | 
									sscanf(buff,"%s %s %d %s %s", type, host, &port_n,
 | 
				
			||||||
					pd[count].user, pd[count].pass);
 | 
										pd[count].user, pd[count].pass);
 | 
				
			||||||
				pd[count].ip=inet_addr(host);
 | 
									
 | 
				
			||||||
 | 
									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;
 | 
										pd[count].pt = HTTP_TYPE;
 | 
				
			||||||
				} else if(!strcmp(type,"socks4")) {
 | 
									} else if(!strcmp(type,"socks4")) {
 | 
				
			||||||
					pd[count].pt = SOCKS4_TYPE;
 | 
										pd[count].pt = SOCKS4_TYPE;
 | 
				
			||||||
				} else if(!strcmp(type,"socks5")) {
 | 
									} else if(!strcmp(type,"socks5")) {
 | 
				
			||||||
					pd[count].pt = SOCKS5_TYPE;
 | 
										pd[count].pt = SOCKS5_TYPE;
 | 
				
			||||||
				}else continue;
 | 
									} else 
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				if( pd[count].ip && (int) pd[count].ip != -1 && port_n)
 | 
									if(pd[count].ip.as_int && port_n &&
 | 
				
			||||||
 | 
									   (int) pd[count].ip.as_int != (uint32_t) -1)
 | 
				
			||||||
					if(++count==MAX_CHAIN)
 | 
										if(++count==MAX_CHAIN)
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
			 } else {
 | 
								 } else {
 | 
				
			||||||
@@ -230,9 +236,7 @@ static inline void get_chain_data(
 | 
				
			|||||||
					sscanf(buff,"%s %d",user,&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) ;
 | 
										sscanf(buff,"%s %d",user,&tcp_connect_time_out) ;
 | 
				
			||||||
				}
 | 
									} else if(strstr(buff,"localnet")) {
 | 
				
			||||||
				else if(strstr(buff,"localnet"))
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (sscanf(buff,"%s %21[^/]/%15s", user,
 | 
										if (sscanf(buff,"%s %21[^/]/%15s", user,
 | 
				
			||||||
						local_in_addr_port, local_netmask) < 3) {
 | 
											local_in_addr_port, local_netmask) < 3) {
 | 
				
			||||||
						fprintf(stderr, "localnet format error");
 | 
											fprintf(stderr, "localnet format error");
 | 
				
			||||||
@@ -276,8 +280,7 @@ static inline void get_chain_data(
 | 
				
			|||||||
					{
 | 
										{
 | 
				
			||||||
						fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET);
 | 
											fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									} else if(strstr(buff,"chain_len")){
 | 
				
			||||||
				else if(strstr(buff,"chain_len")){
 | 
					 | 
				
			||||||
					char *pc;int len;
 | 
										char *pc;int len;
 | 
				
			||||||
					pc=strchr(buff,'=');
 | 
										pc=strchr(buff,'=');
 | 
				
			||||||
					len=atoi(++pc);
 | 
										len=atoi(++pc);
 | 
				
			||||||
@@ -301,6 +304,7 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int socktype=0, flags=0, ret=0;
 | 
						int socktype=0, flags=0, ret=0;
 | 
				
			||||||
	socklen_t optlen = 0;
 | 
						socklen_t optlen = 0;
 | 
				
			||||||
 | 
						ip_type dest_ip;
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	char str[256];
 | 
						char str[256];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -338,14 +342,18 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len)
 | 
				
			|||||||
	flags = fcntl(sock, F_GETFL, 0);
 | 
						flags = fcntl(sock, F_GETFL, 0);
 | 
				
			||||||
	if(flags & O_NONBLOCK)
 | 
						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(
 | 
						ret = connect_proxy_chain(
 | 
				
			||||||
		sock,
 | 
							sock,
 | 
				
			||||||
		SOCKADDR(*addr),
 | 
							dest_ip,
 | 
				
			||||||
		SOCKPORT(*addr),
 | 
							SOCKPORT(*addr),
 | 
				
			||||||
		proxychains_pd,
 | 
							proxychains_pd,
 | 
				
			||||||
		proxychains_proxy_count,
 | 
							proxychains_proxy_count,
 | 
				
			||||||
		proxychains_ct,
 | 
							proxychains_ct,
 | 
				
			||||||
		proxychains_max_chain );
 | 
							proxychains_max_chain );
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	fcntl(sock, F_SETFL, flags);
 | 
						fcntl(sock, F_SETFL, flags);
 | 
				
			||||||
	if(ret != SUCCESS)
 | 
						if(ret != SUCCESS)
 | 
				
			||||||
	errno = ECONNREFUSED;
 | 
						errno = ECONNREFUSED;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user