commit f1301e083ed67752ef89e07f1a961ac5b635d9f2
Author: Yawning Angel <[email protected]>
Date:   Sat Nov 7 11:14:30 2015 +0000

    Add support for localhost only UDP via `AllowOutboundLocalhost 2`.
    
    Exactly what it says on the tin, setting `AllowOutboundLocalhost 2`
    will:
    
     * Allow all SOCK_DGRAM socket() calls.
     * Allow connect() to localhost, even for SOCK_DGRAM.
     * Allow SOCK_DGRAM sendto() calls, as long as the destination address
       is localhost.
    
    Fixes bug #16765.
---
 doc/torsocks.conf        |  4 +++-
 doc/torsocks.conf.5      |  7 ++++---
 src/common/compat.h      |  4 ++++
 src/common/config-file.c |  3 +++
 src/common/config-file.h |  2 +-
 src/lib/connect.c        | 14 ++++++++++----
 src/lib/sendto.c         |  8 +++++++-
 src/lib/socket.c         | 10 ++++++++++
 src/lib/torsocks.h       |  1 +
 9 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/doc/torsocks.conf b/doc/torsocks.conf
index 5dd9df6..ec99766 100644
--- a/doc/torsocks.conf
+++ b/doc/torsocks.conf
@@ -31,7 +31,9 @@ OnionAddrRange 127.42.42.0/24
 
 # Set Torsocks to allow outbound connections to the loopback interface.
 # If set to 1, connect() will be allowed to be used to the loopback interface
-# bypassing Tor. This option should not be used by most users. (Default: 0)
+# bypassing Tor. If set to 2, in addition to TCP connect(), UDP operations to
+# the loopback interface will also be allowed, bypassing Tor. This option
+# should not be used by most users. (Default: 0)
 #AllowOutboundLocalhost 1
 
 # Set Torsocks to use an automatically generated SOCKS5 username/password based
diff --git a/doc/torsocks.conf.5 b/doc/torsocks.conf.5
index 33fba3e..a6cc9b8 100644
--- a/doc/torsocks.conf.5
+++ b/doc/torsocks.conf.5
@@ -78,10 +78,11 @@ allowed for non localhost address so the applicaton can 
handle incoming
 connection. Note that Unix socket are allowed. (Default: 0)
 
 .TP
-.I AllowOutboundLocalhost 0|1
+.I AllowOutboundLocalhost 0|1|2
 Allow outbound connections to the loopback interface meaning that connect()
-will be allowed to connect to localhost addresses bypassing Tor.  This option
-should not be used by most users. (Default: 0)
+will be allowed to connect to localhost addresses bypassing Tor.  If set to 1,
+TCP connections will be allowed.  If set to 2, both TCP/IP and UDP connections
+will be allowed.  This option should not be used by most users. (Default: 0)
 
 .TP
 .I IsolatePID 0|1
diff --git a/src/common/compat.h b/src/common/compat.h
index 6c8ce32..38bf191 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -220,9 +220,13 @@ void tsocks_once(tsocks_once_t *o, void 
(*init_routine)(void));
 #if defined(__NetBSD__)
 #define IS_SOCK_STREAM(type) \
        ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC | SOCK_NOSIGPIPE)) == 
SOCK_STREAM)
+#define IS_SOCK_DGRAM(type) \
+       ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC | SOCK_NOSIGPIPE)) == 
SOCK_DGRAM)
 #else /* __NetBSD__ */
 #define IS_SOCK_STREAM(type) \
        ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) == SOCK_STREAM)
+#define IS_SOCK_DGRAM(type) \
+       ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) == SOCK_DGRAM)
 #endif /* __NetBSD__ */
 
 #endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/config-file.c b/src/common/config-file.c
index 2147068..da89ef7 100644
--- a/src/common/config-file.c
+++ b/src/common/config-file.c
@@ -406,6 +406,9 @@ int conf_file_set_allow_outbound_localhost(const char *val,
        } else if (ret == 1) {
                config->allow_outbound_localhost = 1;
                DBG("[config] Outbound localhost connections allowed.");
+       } else if (ret == 2) {
+               config->allow_outbound_localhost = 2;
+               DBG("[config] Outbound localhost connections + UDP allowed.");
        } else {
                ERR("[config] Invalid %s value for %s", val,
                                conf_allow_outbound_localhost_str);
diff --git a/src/common/config-file.h b/src/common/config-file.h
index 23dd842..48be392 100644
--- a/src/common/config-file.h
+++ b/src/common/config-file.h
@@ -82,7 +82,7 @@ struct configuration {
        /*
         * Allow outbound connections to localhost that bypass Tor.
         */
-       unsigned int allow_outbound_localhost:1;
+       unsigned int allow_outbound_localhost;
 
        /*
         * Automatically set the SOCKS5 authentication to a unique per-process
diff --git a/src/lib/connect.c b/src/lib/connect.c
index 2480643..71c5886 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000-2008 - Shaun Clowes <[email protected]> 
+ * Copyright (C) 2000-2008 - Shaun Clowes <[email protected]>
  *                              2008-2011 - Robert Hogan 
<[email protected]>
  *                                       2013 - David Goulet 
<[email protected]>
  *
@@ -45,7 +45,7 @@ TSOCKS_LIBC_DECL(connect, LIBC_CONNECT_RET_TYPE, 
LIBC_CONNECT_SIG)
  * On error or if validation fails, errno is set and -1 is returned. The caller
  * should *return* right away an error.
  */
-static int validate_socket(int sockfd, const struct sockaddr *addr)
+int tsocks_validate_socket(int sockfd, const struct sockaddr *addr)
 {
        int ret, sock_type;
        socklen_t optlen;
@@ -76,8 +76,14 @@ static int validate_socket(int sockfd, const struct sockaddr 
*addr)
        DBG("[connect] Socket family %s and type %d",
                        addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", 
sock_type);
 
-       /* Refuse non stream socket since Tor can't handle that. */
        if (!IS_SOCK_STREAM(sock_type)) {
+               if ((tsocks_config.allow_outbound_localhost == 2) &&
+                               IS_SOCK_DGRAM(sock_type) && 
utils_sockaddr_is_localhost(addr)) {
+                               DBG("[connect] Allowing localhost UDP socket.");
+                               goto libc_call;
+               }
+
+               /* Refuse non stream socket since Tor can't handle that. */
                DBG("[connect] UDP or ICMP stream can't be handled. 
Rejecting.");
                errno = EPERM;
                goto error;
@@ -115,7 +121,7 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
         * Validate socket values in order to see if we can handle this connect
         * through Tor.
         */
-       ret = validate_socket(sockfd, addr);
+       ret = tsocks_validate_socket(sockfd, addr);
        if (ret == 1) {
                /* Tor can't handle it so send it to the libc. */
                goto libc_connect;
diff --git a/src/lib/sendto.c b/src/lib/sendto.c
index 6b1d3ff..75994f4 100644
--- a/src/lib/sendto.c
+++ b/src/lib/sendto.c
@@ -43,8 +43,8 @@ TSOCKS_LIBC_DECL(sendto, LIBC_SENDTO_RET_TYPE, 
LIBC_SENDTO_SIG)
  */
 LIBC_SENDTO_RET_TYPE tsocks_sendto(LIBC_SENDTO_SIG)
 {
-#ifdef MSG_FASTOPEN
        int ret;
+#ifdef MSG_FASTOPEN
 
        if ((flags & MSG_FASTOPEN) == 0) {
                /* No TFO, fallback to libc sendto() */
@@ -64,6 +64,12 @@ LIBC_SENDTO_RET_TYPE tsocks_sendto(LIBC_SENDTO_SIG)
 libc_sendto:
 #endif /* MSG_FASTOPEN */
 
+       /* Validate that the socket and address are ok to send traffic to. */
+       ret = tsocks_validate_socket(sockfd, dest_addr);
+       if (ret == -1) {
+               return ret;
+       }
+
        return tsocks_libc_sendto(LIBC_SENDTO_ARGS);
 }
 
diff --git a/src/lib/socket.c b/src/lib/socket.c
index edc24ab..331de0b 100644
--- a/src/lib/socket.c
+++ b/src/lib/socket.c
@@ -48,6 +48,16 @@ LIBC_SOCKET_RET_TYPE tsocks_socket(LIBC_SOCKET_SIG)
                }
 
                /*
+                * If outbound localhost UDP traffic is allowed, then allow all 
UDP
+                * socket creation.  Validation on the destination addr is done 
at
+                * connect()/sendto() time.
+                */
+               if ((tsocks_config.allow_outbound_localhost == 2) &&
+                               IS_SOCK_DGRAM(type)) {
+                       goto end;
+               }
+
+               /*
                 * Print this message only in debug mode. Very often, 
applications uses
                 * the libc to do DNS resolution which first tries with UDP and 
then
                 * with TCP. It's not critical for the user to know that a non 
TCP
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 9531db5..eddd0de 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -445,6 +445,7 @@ extern struct onion_pool tsocks_onion_pool;
 
 extern unsigned int tsocks_cleaned_up;
 
+int tsocks_validate_socket(int sockfd, const struct sockaddr *addr);
 int tsocks_connect_to_tor(struct connection *conn);
 void *tsocks_find_libc_symbol(const char *symbol,
                enum tsocks_sym_action action);



_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to