示例#1
0
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
	struct sockaddr_in addr;
	char ip_buf[16];

	*fd = socket(PF_INET, SOCK_STREAM, 0);
	if(*fd == -1)
		goto error;
	
	pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
	proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ",
			      begin_mark, ip_buf, 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;
		goto error1;
	}
	pd->ps = BUSY_STATE;
	return SUCCESS;
	error1:
	proxychains_write_log(TP " timeout\n");
	error:
	if(*fd != -1)
		close(*fd);
	return SOCKET_ERROR;
}
示例#2
0
文件: core.c 项目: hornos/proxychains
static int start_chain(int *fd, proxy_data *pd, char* begin_mark)
{
	struct sockaddr_in addr;
	
	*fd=socket(PF_INET,SOCK_STREAM,0);
	if(*fd==-1)
		goto error;
	
	proxychains_write_log("%s-<>-%s:%d-",
				begin_mark,
				inet_ntoa(*(struct in_addr*)&pd->ip),
				htons(pd->port));
	pd->ps=PLAY_STATE;
	bzero(&addr,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = pd->ip;
	addr.sin_port = pd->port;
	if (timed_connect (*fd ,(struct sockaddr*)&addr,sizeof(addr))) {
		pd->ps=DOWN_STATE;
		goto error1;
	}
	pd->ps=BUSY_STATE;
	return SUCCESS;
error1:
	proxychains_write_log("<--timeout\n");
error:
	if(*fd!=-1)
		close(*fd);
	return SOCKET_ERROR;
}
示例#3
0
文件: core.c 项目: hornos/proxychains
static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
{
	int retcode=-1;
	
	proxychains_write_log("<>-%s:%d-", 
			inet_ntoa(*(struct in_addr*)&pto->ip),
			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;
			break;
		case BLOCKED:
			pto->ps=BLOCKED_STATE;
			proxychains_write_log("<--denied\n");
			close(ns);
			break;
		case SOCKET_ERROR:
			pto->ps=DOWN_STATE;
			proxychains_write_log("<--timeout\n");
			close(ns);
			break;
	}
	return retcode;
}
示例#4
0
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
	*fd = socket(PF_INET, SOCK_STREAM, 0);
	if(*fd == -1)
		goto error;
	
	char ip_buf[16];
	pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
	proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ",
			      begin_mark, ip_buf, htons(pd->port));
	pd->ps = PLAY_STATE;
	struct sockaddr_in addr = {
		.sin_family = AF_INET,
		.sin_port = pd->port,
		.sin_addr.s_addr = (in_addr_t) pd->ip.as_int
	};
	if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr))) {
		pd->ps = DOWN_STATE;
		goto error1;
	}
	pd->ps = BUSY_STATE;
	return SUCCESS;
	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;
	if(*offset >= proxy_count)
		return NULL;
	switch (how) {
		case RANDOMLY:
			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;
		case FIFOLY:
			for(i = *offset; i < proxy_count; i++) {
				if(pd[i].ps == PLAY_STATE) {
					*offset = i;
					break;
				}
			}
		default:
			break;
	}
	if(i >= proxy_count)
		i = 0;
	return (pd[i].ps == PLAY_STATE) ? &pd[i] : NULL;
}
示例#5
0
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
	int retcode = -1;
	char *hostname;
	char hostname_buf[MSG_LEN_MAX];
	char ip_buf[16];

	PFUNC();

	if(pto->ip.octet[0] == remote_dns_subnet) {
		if(!at_get_host_for_ip(pto->ip, hostname_buf)) goto usenumericip;
		else hostname = hostname_buf;
	} else {
	usenumericip:
		pc_stringfromipv4(&pto->ip.octet[0], ip_buf);
		hostname = ip_buf;
	}

	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;
			break;
		case BLOCKED:
			pto->ps = BLOCKED_STATE;
			proxychains_write_log("<--denied\n");
			close(ns);
			break;
		case SOCKET_ERROR:
			pto->ps = DOWN_STATE;
			proxychains_write_log("<--socket error or timeout!\n");
			close(ns);
			break;
	}
	return retcode;
}
示例#6
0
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
	int retcode = -1;
	char *hostname;
	char ip_buf[16];

	PDEBUG("chain_step()\n");

	if(pto->ip.octet[0] == remote_dns_subnet) {
		hostname = string_from_internal_ip(pto->ip);
		if(!hostname)
			goto usenumericip;
	} else {
	usenumericip:
		inet_ntop(AF_INET, &pto->ip.octet[0], ip_buf, sizeof(ip_buf));
		hostname = ip_buf;
	}

	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;
			break;
		case BLOCKED:
			pto->ps = BLOCKED_STATE;
			proxychains_write_log("<--denied\n");
			close(ns);
			break;
		case SOCKET_ERROR:
			pto->ps = DOWN_STATE;
			proxychains_write_log("<--socket error or timeout!\n");
			close(ns);
			break;
	}
	return retcode;
}
示例#7
0
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count) {
	char ip_buf[INET6_ADDRSTRLEN];
	for (; count; pchain++, count--) {
		if(!inet_ntop(pchain->ip.is_v6?AF_INET6:AF_INET,pchain->ip.addr.v6,ip_buf,sizeof ip_buf)) {
			proxychains_write_log(LOG_PREFIX "error: ip address conversion failed\n");
			continue;
		}
		PDEBUG("[%s] %s %s:%d", proxy_state_strmap[pchain->ps],
		       proxy_type_strmap[pchain->pt], 
		       ip_buf, htons(pchain->port));
		if (*pchain->user || *pchain->pass) {
			PSTDERR(" [u=%s,p=%s]", pchain->user, pchain->pass);
		}
		PSTDERR("\n");
	}
}
示例#8
0
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;
	int rc = -1;
	unsigned int offset = 0;
	unsigned int alive_count = 0;
	unsigned int curr_len = 0;
	unsigned int curr_pos = 0;
	unsigned int looped = 0; // went back to start of list in RR mode

	p3 = &p4;

	PFUNC();

	again:
	rc = -1;
	DUMP_PROXY_CHAIN(pd, proxy_count);

	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)) {
					PDEBUG("GOTO AGAIN 1\n");
					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;
			break;

		case ROUND_ROBIN_TYPE:
			alive_count = calc_alive(pd, proxy_count);
			curr_pos = offset = proxychains_proxy_offset;
			if(alive_count < max_chain)
				goto error_more;
                        PDEBUG("1:rr_offset = %d, curr_pos = %d\n", offset, curr_pos);
			/* Check from current RR offset til end */
			for (;rc != SUCCESS;) {
				if (!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
					/* We've reached the end of the list, go to the start */
 					offset = 0;
					looped++;
					continue;
				} else if (looped && rc > 0 && offset >= curr_pos) {
 					PDEBUG("GOTO MORE PROXIES 0\n");
					/* We've gone back to the start and now past our starting position */
					proxychains_proxy_offset = 0;
 					goto error_more;
 				}
 				PDEBUG("2:rr_offset = %d\n", offset);
 				rc=start_chain(&ns, p1, RRT);
			}
			/* Create rest of chain using RR */
			for(curr_len = 1; curr_len < max_chain;) {
				PDEBUG("3:rr_offset = %d, curr_len = %d, max_chain = %d\n", offset, curr_len, max_chain);
				p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
				if(!p2) {
					/* Try from the beginning to where we started */
					offset = 0;
					continue;
				} else if(SUCCESS != chain_step(ns, p1, p2)) {
					PDEBUG("GOTO AGAIN 1\n");
					goto again;
				} else
					p1 = p2;
				curr_len++;
			}
			//proxychains_write_log(TP);
			p3->ip = target_ip;
			p3->port = target_port;
			proxychains_proxy_offset = offset+1;
			PDEBUG("pd_offset = %d, curr_len = %d\n", proxychains_proxy_offset, curr_len);
			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))) {
				PDEBUG("select_proxy failed\n");
				goto error_strict;
			}
			if(SUCCESS != start_chain(&ns, p1, ST)) {
				PDEBUG("start_chain failed\n");
				goto error_strict;
			}
			while(offset < proxy_count) {
				if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
					break;
				if(SUCCESS != chain_step(ns, p1, p2)) {
					PDEBUG("chain_step failed\n");
					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)) {
					PDEBUG("GOTO AGAIN 2\n");
					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);
	close(ns);
	return 0;
	error:
	if(ns != -1)
		close(ns);
	errno = ECONNREFUSED;	// for nmap ;)
	return -1;

	error_more:
	proxychains_write_log("\n!!!need more proxies!!!\n");
	error_strict:
	PDEBUG("error\n");
	
	release_all(pd, proxy_count);
	if(ns != -1)
		close(ns);
	errno = ETIMEDOUT;
	return -1;
}
示例#9
0
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) {
	char *dns_name = NULL;
	char hostnamebuf[MSG_LEN_MAX];
	size_t dns_len = 0;

	PFUNC();

	// 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.)
	// 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_len = at_get_host_for_ip(ip, hostnamebuf);
		if(!dns_len) goto err;
		else dns_name = hostnamebuf;
	}
	
	PDEBUG("host dns %s\n", dns_name ? dns_name : "<NULL>");

	size_t ulen = strlen(user);
	size_t passlen = strlen(pass);

	if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) {
		proxychains_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n");
		goto err;
	}

	int len;
	unsigned char buff[BUFF_SIZE];
	char ip_buf[16];
	
	switch (pt) {
		case HTTP_TYPE:{
			if(!dns_len) {
				pc_stringfromipv4(&ip.octet[0], ip_buf);
				dns_name = ip_buf;
			}
			#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(ulen) {
				snprintf(src, sizeof(src), "%s:%s", user, pass);
				encode_base_64(src, dst, sizeof(dst));
			} else dst[0] = 0;

			len = snprintf((char *) buff, sizeof(buff),
			               "CONNECT %s:%d HTTP/1.0\r\n%s%s%s\r\n",
			                dns_name,  ntohs(port),
			                ulen ? "Proxy-Authorization: Basic " : dst,
			                dst, ulen ? "\r\n" : dst);

			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
					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')) {
				PDEBUG("HTTP proxy blocked: buff=\"%s\"\n", buff);
				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
			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);
			else {
				buff[8] = 0;
			}

			// do socksv4a dns resolution on the server
			if(dns_len) {
				memcpy(&buff[8 + len], dns_name, dns_len + 1);
				len += dns_len + 1;
			}

			if((len + 8) != write_n_bytes(sock, (char *) buff, (8 + len)))
				goto err;

			if(8 != read_n_bytes(sock, (char *) buff, 8))
				goto err;

			if(buff[0] != 0 || buff[1] != 90)
				return BLOCKED;

			return SUCCESS;
		}
		break;
		case SOCKS5_TYPE:{
			int n_methods = ulen ? 2 : 1;
			buff[0] = 5;	// version
			buff[1] = n_methods ;	// number of methods
			buff[2] = 0;	// no auth method
			if(ulen) buff[3] = 2;    /// auth method -> username / password
			if(2+n_methods != write_n_bytes(sock, (char *) buff, 2+n_methods))
				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;
				size_t 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;
		}
		break;
	}

	err:
	return SOCKET_ERROR;
}
示例#10
0
文件: core.c 项目: hornos/proxychains
struct hostent* proxy_gethostbyname(const char *name)
{
	int pipe_fd[2];
	char buff[256];
	in_addr_t addr;
	pid_t pid;
	int status;
	struct hostent* hp;

	hostent_space.h_addr_list = &resolved_addr_p;
	*hostent_space.h_addr_list = (char*)&resolved_addr;
	resolved_addr = 0;
	
	gethostname(buff,sizeof(buff));
	if(!strcmp(buff,name))
		goto got_buff;

	bzero(buff,sizeof(buff));
	
	// TODO: this works only once, so cache it  ...
	// 	 later
	while (hp=gethostent())
		if (!strcmp(hp->h_name,name)) 
			return hp; 
	
	if(pipe(pipe_fd))
		goto err;
	pid = fork();
	switch(pid) {
	
		case 0: // child
			proxychains_write_log("|DNS-request| %s \n", name);
			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
			close(pipe_fd[0]);
			close(pipe_fd[1]);
			perror("can't fork");
			goto err;
		
		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 == -1)
				goto err_dns;
			memcpy(*(hostent_space.h_addr_list),
						&addr ,sizeof(struct in_addr));
			hostent_space.h_name = addr_name;
			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;
err_dns:
	proxychains_write_log("|DNS-response|: %s is not exist\n", name);
err:
	return NULL;
}
示例#11
0
文件: core.c 项目: hornos/proxychains
int connect_proxy_chain( int sock, unsigned int target_ip, 
		unsigned short target_port, proxy_data *pd, 
		unsigned int proxy_count, chain_type ct, int max_chain )
{
	proxy_data p4;
	proxy_data *p1,*p2,*p3;
	int ns=-1;
	int offset=0;
	int alive_count=0;
	int curr_len=0;

#define TP "<>"
#define DT "|D-chain|"
#define ST "|S-chain|"
#define RT "|R-chain|"
	
	p3=&p4;

again:
	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))
				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;
		break;

	case STRICT_TYPE:
		alive_count=calc_alive(pd,proxy_count);
		offset=0;
		if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset)))
			goto error_strict;
		if(SUCCESS!=start_chain(&ns,p1,ST))
			goto error_strict;
		while(offset<proxy_count) {
			if(!(p2=select_proxy(FIFOLY,pd,proxy_count,&offset)))
				break;
			if(SUCCESS!=chain_step(ns,p1,p2))
				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))
				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;
			
	}

done:
	proxychains_write_log("<><>-OK\n");
	dup2(ns,sock);
	close(ns);
	return 0;
error:
	if(ns!=-1)
		close(ns);
	errno = ECONNREFUSED;  // for nmap ;)
	return -1;
	
error_more:
	proxychains_write_log("\n!!!need more proxies!!!\n");
error_strict:
	release_all(pd,proxy_count);
	if(ns!=-1)
		close(ns);
	errno = ETIMEDOUT;
	return -1;
}
示例#12
0
static void init_lib(void) {
	MUTEX_INIT(&internal_ips_lock, NULL);
	/* read the config file */
	get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);

	proxychains_write_log(LOG_PREFIX "DLL init\n");

	true_connect = (connect_t) dlsym(RTLD_NEXT, "connect");

	if(!true_connect) {
		fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'connect'" " real addr %p  wrapped addr %p\n", true_connect, connect);
	}
	if(connect == true_connect) {
		PDEBUG("circular reference detected, aborting!\n");
		abort();
	}

	true_gethostbyname = (gethostbyname_t)
	    dlsym(RTLD_NEXT, "gethostbyname");

	if(!true_gethostbyname) {
		fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'gethostbyname'"
		       " real addr %p  wrapped addr %p\n", true_gethostbyname, gethostbyname);
	}
	true_getaddrinfo = (getaddrinfo_t)
	    dlsym(RTLD_NEXT, "getaddrinfo");

	if(!true_getaddrinfo) {
		fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'getaddrinfo'" " real addr %p  wrapped addr %p\n", true_getaddrinfo, getaddrinfo);
	}
	true_freeaddrinfo = (freeaddrinfo_t)
	    dlsym(RTLD_NEXT, "freeaddrinfo");

	if(!true_freeaddrinfo) {
		fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'freeaddrinfo'"
		       " real addr %p  wrapped addr %p\n", true_freeaddrinfo, freeaddrinfo);
	}
	true_gethostbyaddr = (gethostbyaddr_t)
	    dlsym(RTLD_NEXT, "gethostbyaddr");

	if(!true_gethostbyaddr) {
		fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'gethostbyaddr'"
		       " real addr %p  wrapped addr %p\n", true_gethostbyaddr, gethostbyaddr);
	}
	true_getnameinfo = (getnameinfo_t)
	    dlsym(RTLD_NEXT, "getnameinfo");

	if(!true_getnameinfo) {
		fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n", dlerror());
		exit(1);
	} else {
		PDEBUG("loaded symbol 'getnameinfo'" " real addr %p  wrapped addr %p\n", true_getnameinfo, getnameinfo);
	}
	init_l = 1;
}
示例#13
0
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
	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;
	size_t l;
	struct hostent *hp;

	data->resolved_addr_p[0] = (char *) &data->resolved_addr;
	data->resolved_addr_p[1] = NULL;

	data->hostent_space.h_addr_list = data->resolved_addr_p;

	data->resolved_addr = 0;

	gethostname(buff, sizeof(buff));

	if(!strcmp(buff, name)) {
		data->resolved_addr = inet_addr(buff);
		if(data->resolved_addr == (in_addr_t) (-1))
			data->resolved_addr = (in_addr_t) (local_host.as_int);

		snprintf(hostname,sizeof hostname, "%s", name);
	    data->hostent_space.h_name = hostname;
	    data->hostent_space.h_length = sizeof (in_addr_t);
	    data->hostent_space.h_addrtype = AF_INET;

		return &data->hostent_space;
	}

	memset(buff, 0, sizeof(buff));

	while((hp = gethostent()))
		if(!strcmp(hp->h_name, name))
			return hp;

	hash = dalias_hash((char *) name);

	MUTEX_LOCK(&internal_ips_lock);

	// see if we already have this dns entry saved.
	if(internal_ips.counter) {
		for(i = 0; i < internal_ips.counter; i++) {
			if(internal_ips.list[i]->hash == hash && !strcmp(name, internal_ips.list[i]->string)) {
				data->resolved_addr = make_internal_ip(i);
				PDEBUG("got cached ip for %s\n", name);
				goto have_ip;
			}
		}
	}

	// 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 *));
		if(new_mem) {
			internal_ips.capa += 16;
			internal_ips.list = new_mem;
		} else {
	oom:
			proxychains_write_log("out of mem\n");
			goto err_plus_unlock;
		}
	}

	data->resolved_addr = make_internal_ip(internal_ips.counter);
	if(data->resolved_addr == (in_addr_t) - 1)
		goto err_plus_unlock;

	l = strlen(name);
	new_mem = malloc(sizeof(string_hash_tuple) + l + 1);
	if(!new_mem)
		goto oom;

	PDEBUG("creating new entry %d for ip of %s\n", (int) internal_ips.counter, name);

	internal_ips.list[internal_ips.counter] = new_mem;
	internal_ips.list[internal_ips.counter]->hash = hash;

	internal_ips.list[internal_ips.counter]->string = (char *) new_mem + sizeof(string_hash_tuple);

	memcpy(internal_ips.list[internal_ips.counter]->string, name, l + 1);

	internal_ips.counter += 1;

	have_ip:

	MUTEX_UNLOCK(&internal_ips_lock);

	strncpy(data->addr_name, name, sizeof(data->addr_name));

	data->hostent_space.h_name = data->addr_name;
	data->hostent_space.h_length = sizeof(in_addr_t);
	data->hostent_space.h_addrtype = AF_INET;

	return &data->hostent_space;

	err_plus_unlock:
	MUTEX_UNLOCK(&internal_ips_lock);
	return NULL;
}
示例#14
0
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;

	p3 = &p4;

	PDEBUG("connect_proxy_chain\n");

	again:

	switch (ct) {
		case DYNAMIC_TYPE:
			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)) {
					PDEBUG("GOTO AGAIN 1\n");
					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;
			break;

		/* Chain mirrors order it appears in config file and each
		 * proxy chain must be online.
		 */
		case STRICT_TYPE:
			/* Counts the number of proxy entries that are in the
			 * PLAY_STATE.
			 */
			calc_alive(pd, proxy_count);
			offset = 0;

			/* In this case, select_proxy will choose the next avilable
			 * proxy that is in the PLAY_STATE.
			 */
			if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
				PDEBUG("select_proxy failed\n");
				goto error_strict;
			}

			/* Connect to the first proxy server in the chain. */
			if(SUCCESS != start_chain(&ns, p1, ST)) {
				PDEBUG("start_chain failed\n");
				goto error_strict;
			}
			
			while(offset < proxy_count) {
				if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
					break;
				if(SUCCESS != chain_step(ns, p1, p2)) {
					PDEBUG("chain_step failed\n");
					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)) {
					PDEBUG("GOTO AGAIN 2\n");
					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);
	close(ns);
	return 0;
	error:
	if(ns != -1)
		close(ns);
	errno = ECONNREFUSED;	// for nmap ;)
	return -1;

	error_more:
	proxychains_write_log("\n!!!need more proxies!!!\n");
	error_strict:
	PDEBUG("error\n");

	release_all(pd, proxy_count);
	if(ns != -1)
		close(ns);
	errno = ETIMEDOUT;
	return -1;
}