Loading changes/bug12585 0 → 100644 +9 −0 Original line number Diff line number Diff line o Major features (security) - Implementation of SocksSocket option - SocksSocket implements a SOCKS proxy reachable by Unix Domain Socket. This allows client applications to communicate with Tor without having the ability to create AF_INET or AF_INET6 family sockets. If an application has permission to create a socket with AF_UNIX, it may directly communicate with Tor as if it were an other SOCKS proxy. This should allow high risk applications to be entirely prevented from connecting directly with TCP/IP, they will be able to only connect to the internet through AF_UNIX and only through Tor. doc/tor.1.txt +9 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,15 @@ GENERAL OPTIONS in accordance to RFC 1929. Both username and password must be between 1 and 255 characters. [[SocksSocket]] **SocksSocket** __Path__:: Like SocksPort, but listens on a Unix domain socket, rather than a TCP socket. (Unix and Unix-like systems only.) [[SocksSocketsGroupWritable]] **SocksSocketsGroupWritable** **0**|**1**:: If this option is set to 0, don't allow the filesystem group to read and write unix sockets (e.g. SocksSocket). If the option is set to 1, make the SocksSocket socket readable and writable by the default GID. (Default: 0) [[KeepalivePeriod]] **KeepalivePeriod** __NUM__:: To keep firewalls from expiring connections, send a padding keepalive cell every NUM seconds on open connections that are in use. If the connection Loading src/common/address.c +21 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,9 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, tor_addr_from_in6(a, &sin6->sin6_addr); if (port_out) *port_out = ntohs(sin6->sin6_port); } else if (sa->sa_family == AF_UNIX) { tor_addr_make_af_unix(a); return -1; } else { tor_addr_make_unspec(a); return -1; Loading Loading @@ -182,6 +185,14 @@ tor_addr_make_unspec(tor_addr_t *a) a->family = AF_UNSPEC; } /** Set address <b>a</b> to zero. This address belongs to * the AF_UNIX family. */ void tor_addr_make_af_unix(tor_addr_t *a) { memset(a, 0, sizeof(*a)); a->family = AF_UNIX; } /** Set address <b>a</b> to the null address in address family <b>family</b>. * The null address for AF_INET is 0.0.0.0. The null address for AF_INET6 is * [::]. AF_UNSPEC is all null. */ Loading Loading @@ -410,6 +421,14 @@ tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate) ptr = dest; } break; case AF_UNIX: tor_snprintf(dest, len, "AF_UNIX"); ptr = dest; break; case AF_UNSPEC: tor_snprintf(dest, len, "AF_UNSPEC"); ptr = dest; break; default: return NULL; } Loading Loading @@ -801,6 +820,8 @@ tor_addr_is_null(const tor_addr_t *addr) } case AF_INET: return (tor_addr_to_ipv4n(addr) == 0); case AF_UNIX: return 1; case AF_UNSPEC: return 1; default: Loading src/common/address.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port, int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, uint16_t *port_out); void tor_addr_make_unspec(tor_addr_t *a); void tor_addr_make_af_unix(tor_addr_t *a); void tor_addr_make_null(tor_addr_t *a, sa_family_t family); char *tor_sockaddr_to_str(const struct sockaddr *sa); Loading src/or/config.c +22 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,8 @@ static config_var_t option_vars_[] = { V(ControlPortWriteToFile, FILENAME, NULL), V(ControlSocket, LINELIST, NULL), V(ControlSocketsGroupWritable, BOOL, "0"), V(SocksSocket, LINELIST, NULL), V(SocksSocketsGroupWritable, BOOL, "0"), V(CookieAuthentication, BOOL, "0"), V(CookieAuthFileGroupReadable, BOOL, "0"), V(CookieAuthFile, STRING, NULL), Loading Loading @@ -1045,6 +1047,20 @@ options_act_reversible(const or_options_t *old_options, char **msg) } #endif #ifndef HAVE_SYS_UN_H if (options->SocksSocket || options->SocksSocketsGroupWritable) { *msg = tor_strdup("Unix domain sockets (SocksSocket) not supported " "on this OS/with this build."); goto rollback; } #else if (options->SocksSocketsGroupWritable && !options->SocksSocket) { *msg = tor_strdup("Setting SocksSocketGroupWritable without setting" "a SocksSocket makes no sense."); goto rollback; } #endif if (running_tor) { int n_ports=0; /* We need to set the connection limit before we can open the listeners. */ Loading Loading @@ -6055,6 +6071,12 @@ parse_ports(or_options_t *options, int validate_only, *msg = tor_strdup("Invalid ControlSocket configuration"); goto err; } if (parse_unix_socket_config(ports, options->SocksSocket, CONN_TYPE_AP_LISTENER) < 0) { *msg = tor_strdup("Invalid SocksSocket configuration"); goto err; } } if (! options->ClientOnly) { if (parse_port_config(ports, Loading Loading
changes/bug12585 0 → 100644 +9 −0 Original line number Diff line number Diff line o Major features (security) - Implementation of SocksSocket option - SocksSocket implements a SOCKS proxy reachable by Unix Domain Socket. This allows client applications to communicate with Tor without having the ability to create AF_INET or AF_INET6 family sockets. If an application has permission to create a socket with AF_UNIX, it may directly communicate with Tor as if it were an other SOCKS proxy. This should allow high risk applications to be entirely prevented from connecting directly with TCP/IP, they will be able to only connect to the internet through AF_UNIX and only through Tor.
doc/tor.1.txt +9 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,15 @@ GENERAL OPTIONS in accordance to RFC 1929. Both username and password must be between 1 and 255 characters. [[SocksSocket]] **SocksSocket** __Path__:: Like SocksPort, but listens on a Unix domain socket, rather than a TCP socket. (Unix and Unix-like systems only.) [[SocksSocketsGroupWritable]] **SocksSocketsGroupWritable** **0**|**1**:: If this option is set to 0, don't allow the filesystem group to read and write unix sockets (e.g. SocksSocket). If the option is set to 1, make the SocksSocket socket readable and writable by the default GID. (Default: 0) [[KeepalivePeriod]] **KeepalivePeriod** __NUM__:: To keep firewalls from expiring connections, send a padding keepalive cell every NUM seconds on open connections that are in use. If the connection Loading
src/common/address.c +21 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,9 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, tor_addr_from_in6(a, &sin6->sin6_addr); if (port_out) *port_out = ntohs(sin6->sin6_port); } else if (sa->sa_family == AF_UNIX) { tor_addr_make_af_unix(a); return -1; } else { tor_addr_make_unspec(a); return -1; Loading Loading @@ -182,6 +185,14 @@ tor_addr_make_unspec(tor_addr_t *a) a->family = AF_UNSPEC; } /** Set address <b>a</b> to zero. This address belongs to * the AF_UNIX family. */ void tor_addr_make_af_unix(tor_addr_t *a) { memset(a, 0, sizeof(*a)); a->family = AF_UNIX; } /** Set address <b>a</b> to the null address in address family <b>family</b>. * The null address for AF_INET is 0.0.0.0. The null address for AF_INET6 is * [::]. AF_UNSPEC is all null. */ Loading Loading @@ -410,6 +421,14 @@ tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate) ptr = dest; } break; case AF_UNIX: tor_snprintf(dest, len, "AF_UNIX"); ptr = dest; break; case AF_UNSPEC: tor_snprintf(dest, len, "AF_UNSPEC"); ptr = dest; break; default: return NULL; } Loading Loading @@ -801,6 +820,8 @@ tor_addr_is_null(const tor_addr_t *addr) } case AF_INET: return (tor_addr_to_ipv4n(addr) == 0); case AF_UNIX: return 1; case AF_UNSPEC: return 1; default: Loading
src/common/address.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port, int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, uint16_t *port_out); void tor_addr_make_unspec(tor_addr_t *a); void tor_addr_make_af_unix(tor_addr_t *a); void tor_addr_make_null(tor_addr_t *a, sa_family_t family); char *tor_sockaddr_to_str(const struct sockaddr *sa); Loading
src/or/config.c +22 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,8 @@ static config_var_t option_vars_[] = { V(ControlPortWriteToFile, FILENAME, NULL), V(ControlSocket, LINELIST, NULL), V(ControlSocketsGroupWritable, BOOL, "0"), V(SocksSocket, LINELIST, NULL), V(SocksSocketsGroupWritable, BOOL, "0"), V(CookieAuthentication, BOOL, "0"), V(CookieAuthFileGroupReadable, BOOL, "0"), V(CookieAuthFile, STRING, NULL), Loading Loading @@ -1045,6 +1047,20 @@ options_act_reversible(const or_options_t *old_options, char **msg) } #endif #ifndef HAVE_SYS_UN_H if (options->SocksSocket || options->SocksSocketsGroupWritable) { *msg = tor_strdup("Unix domain sockets (SocksSocket) not supported " "on this OS/with this build."); goto rollback; } #else if (options->SocksSocketsGroupWritable && !options->SocksSocket) { *msg = tor_strdup("Setting SocksSocketGroupWritable without setting" "a SocksSocket makes no sense."); goto rollback; } #endif if (running_tor) { int n_ports=0; /* We need to set the connection limit before we can open the listeners. */ Loading Loading @@ -6055,6 +6071,12 @@ parse_ports(or_options_t *options, int validate_only, *msg = tor_strdup("Invalid ControlSocket configuration"); goto err; } if (parse_unix_socket_config(ports, options->SocksSocket, CONN_TYPE_AP_LISTENER) < 0) { *msg = tor_strdup("Invalid SocksSocket configuration"); goto err; } } if (! options->ClientOnly) { if (parse_port_config(ports, Loading