mirror of
https://github.com/rofl0r/proxychains-ng
synced 2025-01-02 09:33:06 +08:00
Merge 53f5e07574
into 1760c93474
This commit is contained in:
commit
76c4c11cf8
@ -24,6 +24,7 @@
|
||||
#ifndef __CORE_HEADER
|
||||
#define __CORE_HEADER
|
||||
#define MAX_LOCALNET 64
|
||||
#define MAX_REMOTENET 64
|
||||
#define MAX_DNAT 64
|
||||
|
||||
#include "ip_type.h"
|
||||
@ -77,7 +78,7 @@ typedef struct {
|
||||
unsigned char in6_prefix;
|
||||
};
|
||||
};
|
||||
} localaddr_arg;
|
||||
} addr_arg;
|
||||
|
||||
typedef struct {
|
||||
struct in_addr orig_dst, new_dst;
|
||||
@ -106,10 +107,10 @@ typedef struct hostent* (*gethostbyname_t)(const char *);
|
||||
typedef void (*freeaddrinfo_t)(struct addrinfo *);
|
||||
typedef struct hostent *(*gethostbyaddr_t) (const void *, socklen_t, int);
|
||||
|
||||
typedef int (*getaddrinfo_t)(const char *, const char *, const struct addrinfo *,
|
||||
typedef int (*getaddrinfo_t)(const char *, const char *, const struct addrinfo *,
|
||||
struct addrinfo **);
|
||||
|
||||
typedef int (*getnameinfo_t) (const struct sockaddr *, socklen_t, char *,
|
||||
typedef int (*getnameinfo_t) (const struct sockaddr *, socklen_t, char *,
|
||||
GN_NODELEN_T, char *, GN_SERVLEN_T, GN_FLAGS_T);
|
||||
|
||||
typedef ssize_t (*sendto_t) (int sockfd, const void *buf, size_t len, int flags,
|
||||
@ -134,7 +135,7 @@ struct gethostbyname_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);
|
||||
void proxy_freeaddrinfo(struct addrinfo *res);
|
||||
|
||||
|
@ -75,8 +75,10 @@ int proxychains_got_chain_data = 0;
|
||||
unsigned int proxychains_max_chain = 1;
|
||||
int proxychains_quiet_mode = 0;
|
||||
enum dns_lookup_flavor proxychains_resolver = DNSLF_LIBC;
|
||||
localaddr_arg localnet_addr[MAX_LOCALNET];
|
||||
addr_arg localnet_addr[MAX_LOCALNET];
|
||||
addr_arg remotenet_addr[MAX_REMOTENET];
|
||||
size_t num_localnet_addr = 0;
|
||||
size_t num_remotenet_addr = 0;
|
||||
dnat_arg dnats[MAX_DNAT];
|
||||
size_t num_dnats = 0;
|
||||
unsigned int remote_dns_subnet = 224;
|
||||
@ -115,7 +117,7 @@ typedef struct {
|
||||
unsigned int first, last, flags;
|
||||
} close_range_args_t;
|
||||
|
||||
/* If there is some `close` or `close_range` system call before do_init,
|
||||
/* If there is some `close` or `close_range` system call before do_init,
|
||||
we buffer it, and actually execute them in do_init. */
|
||||
static int close_fds[16];
|
||||
static int close_fds_cnt = 0;
|
||||
@ -291,6 +293,7 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
|
||||
char buf[1024], type[1024], host[1024], user[1024];
|
||||
char *buff, *env, *p;
|
||||
char local_addr_port[64], local_addr[64], local_netmask[32];
|
||||
char remote_addr_port[64], remote_addr[64], remote_netmask[32];
|
||||
char dnat_orig_addr_port[32], dnat_new_addr_port[32];
|
||||
char dnat_orig_addr[32], dnat_orig_port[32], dnat_new_addr[32], dnat_new_port[32];
|
||||
char rdnsd_addr[32], rdnsd_port[8];
|
||||
@ -475,6 +478,81 @@ inv_host:
|
||||
} else {
|
||||
fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET);
|
||||
}
|
||||
} else if(STR_STARTSWITH(buff, "remotenet")) {
|
||||
char colon, extra, right_bracket[2];
|
||||
unsigned short remote_port = 0, remote_prefix;
|
||||
int remote_family, n, valid;
|
||||
if(sscanf(buff, "%s %53[^/]/%15s%c", user, remote_addr_port, remote_netmask, &extra) != 3) {
|
||||
fprintf(stderr, "remotenet format error");
|
||||
exit(1);
|
||||
}
|
||||
p = strchr(remote_addr_port, ':');
|
||||
if(!p || p == strrchr(remote_addr_port, ':')) {
|
||||
remote_family = AF_INET;
|
||||
n = sscanf(remote_addr_port, "%15[^:]%c%5hu%c", remote_addr, &colon, &remote_port, &extra);
|
||||
valid = n == 1 || (n == 3 && colon == ':');
|
||||
} else if(remote_addr_port[0] == '[') {
|
||||
remote_family = AF_INET6;
|
||||
n = sscanf(remote_addr_port, "[%45[^][]%1[]]%c%5hu%c", remote_addr, right_bracket, &colon, &remote_port, &extra);
|
||||
valid = n == 2 || (n == 4 && colon == ':');
|
||||
} else {
|
||||
remote_family = AF_INET6;
|
||||
valid = sscanf(remote_addr_port, "%45[^][]%c", remote_addr, &extra) == 1;
|
||||
}
|
||||
if(!valid) {
|
||||
fprintf(stderr, "remotenet address or port error\n");
|
||||
exit(1);
|
||||
}
|
||||
if(remote_port) {
|
||||
PDEBUG("added remotenet: netaddr=%s, port=%u, netmask=%s\n",
|
||||
remote_addr, remote_port, remote_netmask);
|
||||
} else {
|
||||
PDEBUG("added remotenet: netaddr=%s, netmask=%s\n",
|
||||
remote_addr, remote_netmask);
|
||||
}
|
||||
if(num_remotenet_addr < MAX_REMOTENET) {
|
||||
remotenet_addr[num_remotenet_addr].family = remote_family;
|
||||
remotenet_addr[num_remotenet_addr].port = remote_port;
|
||||
valid = 0;
|
||||
if (remote_family == AF_INET) {
|
||||
valid =
|
||||
inet_pton(remote_family, remote_addr,
|
||||
&remotenet_addr[num_remotenet_addr].in_addr) > 0;
|
||||
} else if(remote_family == AF_INET6) {
|
||||
valid =
|
||||
inet_pton(remote_family, remote_addr,
|
||||
&remotenet_addr[num_remotenet_addr].in6_addr) > 0;
|
||||
}
|
||||
if(!valid) {
|
||||
fprintf(stderr, "remotenet address error\n");
|
||||
exit(1);
|
||||
}
|
||||
if(remote_family == AF_INET && strchr(remote_netmask, '.')) {
|
||||
valid =
|
||||
inet_pton(remote_family, remote_netmask,
|
||||
&remotenet_addr[num_remotenet_addr].in_mask) > 0;
|
||||
} else {
|
||||
valid = sscanf(remote_netmask, "%hu%c", &remote_prefix, &extra) == 1;
|
||||
if (valid) {
|
||||
if(remote_family == AF_INET && remote_prefix <= 32) {
|
||||
remotenet_addr[num_remotenet_addr].in_mask.s_addr =
|
||||
htonl(0xFFFFFFFFu << (32u - remote_prefix));
|
||||
} else if(remote_family == AF_INET6 && remote_prefix <= 128) {
|
||||
remotenet_addr[num_remotenet_addr].in6_prefix =
|
||||
remote_prefix;
|
||||
} else {
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!valid) {
|
||||
fprintf(stderr, "remotenet netmask error\n");
|
||||
exit(1);
|
||||
}
|
||||
++num_remotenet_addr;
|
||||
} else {
|
||||
fprintf(stderr, "# of remotenet exceed %d.\n", MAX_REMOTENET);
|
||||
}
|
||||
} else if(STR_STARTSWITH(buff, "chain_len")) {
|
||||
char *pc;
|
||||
int len;
|
||||
@ -639,7 +717,7 @@ HOOKFUNC(int, close_range, unsigned first, unsigned last, int flags) {
|
||||
int protected_fds[] = {req_pipefd[0], req_pipefd[1], resp_pipefd[0], resp_pipefd[1]};
|
||||
intsort(protected_fds, 4);
|
||||
/* We are skipping protected_fds while calling true_close_range()
|
||||
* If protected_fds cut the range into some sub-ranges, we close sub-ranges BEFORE cut point in the loop.
|
||||
* If protected_fds cut the range into some sub-ranges, we close sub-ranges BEFORE cut point in the loop.
|
||||
* [first, cut1-1] , [cut1+1, cut2-1] , [cut2+1, cut3-1]
|
||||
* Finally, we delete the remaining sub-range, outside the loop. [cut3+1, tail]
|
||||
*/
|
||||
@ -749,6 +827,31 @@ HOOKFUNC(int, connect, int sock, const struct sockaddr *addr, unsigned int len)
|
||||
return true_connect(sock, addr, len);
|
||||
}
|
||||
|
||||
int remote_connect = (remote_dns_connect||num_remotenet_addr==0);
|
||||
for(i = 0; i < num_remotenet_addr && !remote_connect; i++) {
|
||||
if (remotenet_addr[i].port && remotenet_addr[i].port != port)
|
||||
continue;
|
||||
if (remotenet_addr[i].family != (v6 ? AF_INET6 : AF_INET))
|
||||
continue;
|
||||
if (v6) {
|
||||
size_t prefix_bytes = remotenet_addr[i].in6_prefix / CHAR_BIT;
|
||||
size_t prefix_bits = remotenet_addr[i].in6_prefix % CHAR_BIT;
|
||||
if (prefix_bytes && memcmp(p_addr_in6->s6_addr, remotenet_addr[i].in6_addr.s6_addr, prefix_bytes) != 0)
|
||||
continue;
|
||||
if (prefix_bits && (p_addr_in6->s6_addr[prefix_bytes] ^ remotenet_addr[i].in6_addr.s6_addr[prefix_bytes]) >> (CHAR_BIT - prefix_bits))
|
||||
continue;
|
||||
} else {
|
||||
if((p_addr_in->s_addr ^ remotenet_addr[i].in_addr.s_addr) & remotenet_addr[i].in_mask.s_addr)
|
||||
continue;
|
||||
}
|
||||
remote_connect = 1;
|
||||
}
|
||||
|
||||
if( !remote_connect ) {
|
||||
PDEBUG("accessing non-remotenet using true_connect\n");
|
||||
return true_connect(sock, addr, len);
|
||||
}
|
||||
|
||||
flags = fcntl(sock, F_GETFL, 0);
|
||||
if(flags & O_NONBLOCK)
|
||||
fcntl(sock, F_SETFL, !O_NONBLOCK);
|
||||
|
@ -79,12 +79,12 @@ proxy_dns
|
||||
# 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.
|
||||
# on further accesses to this ip we will send the saved DNS name to the proxy.
|
||||
# in case some control-freak app checks the returned ip, and denies to
|
||||
# in case some control-freak app checks the returned ip, and denies to
|
||||
# connect, you can use another subnet, e.g. 10.x.x.x or 127.x.x.x.
|
||||
# of course you should make sure that the proxified app does not need
|
||||
# *real* access to this subnet.
|
||||
# *real* access to this subnet.
|
||||
# i.e. dont use the same subnet then in the localnet section
|
||||
#remote_dns_subnet 127
|
||||
#remote_dns_subnet 127
|
||||
#remote_dns_subnet 10
|
||||
remote_dns_subnet 224
|
||||
|
||||
@ -109,7 +109,7 @@ tcp_connect_time_out 8000
|
||||
|
||||
## RFC6890 Loopback address range
|
||||
## if you enable this, you have to make sure remote_dns_subnet is not 127
|
||||
## you'll need to enable it if you want to use an application that
|
||||
## you'll need to enable it if you want to use an application that
|
||||
## connects to localhost.
|
||||
# localnet 127.0.0.0/255.0.0.0
|
||||
# localnet ::1/128
|
||||
@ -119,6 +119,20 @@ tcp_connect_time_out 8000
|
||||
# localnet 172.16.0.0/255.240.0.0
|
||||
# localnet 192.168.0.0/255.255.0.0
|
||||
|
||||
### Examples for remotenet that will use a proxy to connect
|
||||
## only remotenet ranges except localnet ranges will use a proxy to connect.
|
||||
## default(means all connections except localnet ranges will use a proxy):
|
||||
## remotenet ::/0
|
||||
## remotenet 0.0.0.0/0.0.0.0
|
||||
|
||||
## Connections to 31.13.94.36 with port 80 and 443 will use a proxy:
|
||||
# remotenet 31.13.94.36:80/255.255.255.255
|
||||
# remotenet 31.13.94.36:443/255.255.255.255
|
||||
|
||||
## Connections to anywhere with port 25 will use a proxy:
|
||||
# remotenet 0.0.0.0:25/0.0.0.0
|
||||
# remotenet [::]:25/0
|
||||
|
||||
### Examples for dnat
|
||||
## Trying to proxy connections to destinations which are dnatted,
|
||||
## will result in proxying connections to the new given destinations.
|
||||
@ -147,8 +161,8 @@ tcp_connect_time_out 8000
|
||||
# socks5 192.168.67.78 1080 lamer secret
|
||||
# http 192.168.89.3 8080 justu hidden
|
||||
# socks4 192.168.1.49 1080
|
||||
# http 192.168.39.93 8080
|
||||
#
|
||||
# http 192.168.39.93 8080
|
||||
#
|
||||
#
|
||||
# proxy types: http, socks4, socks5, raw
|
||||
# * raw: The traffic is simply forwarded to the proxy without modification.
|
||||
|
Loading…
Reference in New Issue
Block a user