v5.60 rewrite core functions (check change log)

This commit is contained in:
intika
2019-05-31 19:42:05 +02:00
parent d0b562c9b7
commit aabf9dfeb5
4 changed files with 369 additions and 349 deletions

View File

@@ -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:
============== ==============

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 ;