v5.60 rewrite core functions (check change log)
This commit is contained in:
36
README.md
36
README.md
@@ -1,16 +1,16 @@
|
|||||||
ProxyBound v5.50
|
ProxyBound v5.60
|
||||||
================
|
================
|
||||||
|
|
||||||
ProxyBound is a UNIX program, that hooks network-related libc functions in dynamically linked programs via a preloaded DLL and redirects the connections through SOCKS4a/5 or HTTP proxies. This is based on proxychains-ng by rofl0r, proxychains by haad and torsocks by dgoulet
|
ProxyBound force any unix application to use a specific proxy and prevent it from leaking the original ip; Technically, ProxyBound is a UNIX program, that hooks network-related libc functions in dynamically linked programs via a preloaded DLL and redirects the connections through SOCKS4A/5 or HTTP proxies. This project is based on proxychain by [netcreature](https://sourceforge.net/u/netcreature/profile/), proxychains-ng by rofl0r, proxychains by haad and torsocks by dgoulet
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
=========
|
=========
|
||||||
|
|
||||||
- Proxify applications (like mainstream proxychains)
|
- Proxify applications (like mainstream proxychains)
|
||||||
- Works with tcp (like mainstream proxychains)
|
- Works with tcp (like mainstream proxychains)
|
||||||
- No leaks over udp/raw/icmp/etc...
|
- No leaks over udp/icmp/etc... (INET & INET6)
|
||||||
- Unsupported protocols are blocked
|
- Unsupported protocols are blocked
|
||||||
- Works with chrome/chromium/similar
|
- Support chrome/chromium/skype/similar
|
||||||
- Incompatible applications are terminated with a proper message
|
- Incompatible applications are terminated with a proper message
|
||||||
- Many additional settings over environment variable
|
- Many additional settings over environment variable
|
||||||
- etc.
|
- etc.
|
||||||
@@ -25,7 +25,7 @@ Used environment variable:
|
|||||||
- PROXYBOUND_SOCKS5_PORT: Socks 5 port (default not used)
|
- PROXYBOUND_SOCKS5_PORT: Socks 5 port (default not used)
|
||||||
- PROXYBOUND_FORCE_DNS: Force dns resolv requests through (1 or 0, default 1)
|
- PROXYBOUND_FORCE_DNS: Force dns resolv requests through (1 or 0, default 1)
|
||||||
- PROXYBOUND_ALLOW_DNS: Allow direct dns, allow udp port 53 and 853 (1 or 0, default 0)
|
- PROXYBOUND_ALLOW_DNS: Allow direct dns, allow udp port 53 and 853 (1 or 0, default 0)
|
||||||
- PROXYBOUND_ALLOW_LEAKS: Allow/Block unproxyfied protocols "UDP/ICMP/RAW", blocked by default (1 or 0, default 0)
|
- PROXYBOUND_ALLOW_LEAKS: Allow/Block unproxyfied protocols "UDP/ICMP/ETC", blocked by default (1 or 0, default 0)
|
||||||
- PROXYBOUND_WORKING_INDICATOR: Create '/tmp/proxybound.tmp' when dll is working as intended (1 or 0, default 0)
|
- PROXYBOUND_WORKING_INDICATOR: Create '/tmp/proxybound.tmp' when dll is working as intended (1 or 0, default 0)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -34,12 +34,6 @@ How it works:
|
|||||||
|
|
||||||
Proxybound hook libc functions like connect(), dynamic loader facilities are used, namely dl_sym() and LD_PRELOAD thus dynamically linked programs are required.
|
Proxybound hook libc functions like connect(), dynamic loader facilities are used, namely dl_sym() and LD_PRELOAD thus dynamically linked programs are required.
|
||||||
|
|
||||||
Limits :
|
|
||||||
========
|
|
||||||
|
|
||||||
- IPv6 is blocked and is not supported
|
|
||||||
- Some applications are incompatible (they will be explicitly terminated 2 sec after startup, to avoid leaks)
|
|
||||||
|
|
||||||
Install:
|
Install:
|
||||||
========
|
========
|
||||||
|
|
||||||
@@ -49,7 +43,7 @@ Install:
|
|||||||
[optional] sudo make install
|
[optional] sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
if you dont install, you can use proxybound from the build directory like this: `./proxybound -f src/proxybound.conf telnet google.com 80`
|
If you dont install, you can use proxybound from the build directory like this: `./proxybound -f src/proxybound.conf telnet google.com 80`
|
||||||
|
|
||||||
Install debug version :
|
Install debug version :
|
||||||
=======================
|
=======================
|
||||||
@@ -63,6 +57,18 @@ Install debug version :
|
|||||||
Changelog:
|
Changelog:
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
**Version 5.60:**
|
||||||
|
|
||||||
|
- Fix skype compatibility
|
||||||
|
- Improve no leak feature
|
||||||
|
- Improve debug version
|
||||||
|
- Improve output/log messages
|
||||||
|
- Rewrite main hooked functions connect
|
||||||
|
- Rewrite main hooked functions bind
|
||||||
|
- Rewrite main hooked functions sendmsg
|
||||||
|
- Rewrite main hooked functions sendto
|
||||||
|
- Rewrite main hooked functions send
|
||||||
|
|
||||||
**Version 5.50:**
|
**Version 5.50:**
|
||||||
|
|
||||||
- Block non tcp packet on send()
|
- Block non tcp packet on send()
|
||||||
@@ -128,6 +134,12 @@ Changelog:
|
|||||||
- Import security issue fix CVE-2015-3887
|
- Import security issue fix CVE-2015-3887
|
||||||
- Used v4.3 (4.03) for initial fork
|
- Used v4.3 (4.03) for initial fork
|
||||||
|
|
||||||
|
Limits :
|
||||||
|
========
|
||||||
|
|
||||||
|
- IPv6 is blocked and not supported (currently partially supported)
|
||||||
|
- Some applications are incompatible (they will be explicitly terminated 2 sec after startup, to avoid leaks)
|
||||||
|
|
||||||
Configuration:
|
Configuration:
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
53
src/core.c
53
src/core.c
@@ -225,15 +225,15 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
|||||||
pfd[0].events = POLLOUT;
|
pfd[0].events = POLLOUT;
|
||||||
fcntl(sock, F_SETFL, O_NONBLOCK);
|
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
ret = true_connect(sock, addr, len);
|
ret = true_connect(sock, addr, len);
|
||||||
PDEBUG("\nconnect ret=%d\n", ret);
|
PDEBUG("timed_connect: core.c: ret=%d\n", ret);
|
||||||
|
|
||||||
if(ret == -1 && errno == EINPROGRESS) {
|
if(ret == -1 && errno == EINPROGRESS) {
|
||||||
ret = poll_retry(pfd, 1, tcp_connect_time_out);
|
ret = poll_retry(pfd, 1, tcp_connect_time_out);
|
||||||
PDEBUG("\npoll ret=%d\n", ret);
|
PDEBUG("timed_connect: core.c: poll ret=%d\n", ret);
|
||||||
if(ret == 1) {
|
if(ret == 1) {
|
||||||
value_len = sizeof(socklen_t);
|
value_len = sizeof(socklen_t);
|
||||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, &value, &value_len);
|
getsockopt(sock, SOL_SOCKET, SO_ERROR, &value, &value_len);
|
||||||
PDEBUG("\nvalue=%d\n", value);
|
PDEBUG("timed_connect: core.c: value=%d\n", value);
|
||||||
if(!value)
|
if(!value)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else
|
else
|
||||||
@@ -259,7 +259,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
char *dns_name = NULL;
|
char *dns_name = NULL;
|
||||||
size_t dns_len = 0;
|
size_t dns_len = 0;
|
||||||
|
|
||||||
PDEBUG("tunnel_to()\n");
|
PDEBUG("tunnel_to: core.c: init tunnel_to()\n");
|
||||||
|
|
||||||
// we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution
|
// 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 range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
|
||||||
@@ -274,13 +274,13 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
PDEBUG("host dns %s\n", dns_name ? dns_name : "<NULL>");
|
PDEBUG("tunnel_to: core.c: host dns %s\n", dns_name ? dns_name : "<NULL>");
|
||||||
|
|
||||||
size_t ulen = strlen(user);
|
size_t ulen = strlen(user);
|
||||||
size_t passlen = strlen(pass);
|
size_t passlen = strlen(pass);
|
||||||
|
|
||||||
if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) {
|
if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) {
|
||||||
proxybound_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n");
|
proxybound_write_log(LOG_PREFIX "ERROR: USER+PASS/DOMAIN SIZE EXCEEDS MAX VALUE OF 255!\n\n\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +493,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
|
|||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TP " ... "
|
#define TP "... "
|
||||||
#define DT "Dynamic chain"
|
#define DT "Dynamic chain"
|
||||||
#define ST "Strict chain"
|
#define ST "Strict chain"
|
||||||
#define RT "Random chain"
|
#define RT "Random chain"
|
||||||
@@ -507,8 +507,7 @@ static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
|
pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
|
||||||
proxybound_write_log(LOG_PREFIX "%s " TP " %s:%d ",
|
proxybound_write_log(LOG_PREFIX "%s " TP "%s:%d\n", begin_mark, ip_buf, htons(pd->port));
|
||||||
begin_mark, ip_buf, 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;
|
||||||
@@ -521,7 +520,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:
|
||||||
proxybound_write_log(TP " timeout\n");
|
proxybound_write_log(LOG_PREFIX TP "timeout\n");
|
||||||
error:
|
error:
|
||||||
if(*fd != -1)
|
if(*fd != -1)
|
||||||
close(*fd);
|
close(*fd);
|
||||||
@@ -599,7 +598,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
char *hostname;
|
char *hostname;
|
||||||
char ip_buf[16];
|
char ip_buf[16];
|
||||||
|
|
||||||
PDEBUG("chain_step()\n");
|
PDEBUG("chain_step: core.c: init chain_step()\n");
|
||||||
|
|
||||||
if(pto->ip.octet[0] == remote_dns_subnet) {
|
if(pto->ip.octet[0] == remote_dns_subnet) {
|
||||||
hostname = string_from_internal_ip(pto->ip);
|
hostname = string_from_internal_ip(pto->ip);
|
||||||
@@ -611,7 +610,7 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
hostname = ip_buf;
|
hostname = ip_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
proxybound_write_log(TP " %s:%d ", hostname, htons(pto->port));
|
proxybound_write_log(LOG_PREFIX TP "%s:%d\n", hostname, htons(pto->port));
|
||||||
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
|
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
|
||||||
switch (retcode) {
|
switch (retcode) {
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
@@ -619,12 +618,12 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
break;
|
break;
|
||||||
case BLOCKED:
|
case BLOCKED:
|
||||||
pto->ps = BLOCKED_STATE;
|
pto->ps = BLOCKED_STATE;
|
||||||
proxybound_write_log("<--denied\n");
|
proxybound_write_log(LOG_PREFIX "denied\n");
|
||||||
close(ns);
|
close(ns);
|
||||||
break;
|
break;
|
||||||
case SOCKET_ERROR:
|
case SOCKET_ERROR:
|
||||||
pto->ps = DOWN_STATE;
|
pto->ps = DOWN_STATE;
|
||||||
proxybound_write_log("<--socket error or timeout!\n");
|
proxybound_write_log(LOG_PREFIX "socket error or timeout!\n");
|
||||||
close(ns);
|
close(ns);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -643,7 +642,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
|
|
||||||
p3 = &p4;
|
p3 = &p4;
|
||||||
|
|
||||||
PDEBUG("connect_proxy_chain\n");
|
PDEBUG("connect: core.c: connect_proxy_chain\n");
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
|
||||||
@@ -660,7 +659,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
if(!p2)
|
if(!p2)
|
||||||
break;
|
break;
|
||||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||||
PDEBUG("GOTO AGAIN 1\n");
|
PDEBUG("connect: core.c: goto again x1\n");
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
@@ -676,18 +675,18 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
alive_count = calc_alive(pd, proxy_count);
|
alive_count = calc_alive(pd, proxy_count);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
|
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
|
||||||
PDEBUG("select_proxy failed\n");
|
PDEBUG("connect: core.c: select_proxy failed\n");
|
||||||
goto error_strict;
|
goto error_strict;
|
||||||
}
|
}
|
||||||
if(SUCCESS != start_chain(&ns, p1, ST)) {
|
if(SUCCESS != start_chain(&ns, p1, ST)) {
|
||||||
PDEBUG("start_chain failed\n");
|
PDEBUG("connect: core.c: start_chain failed\n");
|
||||||
goto error_strict;
|
goto error_strict;
|
||||||
}
|
}
|
||||||
while(offset < proxy_count) {
|
while(offset < proxy_count) {
|
||||||
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
||||||
break;
|
break;
|
||||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||||
PDEBUG("chain_step failed\n");
|
PDEBUG("connect: core.c: chain_step failed\n");
|
||||||
goto error_strict;
|
goto error_strict;
|
||||||
}
|
}
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
@@ -712,7 +711,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||||
goto error_more;
|
goto error_more;
|
||||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||||
PDEBUG("GOTO AGAIN 2\n");
|
PDEBUG("connect: core.c: goto again x2\n");
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
@@ -725,7 +724,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proxybound_write_log(TP " OK\n");
|
proxybound_write_log(LOG_PREFIX TP "ok\n");
|
||||||
dup2(ns, sock);
|
dup2(ns, sock);
|
||||||
close(ns);
|
close(ns);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -736,9 +735,9 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
error_more:
|
error_more:
|
||||||
proxybound_write_log("\n!!!need more proxies!!!\n");
|
proxybound_write_log(LOG_PREFIX "ERROR: NEED MORE PROXIES!\n\n\n");
|
||||||
error_strict:
|
error_strict:
|
||||||
PDEBUG("error\n");
|
PDEBUG("connect: core.c: error\n");
|
||||||
|
|
||||||
release_all(pd, proxy_count);
|
release_all(pd, proxy_count);
|
||||||
if(ns != -1)
|
if(ns != -1)
|
||||||
@@ -800,7 +799,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
|||||||
for(i = 0; i < internal_ips.counter; i++) {
|
for(i = 0; i < internal_ips.counter; i++) {
|
||||||
if(internal_ips.list[i]->hash == hash && !strcmp(name, internal_ips.list[i]->string)) {
|
if(internal_ips.list[i]->hash == hash && !strcmp(name, internal_ips.list[i]->string)) {
|
||||||
data->resolved_addr = make_internal_ip(i);
|
data->resolved_addr = make_internal_ip(i);
|
||||||
PDEBUG("got cached ip for %s\n", name);
|
PDEBUG("proxy_gethostbyname: core.c: got cached ip for %s\n", name);
|
||||||
goto have_ip;
|
goto have_ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,7 +807,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
|||||||
|
|
||||||
// grow list if needed.
|
// grow list if needed.
|
||||||
if(internal_ips.capa < internal_ips.counter + 1) {
|
if(internal_ips.capa < internal_ips.counter + 1) {
|
||||||
PDEBUG("realloc\n");
|
PDEBUG("proxy_gethostbyname: core.c: realloc\n");
|
||||||
new_mem = realloc(internal_ips.list, (internal_ips.capa + 16) * sizeof(void *));
|
new_mem = realloc(internal_ips.list, (internal_ips.capa + 16) * sizeof(void *));
|
||||||
if(new_mem) {
|
if(new_mem) {
|
||||||
internal_ips.capa += 16;
|
internal_ips.capa += 16;
|
||||||
@@ -816,7 +815,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
|||||||
} else {
|
} else {
|
||||||
// goto ------------
|
// goto ------------
|
||||||
oom:
|
oom:
|
||||||
proxybound_write_log("out of mem\n");
|
proxybound_write_log(LOG_PREFIX "ERROR: OUT OF MEMORY!\n\n\n");
|
||||||
goto err_plus_unlock;
|
goto err_plus_unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -830,7 +829,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
|||||||
if(!new_mem)
|
if(!new_mem)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
PDEBUG("creating new entry %d for ip of %s\n", (int) internal_ips.counter, name);
|
PDEBUG("proxy_gethostbyname: core.c: 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] = new_mem;
|
||||||
internal_ips.list[internal_ips.counter]->hash = hash;
|
internal_ips.list[internal_ips.counter]->hash = hash;
|
||||||
|
@@ -363,132 +363,6 @@ static int is_dns_port(unsigned short port) {
|
|||||||
/**************************************************************************************************************************************************************/
|
/**************************************************************************************************************************************************************/
|
||||||
/******* HOOK FUNCTIONS *************************************************************************************************************************************/
|
/******* HOOK FUNCTIONS *************************************************************************************************************************************/
|
||||||
|
|
||||||
int connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
|
||||||
PDEBUG("\n\n\n\n\n\n\n\n\n\n\n\n...CONNECT........................................................................................................... \n\n");
|
|
||||||
|
|
||||||
int socktype = 0, flags = 0, ret = 0;
|
|
||||||
socklen_t optlen = 0;
|
|
||||||
ip_type dest_ip;
|
|
||||||
char ip[256];
|
|
||||||
struct in_addr *p_addr_in;
|
|
||||||
unsigned short port;
|
|
||||||
size_t i;
|
|
||||||
int remote_dns_connect = 0;
|
|
||||||
INIT();
|
|
||||||
optlen = sizeof(socktype);
|
|
||||||
getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
|
||||||
|
|
||||||
// Sock family list (not complete)
|
|
||||||
// AF_UNIX_CCSID /* - Unix domain sockets */
|
|
||||||
// AF_UNIX /* 1 - Unix domain sockets */
|
|
||||||
// AF_INET /* 2 - Internet IP Protocol */
|
|
||||||
// AF_INET6 /* 10 - IPv6 */
|
|
||||||
// AF_UNSPEC /* 0 */
|
|
||||||
// AF_AX25 /* 3 - Amateur Radio AX.25 */
|
|
||||||
// AF_IPX /* 4 - Novell IPX */
|
|
||||||
// AF_APPLETALK /* 5 - Appletalk DDP */
|
|
||||||
// AF_NETROM /* 6 - Amateur radio NetROM */
|
|
||||||
// AF_BRIDGE /* 7 - Multiprotocol bridge */
|
|
||||||
// AF_AAL5 /* 8 - Reserved for Werner's ATM */
|
|
||||||
// AF_X25 /* 9 - Reserved for X.25 project */
|
|
||||||
// AF_MAX /* 12 - For now.. */
|
|
||||||
// PF_FILE
|
|
||||||
// ...
|
|
||||||
|
|
||||||
//Allow direct unix
|
|
||||||
if (SOCKFAMILY(*addr) == AF_UNIX) {
|
|
||||||
PDEBUG("connect: allowing direct unix connect()\n");
|
|
||||||
return true_connect(sock, addr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
|
||||||
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
|
|
||||||
//inet_ntop - convert IPv4 and IPv6 addresses from binary to text form
|
|
||||||
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
//PDEBUG("connect: localnet: %s; ", inet_ntop(AF_INET, &in_addr_localnet, ip, sizeof(ip)));
|
|
||||||
//PDEBUG("connect: netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, ip, sizeof(ip)));
|
|
||||||
PDEBUG("connect: target: %s\n", ip);
|
|
||||||
PDEBUG("connect: port: %d\n", port);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Allow direct local 127.x.x.x
|
|
||||||
if ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
|
||||||
PDEBUG("connect: local ip detected... ignoring\n");
|
|
||||||
return true_connect(sock, addr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Allow empty ip
|
|
||||||
/*if (!ip[0]) {
|
|
||||||
PDEBUG("connect: noip... ignoring\n");
|
|
||||||
return true_connect(sock, addr, len);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//SOCK_STREAM
|
|
||||||
//SOCK_DGRAM
|
|
||||||
//SOCK_SEQPACKET
|
|
||||||
//SOCK_RAW
|
|
||||||
//SOCK_RDM
|
|
||||||
//SOCK_PACKET
|
|
||||||
//Block unsupported sock
|
|
||||||
//WARNING: this block other unrelated network connect
|
|
||||||
if ((socktype != SOCK_STREAM) || (SOCKFAMILY(*addr) != AF_INET)) {
|
|
||||||
if (proxybound_allow_leak) {
|
|
||||||
PDEBUG("connect: allowing direct udp connect()\n");
|
|
||||||
return true_connect(sock, addr, len);
|
|
||||||
} else {
|
|
||||||
PDEBUG("connect: blocking direct udp connect()\n");
|
|
||||||
if (!port) {return -1;}
|
|
||||||
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_connect(sock, addr, len);}
|
|
||||||
else {return -1;}
|
|
||||||
return -1; //Au cas ou
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if connect called from proxydns
|
|
||||||
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
|
||||||
|
|
||||||
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
|
|
||||||
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr) == (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
|
||||||
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
|
|
||||||
PDEBUG("connect: accessing localnet 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);}
|
|
||||||
dest_ip.as_int = SOCKADDR(*addr);
|
|
||||||
ret = connect_proxy_chain(sock, dest_ip, SOCKPORT(*addr), proxybound_pd, proxybound_proxy_count, proxybound_ct, proxybound_max_chain);
|
|
||||||
|
|
||||||
fcntl(sock, F_SETFL, flags);
|
|
||||||
if(ret != SUCCESS)
|
|
||||||
errno = ECONNREFUSED;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//int connect(int sock, const struct sockaddr *addr, socklen_t len)
|
|
||||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|
||||||
PDEBUG("bind: got a bind request ------------------------\n");
|
|
||||||
|
|
||||||
/* If the real bind doesn't exist, we're stuffed */
|
|
||||||
if (true_bind == NULL) {
|
|
||||||
PDEBUG("bind: unresolved symbol: bind\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int socktype = 0;
|
|
||||||
socklen_t optlen = 0;
|
|
||||||
char ip[256];
|
|
||||||
struct in_addr *p_addr_in;
|
|
||||||
unsigned short port;
|
|
||||||
size_t i;
|
|
||||||
int remote_dns_bind = 0;
|
|
||||||
optlen = sizeof(socktype);
|
|
||||||
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
|
||||||
|
|
||||||
// Sock family list (not complete)
|
// Sock family list (not complete)
|
||||||
// AF_UNIX_CCSID /* - Unix domain sockets */
|
// AF_UNIX_CCSID /* - Unix domain sockets */
|
||||||
// AF_UNIX /* 1 - Unix domain sockets */
|
// AF_UNIX /* 1 - Unix domain sockets */
|
||||||
@@ -507,10 +381,63 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
// PF_FILE /* ?? - ... */
|
// PF_FILE /* ?? - ... */
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
//SOCK_STREAM // 1
|
||||||
|
//SOCK_DGRAM // 2
|
||||||
|
//SOCK_SEQPACKET // 5
|
||||||
|
//SOCK_RAW // 3
|
||||||
|
//SOCK_RDM // 4
|
||||||
|
//SOCK_PACKET // 10
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//struct msghdr {
|
||||||
|
// void *msg_name; /* optional address */
|
||||||
|
// socklen_t msg_namelen; /* size of address */
|
||||||
|
// struct iovec *msg_iov; /* scatter/gather array */
|
||||||
|
// size_t msg_iovlen; /* # elements in msg_iov */
|
||||||
|
// void *msg_control; /* ancillary data, see below */
|
||||||
|
// size_t msg_controllen; /* ancillary data buffer len */
|
||||||
|
// int msg_flags; /* flags on received message */
|
||||||
|
//};
|
||||||
|
|
||||||
|
/**************************************************************************************************************************************************************/
|
||||||
|
|
||||||
|
int connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
||||||
|
PDEBUG("\n\n\n\n\n\n\n\n\n\n\n\n...CONNECT........................................................................................................... \n\n");
|
||||||
|
|
||||||
|
if (true_connect == NULL) {
|
||||||
|
PDEBUG("violation: connect: rejecting, unresolved symbol: connect\n");
|
||||||
|
errno = ECONNREFUSED; return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socktype = 0, flags = 0, ret = 0;
|
||||||
|
socklen_t optlen = 0;
|
||||||
|
ip_type dest_ip;
|
||||||
|
char ip[256];
|
||||||
|
struct in_addr *p_addr_in;
|
||||||
|
unsigned short port;
|
||||||
|
size_t i;
|
||||||
|
int remote_dns_connect = 0;
|
||||||
|
INIT();
|
||||||
|
optlen = sizeof(socktype);
|
||||||
|
getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
||||||
|
|
||||||
|
if (!socktype) {
|
||||||
|
PDEBUG("violation: connect: allowing, no socket_type\n");
|
||||||
|
return true_connect(sock, addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if ((SOCKFAMILY(*addr) < 1) && (!proxybound_allow_leak)) {
|
||||||
|
PDEBUG("violation: connect: rejecting, unresolved, socket family\n");
|
||||||
|
errno = ECONNREFUSED; return -1;
|
||||||
|
}*/
|
||||||
|
|
||||||
//Allow direct unix
|
//Allow direct unix
|
||||||
if (SOCKFAMILY(*addr) == AF_UNIX) {
|
if ((SOCKFAMILY(*addr) != AF_INET) && (SOCKFAMILY(*addr) != AF_INET6) ) {
|
||||||
PDEBUG("bind: allowing direct unix bind()\n");
|
PDEBUG("connect: requested SOCK =%d\n",socktype);
|
||||||
return true_bind(sockfd, addr, addrlen);
|
PDEBUG("connect: requested SOCKFAMILY =%d\n",SOCKFAMILY(*addr));
|
||||||
|
PDEBUG("-------------------------------------------------\n");
|
||||||
|
PDEBUG("connect: allowing non inet connect()\n");
|
||||||
|
return true_connect(sock, addr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
||||||
@@ -519,19 +446,106 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PDEBUG("------------------------------- \n");
|
//PDEBUG("connect: localnet: %s\n", inet_ntop(AF_INET, &in_addr_localnet, ip, sizeof(ip)));
|
||||||
PDEBUG("bind: target: %s\n", ip);
|
//PDEBUG("connect: netmask: %s\n" , inet_ntop(AF_INET, &in_addr_netmask, ip, sizeof(ip)));
|
||||||
PDEBUG("bind: port: %d\n", port);
|
if (strlen(ip) == 0) {PDEBUG("violation: connect: null ip\n");} else {PDEBUG("connect: target: %s\n", ip);}
|
||||||
PDEBUG("------------------------------- \n");
|
if (port < 0) {PDEBUG("violation: connect: null port\n");} else {PDEBUG("connect: port: %d\n", port);}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Allow direct local 127.x.x.x
|
//Allow direct local 127.x.x.x
|
||||||
if ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
if ((strlen(ip) != 0) && (ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
||||||
|
PDEBUG("connect: local ip detected... ignoring\n");
|
||||||
|
return true_connect(sock, addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if connect called from proxydns
|
||||||
|
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
||||||
|
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
|
||||||
|
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr) == (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
||||||
|
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
|
||||||
|
PDEBUG("connect: accessing localnet using true_connect\n");
|
||||||
|
return true_connect(sock, addr, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Block unsupported sock
|
||||||
|
//WARNING: this block other unrelated network connect
|
||||||
|
if (socktype != SOCK_STREAM) {
|
||||||
|
if (proxybound_allow_leak) {
|
||||||
|
PDEBUG("connect: allowing leak connect()\n");
|
||||||
|
return true_connect(sock, addr, len);
|
||||||
|
} else {
|
||||||
|
if (port < 0) {PDEBUG("violation: connect: rejecting leak connect() null port\n"); errno = ECONNREFUSED; return -1;}
|
||||||
|
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_connect(sock, addr, len);}
|
||||||
|
PDEBUG("connect: rejecting leak connect()\n"); errno = ECONNREFUSED; return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Proxify connect
|
||||||
|
flags = fcntl(sock, F_GETFL, 0);
|
||||||
|
if(flags & O_NONBLOCK) {fcntl(sock, F_SETFL, !O_NONBLOCK);}
|
||||||
|
dest_ip.as_int = SOCKADDR(*addr);
|
||||||
|
ret = connect_proxy_chain(sock, dest_ip, SOCKPORT(*addr), proxybound_pd, proxybound_proxy_count, proxybound_ct, proxybound_max_chain);
|
||||||
|
|
||||||
|
fcntl(sock, F_SETFL, flags);
|
||||||
|
if(ret != SUCCESS) errno = ECONNREFUSED;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//int connect(int sock, const struct sockaddr *addr, socklen_t len)
|
||||||
|
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
|
PDEBUG("bind: got a bind request ------------------------\n");
|
||||||
|
|
||||||
|
if (true_bind == NULL) {
|
||||||
|
PDEBUG("violation: bind: rejecting, unresolved symbol: bind\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socktype = 0;
|
||||||
|
socklen_t optlen = 0;
|
||||||
|
char ip[256];
|
||||||
|
struct in_addr *p_addr_in;
|
||||||
|
unsigned short port;
|
||||||
|
size_t i;
|
||||||
|
int remote_dns_bind = 0;
|
||||||
|
optlen = sizeof(socktype);
|
||||||
|
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
|
||||||
|
|
||||||
|
if (!socktype) {
|
||||||
|
PDEBUG("violation: bind: allowing, no socket_type\n");
|
||||||
|
return true_bind(sockfd, addr, addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if ((SOCKFAMILY(*addr) < 1) && (!proxybound_allow_leak)) {
|
||||||
|
PDEBUG("violation: bind: rejecting, unresolved, socket family\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//Allow direct unix
|
||||||
|
if ((SOCKFAMILY(*addr) != AF_INET) && (SOCKFAMILY(*addr) != AF_INET6) ) {
|
||||||
|
PDEBUG("bind: allowing non inet sock bind()\n");
|
||||||
|
return true_bind(sockfd, addr, addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
||||||
|
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
|
||||||
|
//inet_ntop - convert IPv4 and IPv6 addresses from binary to text form
|
||||||
|
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (strlen(ip) == 0) {PDEBUG("violation: bind: null ip\n");} else {PDEBUG("bind: target: %s\n", ip);}
|
||||||
|
if (port < 0) {PDEBUG("violation: bind: null port\n");} else {PDEBUG("bind: port: %d\n", port);}
|
||||||
|
PDEBUG("-------------------------------------------------\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Allow direct local 127.x.x.x
|
||||||
|
if ((strlen(ip) == 0) && (ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
||||||
PDEBUG("bind: local ip detected... ignoring\n");
|
PDEBUG("bind: local ip detected... ignoring\n");
|
||||||
return true_bind(sockfd, addr, addrlen);
|
return true_bind(sockfd, addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bind called from proxydns
|
//Check if bind called from proxydns
|
||||||
remote_dns_bind = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
remote_dns_bind = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
|
||||||
for(i = 0; i < num_localnet_addr && !remote_dns_bind; i++) {
|
for(i = 0; i < num_localnet_addr && !remote_dns_bind; i++) {
|
||||||
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr) == (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr) == (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
|
||||||
@@ -543,111 +557,190 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PDEBUG("------------------------------- \n");
|
|
||||||
PDEBUG("bind() sock SOCK_STREAM = %d\n",SOCK_STREAM);
|
PDEBUG("bind() sock SOCK_STREAM = %d\n",SOCK_STREAM);
|
||||||
PDEBUG("bind() sock SOCK_DGRAM = %d\n",SOCK_DGRAM);
|
PDEBUG("bind() sock SOCK_DGRAM = %d\n",SOCK_DGRAM);
|
||||||
PDEBUG("bind() sock SOCK_SEQPACKET = %d\n",SOCK_SEQPACKET);
|
PDEBUG("bind() sock SOCK_SEQPACKET = %d\n",SOCK_SEQPACKET);
|
||||||
PDEBUG("bind() sock SOCK_RAW = %d\n",SOCK_RAW);
|
PDEBUG("bind() sock SOCK_RAW = %d\n",SOCK_RAW);
|
||||||
PDEBUG("bind() sock SOCK_RDM = %d\n",SOCK_RDM);
|
PDEBUG("bind() sock SOCK_RDM = %d\n",SOCK_RDM);
|
||||||
PDEBUG("bind() sock SOCK_PACKET = %d\n",SOCK_PACKET);
|
PDEBUG("bind() sock SOCK_PACKET = %d\n",SOCK_PACKET);
|
||||||
PDEBUG("------------------------------- \n");
|
PDEBUG("-------------------------------------------------\n");
|
||||||
PDEBUG("bind: requested SOCK =%d\n",socktype);
|
PDEBUG("bind: requested SOCK =%d\n",socktype);
|
||||||
PDEBUG("bind: requested SOCKFAMILY =%d\n",SOCKFAMILY(*addr));
|
PDEBUG("bind: requested SOCKFAMILY =%d\n",SOCKFAMILY(*addr));
|
||||||
PDEBUG("------------------------------- \n");
|
PDEBUG("-------------------------------------------------\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Required for proxify
|
//Required for proxify, type raw, 0.0.0.0, MSG_PROXY
|
||||||
//Type Raw, 0.0.0.0, MSG_PROXY
|
/*if ((socktype == SOCK_RAW) && (SOCKFAMILY(*addr) == MSG_PROXY)) {
|
||||||
//if ((socktype == SOCK_RAW) && (SOCKFAMILY(*addr) == MSG_PROXY)) {
|
|
||||||
if ((SOCKFAMILY(*addr) == MSG_PROXY)) {
|
|
||||||
if ((ip[0] == '0') && (ip[1] == '.') && (ip[2] == '0') && (ip[3] == '.' ) && (ip[4] == '0') && (ip[5] == '.') && (ip[6] == '0')) {
|
if ((ip[0] == '0') && (ip[1] == '.') && (ip[2] == '0') && (ip[3] == '.' ) && (ip[4] == '0') && (ip[5] == '.') && (ip[6] == '0')) {
|
||||||
PDEBUG("bind: bind allowing, 0.0.0.0, MSG_PROXY...\n");
|
PDEBUG("bind: bind allowing, 0.0.0.0, MSG_PROXY...\n");
|
||||||
return true_bind(sockfd, addr, addrlen);
|
return true_bind(sockfd, addr, addrlen);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//SOCK_STREAM
|
|
||||||
//SOCK_DGRAM
|
|
||||||
//SOCK_SEQPACKET
|
|
||||||
//SOCK_RAW
|
|
||||||
//SOCK_RDM
|
|
||||||
//SOCK_PACKET
|
|
||||||
//Block unsupported sock
|
//Block unsupported sock
|
||||||
//WARNING: this block other unrelated network connect
|
//WARNING: this block other unrelated network connect
|
||||||
if (socktype != SOCK_STREAM) {
|
if ((socktype != SOCK_STREAM) && (!proxybound_allow_leak)) {
|
||||||
if (proxybound_allow_leak) {
|
if (port < 0) {PDEBUG("violation: bind: rejecting un-managed protocol bind() null port\n"); errno = EFAULT; return -1;}
|
||||||
PDEBUG("bind: allowing direct udp bind()\n");
|
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_bind(sockfd, addr, addrlen);}
|
||||||
return true_bind(sockfd, addr, addrlen);
|
PDEBUG("bind: rejecting un-managed protocol bind()\n");
|
||||||
} else {
|
errno = EFAULT; return -1;
|
||||||
PDEBUG("bind: blocking direct udp bind()\n");
|
|
||||||
if (!port) {PDEBUG("bind: blocking direct udp bind()\n"); return -1;}
|
|
||||||
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_bind(sockfd, addr, addrlen);}
|
|
||||||
else {
|
|
||||||
PDEBUG("bind: blocking direct udp bind()\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
PDEBUG("bind: blocking direct udp bind()\n");
|
|
||||||
return -1; //Au cas ou
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//SOCK_STREAM TCP
|
|
||||||
return true_bind(sockfd, addr, addrlen);
|
return true_bind(sockfd, addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxybound_allow_leak) {
|
if (proxybound_allow_leak) {
|
||||||
return true_bind(sockfd, addr, addrlen);
|
return true_bind(sockfd, addr, addrlen);
|
||||||
} else {
|
|
||||||
PDEBUG("bind: blocking direct udp bind()\n");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PDEBUG("bind: blocking direct udp bind()\n");
|
PDEBUG("bind: rejecting un-managed protocol bind()\n");
|
||||||
return -1;
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
||||||
|
PDEBUG("sendmsg: got sendmsg request --------------------\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
|
||||||
|
if (true_sendmsg == NULL) {
|
||||||
|
PDEBUG("violation: sendmsg: rejecting, unresolved symbol: sendmsg\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_type = -1;
|
||||||
|
unsigned int sock_type_len = sizeof(sock_type);
|
||||||
|
const struct sockaddr_in *addr = (const struct sockaddr_in *)msg->msg_name; //optional adress
|
||||||
|
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len); //get the type of the socket
|
||||||
|
|
||||||
|
if (!sock_type) {
|
||||||
|
PDEBUG("violation: sendmsg: allowing unknown sock\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr) {
|
||||||
|
if (addr->sin_family) {
|
||||||
|
PDEBUG("sendmsg: sock familly %d\n",addr->sin_family);
|
||||||
|
if ((addr->sin_family != AF_INET) && (addr->sin_family != AF_INET6)) {
|
||||||
|
PDEBUG("sendmsg: allowing non inet\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//This require connect on the first place...
|
||||||
|
PDEBUG("violation: sendmsg: allowing unknown sin_family\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//This require connect on the first place...
|
||||||
|
PDEBUG("violation: sendmsg: allowing unknown addr\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Block unsupported sock
|
||||||
|
//WARNING: this block other unrelated network connect
|
||||||
|
if (sock_type == SOCK_STREAM) {
|
||||||
|
PDEBUG("sendmsg: allowing tcp sock stream\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
} else {
|
||||||
|
PDEBUG("sendmsg sock SOCK_STREAM = %d\n",SOCK_STREAM);
|
||||||
|
PDEBUG("sendmsg sock SOCK_DGRAM = %d\n",SOCK_DGRAM);
|
||||||
|
PDEBUG("sendmsg sock SOCK_SEQPACKET = %d\n",SOCK_SEQPACKET);
|
||||||
|
PDEBUG("sendmsg sock SOCK_RAW = %d\n",SOCK_RAW);
|
||||||
|
PDEBUG("sendmsg sock SOCK_RDM = %d\n",SOCK_RDM);
|
||||||
|
PDEBUG("sendmsg sock SOCK_PACKET = %d\n",SOCK_PACKET);
|
||||||
|
PDEBUG("-------------------------------------------------\n");
|
||||||
|
PDEBUG("sendmsg: sock %d\n",sock_type);
|
||||||
|
PDEBUG("-------------------------------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (((sock_type == SOCK_SEQPACKET) || (sock_type == SOCK_SEQPACKET)) && (!addr)) {
|
||||||
|
PDEBUG("sendmsg: allowing seqpacket stream\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (proxybound_allow_leak) {
|
||||||
|
PDEBUG("sendmsg: allow leak\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
} else {
|
||||||
|
if (addr) {
|
||||||
|
char ip[256];
|
||||||
|
struct in_addr *p_addr_in;
|
||||||
|
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
|
||||||
|
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
||||||
|
if (strlen(ip) == 0) {PDEBUG("violation: sendmsg: rejecting null ip\n"); errno = EFAULT; return -1;}
|
||||||
|
PDEBUG("sendmsg: ip: %s\n",ip);
|
||||||
|
|
||||||
|
unsigned short port;
|
||||||
|
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
|
||||||
|
if (port < 0) {PDEBUG("violation: sendmsg: rejecting null port\n"); errno = EFAULT; return -1;}
|
||||||
|
PDEBUG("sendmsg: port: %d\n", port);
|
||||||
|
|
||||||
|
//Allow local
|
||||||
|
if ((strlen(ip) != 0) && ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.'))) {
|
||||||
|
PDEBUG("sendmsg: allowing local 127.0.0.1\n");
|
||||||
|
return true_sendmsg(sockfd, msg, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_sendmsg(sockfd, msg, flags);}
|
||||||
|
|
||||||
|
PDEBUG("sendmsg: rejecting c\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
|
PDEBUG("sendmsg: rejecting d\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
|
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||||
PDEBUG("sendto: got sendto request ----------------------\n");
|
PDEBUG("sendto: got sendto request ----------------------\n");
|
||||||
|
|
||||||
struct sockaddr_in *connaddr;
|
if (true_sendto == NULL) {
|
||||||
|
PDEBUG("violation: sendto: rejecting, unresolved symbol: sendto\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int sock_type = -1;
|
int sock_type = -1;
|
||||||
unsigned int sock_type_len = sizeof(sock_type);
|
unsigned int sock_type_len = sizeof(sock_type);
|
||||||
|
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len); //get the type of the socket
|
||||||
|
|
||||||
/* If the real connect doesn't exist, we're stuffed */
|
if (!sock_type) {
|
||||||
if (true_sendto == NULL) {
|
PDEBUG("violation: sendto: allowing, no socket_type\n");
|
||||||
PDEBUG("sendto: unresolved symbol: sendto\n");
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in *connaddr;
|
||||||
connaddr = (struct sockaddr_in *) dest_addr;
|
connaddr = (struct sockaddr_in *) dest_addr;
|
||||||
|
|
||||||
if (!connaddr) {
|
if (!connaddr) {
|
||||||
PDEBUG("sendto: no dest_addr, allowing\n");
|
PDEBUG("violation: sendto: null dest_addr\n");
|
||||||
|
//send(sockfd, buf, len, flags) = sendto(sockfd, buf, len, flags, NULL, 0)
|
||||||
|
//send require connect on the first place...
|
||||||
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connaddr->sin_family == AF_UNIX) {
|
if ((connaddr->sin_family != AF_INET) && (connaddr->sin_family != AF_INET6)) {
|
||||||
PDEBUG("sendto: allowing unix\n");
|
PDEBUG("sendto: allowing non inet socket\n");
|
||||||
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the type of the socket */
|
|
||||||
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len);
|
|
||||||
|
|
||||||
//SOCK_STREAM
|
|
||||||
//SOCK_DGRAM
|
|
||||||
//SOCK_SEQPACKET
|
|
||||||
//SOCK_RAW
|
|
||||||
//SOCK_RDM
|
|
||||||
//SOCK_PACKET
|
|
||||||
//Block unsupported sock
|
//Block unsupported sock
|
||||||
//WARNING: this block other unrelated network connect
|
//WARNING: this block other unrelated network connect
|
||||||
if ((connaddr->sin_family != AF_INET) || (sock_type != SOCK_STREAM)) {
|
if ((sock_type != SOCK_STREAM) && (!proxybound_allow_leak)) {
|
||||||
PDEBUG("sendto: is on a udp/unsupported stream\n");
|
PDEBUG("sendto: is on a udp/unsupported stream\n");
|
||||||
|
PDEBUG("sendto: requested SOCK =%d\n",sock_type);
|
||||||
char ip[256];
|
char ip[256];
|
||||||
struct in_addr *p_addr_in;
|
struct in_addr *p_addr_in;
|
||||||
|
unsigned short port;
|
||||||
p_addr_in = &((struct sockaddr_in *) connaddr)->sin_addr;
|
p_addr_in = &((struct sockaddr_in *) connaddr)->sin_addr;
|
||||||
|
port = ntohs(((struct sockaddr_in *) connaddr)->sin_port);
|
||||||
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
||||||
|
|
||||||
|
if (!connaddr->sin_family) {PDEBUG("violation: sendto: rejecting null sin_family\n"); errno = EFAULT; return -1;}
|
||||||
|
if (strlen(ip) == 0) {PDEBUG("violation: sendmsg: rejecting null ip\n"); errno = EFAULT; return -1;}
|
||||||
|
if (port < 0) {PDEBUG("violation: sendmsg: rejecting null port\n"); errno = EFAULT; return -1;}
|
||||||
|
|
||||||
|
PDEBUG("sendto: requested SOCKFAMILY =%d\n",connaddr->sin_family);
|
||||||
PDEBUG("sendto: ip: %s\n",ip);
|
PDEBUG("sendto: ip: %s\n",ip);
|
||||||
|
PDEBUG("sendto: port: %d\n", port);
|
||||||
|
|
||||||
|
PDEBUG("sendto: -----------------------------------------\n");
|
||||||
|
|
||||||
//Allow local
|
//Allow local
|
||||||
if ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
if ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
||||||
@@ -657,30 +750,24 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct
|
|||||||
|
|
||||||
//Blocking the connection
|
//Blocking the connection
|
||||||
if (proxybound_allow_leak) {
|
if (proxybound_allow_leak) {
|
||||||
PDEBUG("sendto: allowing direct udp sendto()\n");
|
PDEBUG("sendto: allowing udp/unsupported sendto()\n");
|
||||||
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
} else {
|
} else {
|
||||||
unsigned short port;
|
//if (port < 0) {PDEBUG("violation: sendto: rejecting null port\n"); errno = EFAULT; return -1;}
|
||||||
port = ntohs(((struct sockaddr_in *) connaddr)->sin_port);
|
//if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);}
|
||||||
if (!port) {PDEBUG("sendto: rejecting.\n"); return -1;}
|
|
||||||
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);}
|
|
||||||
else {
|
|
||||||
PDEBUG("sendto: rejecting.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
PDEBUG("sendto: rejecting.\n");
|
PDEBUG("sendto: rejecting.\n");
|
||||||
return -1; //Au cas ou
|
errno = EFAULT; return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
//return (ssize_t) true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (proxybound_allow_leak) {
|
if (proxybound_allow_leak) {
|
||||||
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
return true_sendto(sockfd, buf, len, flags, *dest_addr, addrlen);
|
||||||
} else {
|
}
|
||||||
PDEBUG("sendto: rejecting.\n");
|
|
||||||
return -1;
|
PDEBUG("sendto: rejecting.\n");
|
||||||
}
|
errno = EFAULT; return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
|
ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
|
||||||
@@ -690,119 +777,42 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
|
|||||||
|
|
||||||
/* If the real connect doesn't exist, we're stuffed */
|
/* If the real connect doesn't exist, we're stuffed */
|
||||||
if (true_send == NULL) {
|
if (true_send == NULL) {
|
||||||
PDEBUG("send: unresolved symbol: send\n");
|
PDEBUG("violation: send: rejecting, unresolved symbol: send\n");
|
||||||
return -1;
|
errno = EFAULT; return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxybound_allow_leak) {
|
//send require connect/sendto in the first place...
|
||||||
|
return true_send(sockfd, buf, len, flags);
|
||||||
|
|
||||||
|
/*if (proxybound_allow_leak) {
|
||||||
PDEBUG("send: allowing direct send()\n");
|
PDEBUG("send: allowing direct send()\n");
|
||||||
return true_send(sockfd, buf, len, flags);
|
return true_send(sockfd, buf, len, flags);
|
||||||
//Already handled in connect ?
|
|
||||||
//TODO deeper handling (socktype)
|
|
||||||
} else {
|
} else {
|
||||||
int sock_type = -1;
|
int sock_type = -1;
|
||||||
unsigned int sock_type_len = sizeof(sock_type);
|
unsigned int sock_type_len = sizeof(sock_type);
|
||||||
|
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len); //Get the type of the socket
|
||||||
/* Get the type of the socket */
|
|
||||||
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len);
|
|
||||||
|
|
||||||
//SOCK_STREAM
|
if (!sock_type) {
|
||||||
//SOCK_DGRAM
|
PDEBUG("violation: send: allowing empty sock_type send()\n");
|
||||||
//SOCK_SEQPACKET
|
|
||||||
//SOCK_RAW
|
|
||||||
//SOCK_RDM
|
|
||||||
//SOCK_PACKET
|
|
||||||
//Block unsupported sock
|
|
||||||
//TODO may block dns here
|
|
||||||
//WARNING: this block other unrelated network connect
|
|
||||||
if (sock_type != SOCK_STREAM) {
|
|
||||||
PDEBUG("send: blocking send request type SOCK_DGRAM/SOCK_SEQPACKET/SOCK_RAW/SOCK_RDM/SOCK_PACKET\n");
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return true_send(sockfd, buf, len, flags);
|
return true_send(sockfd, buf, len, flags);
|
||||||
}
|
|
||||||
PDEBUG("send: blocking send request");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
|
||||||
PDEBUG("sendmsg: got sendmsg request --------------------\n");
|
|
||||||
|
|
||||||
struct sockaddr_in *connaddr;
|
|
||||||
int sock_type = -1;
|
|
||||||
unsigned int sock_type_len = sizeof(sock_type);
|
|
||||||
|
|
||||||
/* If the real connect doesn't exist, we're stuffed */
|
|
||||||
if (true_sendmsg == NULL) {
|
|
||||||
PDEBUG("sendmsg: unresolved symbol: sendmsg\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
connaddr = (struct sockaddr_in *) msg->msg_name;
|
|
||||||
|
|
||||||
if (!connaddr) {
|
|
||||||
PDEBUG("sendmsg: no msg_name (dest), allowing\n");
|
|
||||||
return true_sendmsg(sockfd, msg, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connaddr->sin_family == AF_UNIX) {
|
|
||||||
PDEBUG("sendmsg: allowing unix\n");
|
|
||||||
return true_sendmsg(sockfd, msg, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the type of the socket */
|
|
||||||
getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len);
|
|
||||||
|
|
||||||
//SOCK_STREAM
|
|
||||||
//SOCK_DGRAM
|
|
||||||
//SOCK_SEQPACKET
|
|
||||||
//SOCK_RAW
|
|
||||||
//SOCK_RDM
|
|
||||||
//SOCK_PACKET
|
|
||||||
//Block unsupported sock
|
|
||||||
//WARNING: this block other unrelated network connect
|
|
||||||
if ((connaddr->sin_family != AF_INET) || (sock_type != SOCK_STREAM)) {
|
|
||||||
PDEBUG("sendmsg: is on a udp stream\n");
|
|
||||||
|
|
||||||
char ip[256];
|
|
||||||
struct in_addr *p_addr_in;
|
|
||||||
|
|
||||||
p_addr_in = &((struct sockaddr_in *) connaddr)->sin_addr;
|
|
||||||
inet_ntop(AF_INET, p_addr_in, ip, sizeof(ip));
|
|
||||||
|
|
||||||
PDEBUG("sendmsg: ip: %s\n",ip);
|
|
||||||
|
|
||||||
//Allow local
|
|
||||||
if ((ip[0] == '1') && (ip[1] == '2') && (ip[2] == '7') && (ip[3] == '.')) {
|
|
||||||
PDEBUG("sendmsg: allowing local 127.0.0.1\n");
|
|
||||||
return true_sendmsg(sockfd, msg, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Blocking the connection
|
|
||||||
if (proxybound_allow_leak) {
|
|
||||||
PDEBUG("sendmsg: allowing direct udp sendmsg()\n");
|
|
||||||
} else {
|
|
||||||
unsigned short port;
|
|
||||||
port = ntohs(((struct sockaddr_in *) connaddr)->sin_port);
|
|
||||||
if (!port) {PDEBUG("sendmsg: blocking\n"); return -1;}
|
|
||||||
if ((proxybound_allow_dns) && (is_dns_port(port))) {return true_sendmsg(sockfd, msg, flags);}
|
|
||||||
else {PDEBUG("sendmsg: blocking\n"); return -1;}
|
|
||||||
PDEBUG("sendmsg: blocking\n");
|
|
||||||
return -1; //Au cas ou
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
//SOCK_STREAM SOCK_DGRAM SOCK_SEQPACKET SOCK_RAW SOCK_RDM SOCK_PACKET
|
||||||
return true_sendmsg(sockfd, msg, flags);
|
if (sock_type == SOCK_STREAM) {return true_send(sockfd, buf, len, flags);}
|
||||||
//return (ssize_t) true_sendmsg(sockfd, msg, flags);
|
|
||||||
}
|
PDEBUG("send: sock SOCK_STREAM = %d\n",SOCK_STREAM);
|
||||||
|
PDEBUG("send: sock SOCK_DGRAM = %d\n",SOCK_DGRAM);
|
||||||
if (proxybound_allow_leak) {
|
PDEBUG("send: sock SOCK_SEQPACKET = %d\n",SOCK_SEQPACKET);
|
||||||
return true_sendmsg(sockfd, msg, flags);
|
PDEBUG("send: sock SOCK_RAW = %d\n",SOCK_RAW);
|
||||||
} else {
|
PDEBUG("send: sock SOCK_RDM = %d\n",SOCK_RDM);
|
||||||
PDEBUG("sendmsg: blocking\n");
|
PDEBUG("send: sock SOCK_PACKET = %d\n",SOCK_PACKET);
|
||||||
return -1;
|
PDEBUG("-------------------------------------------------\n");
|
||||||
}
|
PDEBUG("send: sock %d\n",sock_type);
|
||||||
|
PDEBUG("-------------------------------------------------\n");
|
||||||
|
|
||||||
|
PDEBUG("send: rejecting send request unsupported sock\n");
|
||||||
|
errno = EFAULT; return -1;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: DNS LEAK: OTHER RESOLVER FUNCTION
|
//TODO: DNS LEAK: OTHER RESOLVER FUNCTION
|
||||||
@@ -908,7 +918,6 @@ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
|
|||||||
if(!proxybound_resolver)
|
if(!proxybound_resolver)
|
||||||
return true_gethostbyaddr(addr, len, type);
|
return true_gethostbyaddr(addr, len, type);
|
||||||
else {
|
else {
|
||||||
|
|
||||||
PDEBUG("hostent: len %u\n", len);
|
PDEBUG("hostent: len %u\n", len);
|
||||||
if(len != 4)
|
if(len != 4)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
static char appVersion[5] = "5.50\n";
|
static char appVersion[5] = "5.60\n";
|
||||||
|
|
||||||
static const char *dll_name = DLL_NAME;
|
static const char *dll_name = DLL_NAME;
|
||||||
static pid_t child_pid = -1 ;
|
static pid_t child_pid = -1 ;
|
||||||
|
Reference in New Issue
Block a user