mirror of
https://github.com/rofl0r/proxychains-ng
synced 2025-02-08 13:52:53 +08:00
Compare commits
7 Commits
acf2f4725d
...
2ab631918d
Author | SHA1 | Date | |
---|---|---|---|
|
2ab631918d | ||
|
3e791fd797 | ||
|
3a5050bec2 | ||
|
3dfda493d8 | ||
|
ed8f8444ab | ||
|
12e5da1b90 | ||
|
121c582d9c |
@ -20,6 +20,7 @@
|
|||||||
#include "ip_type.h"
|
#include "ip_type.h"
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "remotedns.h"
|
||||||
|
|
||||||
/* stuff for our internal translation table */
|
/* stuff for our internal translation table */
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ static ip_type4 ip_from_internal_list(char* name, size_t len) {
|
|||||||
internal_ips->list[internal_ips->counter] = new_mem;
|
internal_ips->list[internal_ips->counter] = new_mem;
|
||||||
internal_ips->list[internal_ips->counter]->hash = hash;
|
internal_ips->list[internal_ips->counter]->hash = hash;
|
||||||
|
|
||||||
new_mem = dumpstring((char*) name, len + 1);
|
new_mem = dumpstring((char*) name, len);
|
||||||
|
|
||||||
if(!new_mem) {
|
if(!new_mem) {
|
||||||
internal_ips->list[internal_ips->counter] = 0;
|
internal_ips->list[internal_ips->counter] = 0;
|
||||||
@ -138,23 +139,12 @@ static ip_type4 ip_from_internal_list(char* name, size_t len) {
|
|||||||
|
|
||||||
/* stuff for communication with the allocator thread */
|
/* stuff for communication with the allocator thread */
|
||||||
|
|
||||||
enum at_msgtype {
|
|
||||||
ATM_GETIP,
|
|
||||||
ATM_GETNAME,
|
|
||||||
ATM_EXIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum at_direction {
|
enum at_direction {
|
||||||
ATD_SERVER = 0,
|
ATD_SERVER = 0,
|
||||||
ATD_CLIENT,
|
ATD_CLIENT,
|
||||||
ATD_MAX,
|
ATD_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct at_msghdr {
|
|
||||||
enum at_msgtype msgtype;
|
|
||||||
size_t datalen;
|
|
||||||
};
|
|
||||||
|
|
||||||
static pthread_t allocator_thread;
|
static pthread_t allocator_thread;
|
||||||
int req_pipefd[2];
|
int req_pipefd[2];
|
||||||
int resp_pipefd[2];
|
int resp_pipefd[2];
|
||||||
@ -198,13 +188,11 @@ again:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sendmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
|
static int sendmessage(enum at_direction dir, struct at_msg *msg) {
|
||||||
static int* destfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[1], [ATD_CLIENT] = &resp_pipefd[1] };
|
static int* destfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[1], [ATD_CLIENT] = &resp_pipefd[1] };
|
||||||
int ret = trywrite(*destfd[dir], hdr, sizeof *hdr);
|
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||||
if(ret && hdr->datalen) {
|
int ret = trywrite(*destfd[dir], msg, sizeof (msg->h)+msg->h.datalen);
|
||||||
assert(hdr->datalen <= MSG_LEN_MAX);
|
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||||
ret = trywrite(*destfd[dir], data, hdr->datalen);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,17 +213,19 @@ again:
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static int readmsg(int fd, struct at_msg *msg) {
|
||||||
|
int ret = tryread(fd, msg, sizeof(msg->h));
|
||||||
|
if(ret != 1) return ret;
|
||||||
|
return tryread(fd, &msg->m, msg->h.datalen);
|
||||||
|
}
|
||||||
|
|
||||||
static int getmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
|
static int getmessage(enum at_direction dir, struct at_msg *msg) {
|
||||||
static int* readfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[0], [ATD_CLIENT] = &resp_pipefd[0] };
|
static int* readfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[0], [ATD_CLIENT] = &resp_pipefd[0] };
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
if((ret = wait_data(*readfd[dir]))) {
|
if((ret = wait_data(*readfd[dir]))) {
|
||||||
if(!tryread(*readfd[dir], hdr, sizeof *hdr))
|
if(!readmsg(*readfd[dir], msg))
|
||||||
return 0;
|
return 0;
|
||||||
assert(hdr->datalen <= MSG_LEN_MAX);
|
assert(msg->h.datalen <= MSG_LEN_MAX);
|
||||||
if(hdr->datalen) {
|
|
||||||
ret = tryread(*readfd[dir], data, hdr->datalen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -243,26 +233,24 @@ static int getmessage(enum at_direction dir, struct at_msghdr *hdr, void* data)
|
|||||||
static void* threadfunc(void* x) {
|
static void* threadfunc(void* x) {
|
||||||
(void) x;
|
(void) x;
|
||||||
int ret;
|
int ret;
|
||||||
struct at_msghdr msg;
|
struct at_msg msg;
|
||||||
union {
|
while((ret = getmessage(ATD_SERVER, &msg))) {
|
||||||
char host[MSG_LEN_MAX];
|
switch(msg.h.msgtype) {
|
||||||
ip_type4 ip;
|
|
||||||
} readbuf;
|
|
||||||
while((ret = getmessage(ATD_SERVER, &msg, &readbuf))) {
|
|
||||||
switch(msg.msgtype) {
|
|
||||||
case ATM_GETIP:
|
case ATM_GETIP:
|
||||||
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
|
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
|
||||||
* if not, create a new one. */
|
* if not, create a new one. */
|
||||||
readbuf.ip = ip_from_internal_list(readbuf.host, msg.datalen - 1);
|
msg.m.ip = ip_from_internal_list(msg.m.host, msg.h.datalen);
|
||||||
msg.datalen = sizeof(ip_type4);
|
msg.h.datalen = sizeof(ip_type4);
|
||||||
break;
|
break;
|
||||||
case ATM_GETNAME: {
|
case ATM_GETNAME: {
|
||||||
char *host = string_from_internal_ip(readbuf.ip);
|
char *host = string_from_internal_ip(msg.m.ip);
|
||||||
if(host) {
|
if(host) {
|
||||||
size_t l = strlen(host);
|
size_t l = strlen(host);
|
||||||
assert(l < MSG_LEN_MAX);
|
assert(l+1 < MSG_LEN_MAX);
|
||||||
memcpy(readbuf.host, host, l + 1);
|
memcpy(msg.m.host, host, l + 1);
|
||||||
msg.datalen = l + 1;
|
msg.h.datalen = l + 1;
|
||||||
|
} else {
|
||||||
|
msg.h.datalen = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -271,7 +259,7 @@ static void* threadfunc(void* x) {
|
|||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
ret = sendmessage(ATD_CLIENT, &msg, &readbuf);
|
ret = sendmessage(ATD_CLIENT, &msg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -282,27 +270,31 @@ ip_type4 at_get_ip_for_host(char* host, size_t len) {
|
|||||||
ip_type4 readbuf;
|
ip_type4 readbuf;
|
||||||
MUTEX_LOCK(internal_ips_lock);
|
MUTEX_LOCK(internal_ips_lock);
|
||||||
if(len > MSG_LEN_MAX) goto inv;
|
if(len > MSG_LEN_MAX) goto inv;
|
||||||
struct at_msghdr msg = {.msgtype = ATM_GETIP, .datalen = len + 1 };
|
struct at_msg msg = {.h.msgtype = ATM_GETIP, .h.datalen = len + 1 };
|
||||||
if(sendmessage(ATD_SERVER, &msg, host) &&
|
memcpy(msg.m.host, host, len+1);
|
||||||
getmessage(ATD_CLIENT, &msg, &readbuf));
|
if(sendmessage(ATD_SERVER, &msg) &&
|
||||||
|
getmessage(ATD_CLIENT, &msg)) readbuf = msg.m.ip;
|
||||||
else {
|
else {
|
||||||
inv:
|
inv:
|
||||||
readbuf = ip_type_invalid.addr.v4;
|
readbuf = ip_type_invalid.addr.v4;
|
||||||
}
|
}
|
||||||
assert(msg.msgtype == ATM_GETIP);
|
assert(msg.h.msgtype == ATM_GETIP);
|
||||||
MUTEX_UNLOCK(internal_ips_lock);
|
MUTEX_UNLOCK(internal_ips_lock);
|
||||||
return readbuf;
|
return readbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t at_get_host_for_ip(ip_type4 ip, char* readbuf) {
|
size_t at_get_host_for_ip(ip_type4 ip, char* readbuf) {
|
||||||
struct at_msghdr msg = {.msgtype = ATM_GETNAME, .datalen = sizeof(ip_type4) };
|
struct at_msg msg = {.h.msgtype = ATM_GETNAME, .h.datalen = sizeof(ip_type4), .m.ip = ip };
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
MUTEX_LOCK(internal_ips_lock);
|
MUTEX_LOCK(internal_ips_lock);
|
||||||
if(sendmessage(ATD_SERVER, &msg, &ip) && getmessage(ATD_CLIENT, &msg, readbuf)) {
|
if(sendmessage(ATD_SERVER, &msg) && getmessage(ATD_CLIENT, &msg)) {
|
||||||
if((ptrdiff_t) msg.datalen <= 0) res = 0;
|
if((int16_t) msg.h.datalen <= 0) res = 0;
|
||||||
else res = msg.datalen - 1;
|
else {
|
||||||
|
memcpy(readbuf, msg.m.host, msg.h.datalen);
|
||||||
|
res = msg.h.datalen - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(msg.msgtype == ATM_GETNAME);
|
assert(msg.h.msgtype == ATM_GETNAME);
|
||||||
MUTEX_UNLOCK(internal_ips_lock);
|
MUTEX_UNLOCK(internal_ips_lock);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
91
src/core.c
91
src/core.c
@ -43,6 +43,7 @@
|
|||||||
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;
|
||||||
|
extern int proxychains_resolver;
|
||||||
extern unsigned int proxychains_proxy_offset;
|
extern unsigned int proxychains_proxy_offset;
|
||||||
extern unsigned int remote_dns_subnet;
|
extern unsigned int remote_dns_subnet;
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
// 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 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
|
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
|
||||||
if(!ip.is_v6 && ip.addr.v4.octet[0] == remote_dns_subnet) {
|
if(!ip.is_v6 && proxychains_resolver && ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||||
dns_len = at_get_host_for_ip(ip.addr.v4, hostnamebuf);
|
dns_len = at_get_host_for_ip(ip.addr.v4, hostnamebuf);
|
||||||
if(!dns_len) goto err;
|
if(!dns_len) goto err;
|
||||||
else dns_name = hostnamebuf;
|
else dns_name = hostnamebuf;
|
||||||
@ -524,7 +525,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
|
|
||||||
PFUNC();
|
PFUNC();
|
||||||
|
|
||||||
if(!v6 && pto->ip.addr.v4.octet[0] == remote_dns_subnet) {
|
if(!v6 && proxychains_resolver && pto->ip.addr.v4.octet[0] == remote_dns_subnet) {
|
||||||
if(!at_get_host_for_ip(pto->ip.addr.v4, hostname_buf)) goto usenumericip;
|
if(!at_get_host_for_ip(pto->ip.addr.v4, hostname_buf)) goto usenumericip;
|
||||||
else hostname = hostname_buf;
|
else hostname = hostname_buf;
|
||||||
} else {
|
} else {
|
||||||
@ -744,6 +745,86 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char*
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern ip_type4 hostsreader_get_numeric_ip_for_name(const char* name);
|
extern ip_type4 hostsreader_get_numeric_ip_for_name(const char* name);
|
||||||
|
struct hostent* proxy_gethostbyname_old(const char *name)
|
||||||
|
{
|
||||||
|
static struct hostent hostent_space;
|
||||||
|
static in_addr_t resolved_addr;
|
||||||
|
static char* resolved_addr_p;
|
||||||
|
static char addr_name[1024*8];
|
||||||
|
|
||||||
|
int pipe_fd[2];
|
||||||
|
char buff[256];
|
||||||
|
in_addr_t addr;
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
size_t l;
|
||||||
|
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;
|
||||||
|
|
||||||
|
memset(buff, 0, 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);
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
dup2(pipe_fd[1],1);
|
||||||
|
close(pipe_fd[1]);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
buff[0] = 0;
|
||||||
|
read(pipe_fd[0],&buff,sizeof(buff));
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
got_buff:
|
||||||
|
l = strlen(buff);
|
||||||
|
if(l && buff[l-1] == '\n') buff[l-1] = 0;
|
||||||
|
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_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 does not exist\n", name);
|
||||||
|
perror("err_dns");
|
||||||
|
err:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
|
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
|
||||||
PFUNC();
|
PFUNC();
|
||||||
char buff[256];
|
char buff[256];
|
||||||
@ -871,7 +952,11 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
|
|||||||
free(space);
|
free(space);
|
||||||
return EAI_NONAME;
|
return EAI_NONAME;
|
||||||
}
|
}
|
||||||
hp = proxy_gethostbyname(node, &ghdata);
|
if(proxychains_resolver == 2)
|
||||||
|
hp = proxy_gethostbyname_old(node);
|
||||||
|
else
|
||||||
|
hp = proxy_gethostbyname(node, &ghdata);
|
||||||
|
|
||||||
if(hp)
|
if(hp)
|
||||||
memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr,
|
memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr,
|
||||||
*(hp->h_addr_list), sizeof(in_addr_t));
|
*(hp->h_addr_list), sizeof(in_addr_t));
|
||||||
|
@ -121,6 +121,7 @@ struct gethostbyname_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct hostent* proxy_gethostbyname(const char *name, struct gethostbyname_data *data);
|
struct hostent* proxy_gethostbyname(const char *name, struct gethostbyname_data *data);
|
||||||
|
struct hostent* proxy_gethostbyname_old(const char *name);
|
||||||
|
|
||||||
int proxy_getaddrinfo(const char *node, const char *service,
|
int proxy_getaddrinfo(const char *node, const char *service,
|
||||||
const struct addrinfo *hints, struct addrinfo **res);
|
const struct addrinfo *hints, struct addrinfo **res);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# include "debug.h"
|
# include "debug.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count) {
|
void dump_proxy_chain(proxy_data *pchain, unsigned int count) {
|
||||||
char ip_buf[INET6_ADDRSTRLEN];
|
char ip_buf[INET6_ADDRSTRLEN];
|
||||||
for (; count; pchain++, count--) {
|
for (; count; pchain++, count--) {
|
||||||
if(!inet_ntop(pchain->ip.is_v6?AF_INET6:AF_INET,pchain->ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
if(!inet_ntop(pchain->ip.is_v6?AF_INET6:AF_INET,pchain->ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
||||||
|
12
src/debug.h
12
src/debug.h
@ -1,15 +1,13 @@
|
|||||||
#ifndef DEBUG_H
|
#ifndef DEBUG_H
|
||||||
#define DEBUG_H
|
#define DEBUG_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
# define PSTDERR(fmt, args...) do { dprintf(2,fmt, ## args); } while(0)
|
# define PSTDERR(fmt, args...) do { dprintf(2,fmt, ## args); } while(0)
|
||||||
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
|
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
|
||||||
# define DEBUGDECL(args...) args
|
# define DEBUGDECL(args...) args
|
||||||
|
# define DUMP_PROXY_CHAIN(A, B) dump_proxy_chain(A, B)
|
||||||
# include "core.h"
|
|
||||||
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define PDEBUG(fmt, args...) do {} while (0)
|
# define PDEBUG(fmt, args...) do {} while (0)
|
||||||
# define DEBUGDECL(args...)
|
# define DEBUGDECL(args...)
|
||||||
@ -18,5 +16,9 @@ void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
|
|||||||
|
|
||||||
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
|
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
void dump_proxy_chain(proxy_data *pchain, unsigned int count);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -116,19 +116,24 @@ static void setup_hooks(void) {
|
|||||||
SETUP_SYM(freeaddrinfo);
|
SETUP_SYM(freeaddrinfo);
|
||||||
SETUP_SYM(gethostbyaddr);
|
SETUP_SYM(gethostbyaddr);
|
||||||
SETUP_SYM(getnameinfo);
|
SETUP_SYM(getnameinfo);
|
||||||
SETUP_SYM(close);
|
|
||||||
#ifdef IS_SOLARIS
|
#ifdef IS_SOLARIS
|
||||||
SETUP_SYM(__xnet_connect);
|
SETUP_SYM(__xnet_connect);
|
||||||
#endif
|
#endif
|
||||||
|
SETUP_SYM(close);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int close_fds[16];
|
static int close_fds[16];
|
||||||
static int close_fds_cnt = 0;
|
static int close_fds_cnt = 0;
|
||||||
|
|
||||||
|
static void rdns_init(void) {
|
||||||
|
static int init_done = 0;
|
||||||
|
if(!init_done) at_init();
|
||||||
|
init_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void do_init(void) {
|
static void do_init(void) {
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
core_initialize();
|
core_initialize();
|
||||||
at_init();
|
|
||||||
|
|
||||||
/* read the config file */
|
/* read the config file */
|
||||||
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
||||||
@ -139,8 +144,9 @@ static void do_init(void) {
|
|||||||
setup_hooks();
|
setup_hooks();
|
||||||
|
|
||||||
while(close_fds_cnt) true_close(close_fds[--close_fds_cnt]);
|
while(close_fds_cnt) true_close(close_fds[--close_fds_cnt]);
|
||||||
|
|
||||||
init_l = 1;
|
init_l = 1;
|
||||||
|
|
||||||
|
if(proxychains_resolver == 1) rdns_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_lib_wrapper(const char* caller) {
|
static void init_lib_wrapper(const char* caller) {
|
||||||
@ -278,6 +284,8 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||||||
if(proxychains_got_chain_data)
|
if(proxychains_got_chain_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PFUNC();
|
||||||
|
|
||||||
//Some defaults
|
//Some defaults
|
||||||
tcp_read_time_out = 4 * 1000;
|
tcp_read_time_out = 4 * 1000;
|
||||||
tcp_connect_time_out = 10 * 1000;
|
tcp_connect_time_out = 10 * 1000;
|
||||||
@ -320,8 +328,9 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
|||||||
pd[count].port = htons((unsigned short) port_n);
|
pd[count].port = htons((unsigned short) port_n);
|
||||||
ip_type* host_ip = &pd[count].ip;
|
ip_type* host_ip = &pd[count].ip;
|
||||||
if(1 != inet_pton(host_ip->is_v6 ? AF_INET6 : AF_INET, host, host_ip->addr.v6)) {
|
if(1 != inet_pton(host_ip->is_v6 ? AF_INET6 : AF_INET, host, host_ip->addr.v6)) {
|
||||||
if(*ct == STRICT_TYPE && proxychains_resolver && count > 0) {
|
if(*ct == STRICT_TYPE && proxychains_resolver == 1 && count > 0) {
|
||||||
/* we can allow dns hostnames for all but the first proxy in the list if chaintype is strict, as remote lookup can be done */
|
/* we can allow dns hostnames for all but the first proxy in the list if chaintype is strict, as remote lookup can be done */
|
||||||
|
rdns_init();
|
||||||
ip_type4 internal_ip = at_get_ip_for_host(host, strlen(host));
|
ip_type4 internal_ip = at_get_ip_for_host(host, strlen(host));
|
||||||
pd[count].ip.is_v6 = 0;
|
pd[count].ip.is_v6 = 0;
|
||||||
host_ip->addr.v4 = internal_ip;
|
host_ip->addr.v4 = internal_ip;
|
||||||
@ -422,6 +431,8 @@ inv_host:
|
|||||||
proxychains_max_chain = (len ? len : 1);
|
proxychains_max_chain = (len ? len : 1);
|
||||||
} else if(strstr(buff, "quiet_mode")) {
|
} else if(strstr(buff, "quiet_mode")) {
|
||||||
proxychains_quiet_mode = 1;
|
proxychains_quiet_mode = 1;
|
||||||
|
} else if(strstr(buff, "proxy_dns_old")) {
|
||||||
|
proxychains_resolver = 2;
|
||||||
} else if(strstr(buff, "proxy_dns")) {
|
} else if(strstr(buff, "proxy_dns")) {
|
||||||
proxychains_resolver = 1;
|
proxychains_resolver = 1;
|
||||||
} else if(strstr(buff, "dnat")) {
|
} else if(strstr(buff, "dnat")) {
|
||||||
@ -486,7 +497,7 @@ inv_host:
|
|||||||
}
|
}
|
||||||
*proxy_count = count;
|
*proxy_count = count;
|
||||||
proxychains_got_chain_data = 1;
|
proxychains_got_chain_data = 1;
|
||||||
PDEBUG("proxy_dns: %s\n", proxychains_resolver ? "ON" : "OFF");
|
PDEBUG("proxy_dns: %s\n", proxychains_resolver ? (proxychains_resolver == 2 ? "OLD" : "ON") : "OFF");
|
||||||
}
|
}
|
||||||
|
|
||||||
/******* HOOK FUNCTIONS *******/
|
/******* HOOK FUNCTIONS *******/
|
||||||
@ -498,6 +509,8 @@ int close(int fd) {
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(proxychains_resolver != 1) return true_close(fd);
|
||||||
|
|
||||||
/* prevent rude programs (like ssh) from closing our pipes */
|
/* prevent rude programs (like ssh) from closing our pipes */
|
||||||
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
|
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
|
||||||
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
|
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
|
||||||
@ -611,8 +624,10 @@ struct hostent *gethostbyname(const char *name) {
|
|||||||
INIT();
|
INIT();
|
||||||
PDEBUG("gethostbyname: %s\n", name);
|
PDEBUG("gethostbyname: %s\n", name);
|
||||||
|
|
||||||
if(proxychains_resolver)
|
if(proxychains_resolver == 1)
|
||||||
return proxy_gethostbyname(name, &ghbndata);
|
return proxy_gethostbyname(name, &ghbndata);
|
||||||
|
else if(proxychains_resolver == 2)
|
||||||
|
return proxy_gethostbyname_old(name);
|
||||||
else
|
else
|
||||||
return true_gethostbyname(name);
|
return true_gethostbyname(name);
|
||||||
|
|
||||||
|
@ -49,8 +49,16 @@ strict_chain
|
|||||||
#quiet_mode
|
#quiet_mode
|
||||||
|
|
||||||
# Proxy DNS requests - no leak for DNS data
|
# Proxy DNS requests - no leak for DNS data
|
||||||
|
# this uses the proxychains4 style method to do remote dns
|
||||||
proxy_dns
|
proxy_dns
|
||||||
|
|
||||||
|
# use the old proxyresolv script to proxy DNS requests
|
||||||
|
# in proxychains 3.1 style. requires proxyresolv in $PATH
|
||||||
|
# plus a dynamically linked `dig` binary.
|
||||||
|
# this is a lot slower than `proxy_dns`, doesn't support .onion URLs,
|
||||||
|
# but might be more compatible with complex software like webbrowsers.
|
||||||
|
#proxy_dns_old
|
||||||
|
|
||||||
# set the class A subnet number to use for the internal remote DNS mapping
|
# set the class A subnet number to use for the internal remote DNS mapping
|
||||||
# we use the reserved 224.x.x.x range by default,
|
# we use the reserved 224.x.x.x range by default,
|
||||||
# if the proxified app does a DNS request, we will return an IP from that range.
|
# if the proxified app does a DNS request, we will return an IP from that range.
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# This is a legacy script that uses "dig" to do DNS lookups via TCP.
|
# This is a legacy script that uses "dig" or "drill" to do DNS lookups via TCP.
|
||||||
# it is not actively maintained since proxychains no longer depends
|
|
||||||
# on it. i leave it here as a bonus.
|
|
||||||
|
|
||||||
# DNS server used to resolve names
|
# DNS server used to resolve names
|
||||||
DNS_SERVER=8.8.8.8
|
test -z "$DNS_SERVER" && DNS_SERVER=8.8.8.8
|
||||||
|
|
||||||
|
|
||||||
if [ $# = 0 ] ; then
|
if [ $# = 0 ] ; then
|
||||||
@ -14,5 +12,12 @@ if [ $# = 0 ] ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
export LD_PRELOAD=libproxychains4.so
|
test -z $LD_PRELOAD && export LD_PRELOAD=libproxychains4.so
|
||||||
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
|
||||||
|
if type dig 1>/dev/null 2>&1 ; then
|
||||||
|
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
||||||
|
elif type drill 1>/dev/null 2>&1 ; then
|
||||||
|
drill -t4 $1 @$DNS_SERVER | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
|
||||||
|
else
|
||||||
|
echo "error: neither dig nor drill found" >&2
|
||||||
|
fi
|
||||||
|
29
src/remotedns.h
Normal file
29
src/remotedns.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef REMOTEDNS_H
|
||||||
|
#define REMOTEDNS_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "ip_type.h"
|
||||||
|
|
||||||
|
enum at_msgtype {
|
||||||
|
ATM_GETIP = 0,
|
||||||
|
ATM_GETNAME,
|
||||||
|
ATM_FAIL,
|
||||||
|
ATM_EXIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct at_msghdr {
|
||||||
|
unsigned char msgtype; /* at_msgtype */
|
||||||
|
char reserved;
|
||||||
|
unsigned short datalen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct at_msg {
|
||||||
|
struct at_msghdr h;
|
||||||
|
union {
|
||||||
|
char host[260];
|
||||||
|
ip_type4 ip;
|
||||||
|
} m;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user