mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Merge remote-tracking branch 'andrea/ticket12585_v3'
This commit is contained in:
commit
d8b7dcca8d
9
changes/bug12585
Normal file
9
changes/bug12585
Normal file
@ -0,0 +1,9 @@
|
||||
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.
|
@ -294,7 +294,7 @@ GENERAL OPTIONS
|
||||
|
||||
[[ControlSocket]] **ControlSocket** __Path__::
|
||||
Like ControlPort, but listens on a Unix domain socket, rather than a TCP
|
||||
socket. (Unix and Unix-like systems only.)
|
||||
socket. '0' disables ControlSocket (Unix and Unix-like systems only.)
|
||||
|
||||
[[ControlSocketsGroupWritable]] **ControlSocketsGroupWritable** **0**|**1**::
|
||||
If this option is set to 0, don't allow the filesystem group to read and
|
||||
@ -483,6 +483,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. '0' disables SocksSocket (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
|
||||
|
@ -121,6 +121,15 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
|
||||
}
|
||||
}
|
||||
|
||||
/** Set address <b>a</b> to zero. This address belongs to
|
||||
* the AF_UNIX family. */
|
||||
static void
|
||||
tor_addr_make_af_unix(tor_addr_t *a)
|
||||
{
|
||||
memset(a, 0, sizeof(*a));
|
||||
a->family = AF_UNIX;
|
||||
}
|
||||
|
||||
/** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
|
||||
* <b>sa</b>. */
|
||||
int
|
||||
@ -142,6 +151,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 0;
|
||||
} else {
|
||||
tor_addr_make_unspec(a);
|
||||
return -1;
|
||||
@ -421,6 +433,10 @@ 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;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -816,6 +832,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:
|
||||
|
110
src/or/config.c
110
src/or/config.c
@ -200,6 +200,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),
|
||||
@ -1047,6 +1049,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. */
|
||||
@ -6034,22 +6050,87 @@ parse_port_config(smartlist_t *out,
|
||||
|
||||
/** Parse a list of config_line_t for an AF_UNIX unix socket listener option
|
||||
* from <b>cfg</b> and add them to <b>out</b>. No fancy options are
|
||||
* supported: the line contains nothing but the path to the AF_UNIX socket. */
|
||||
* supported: the line contains nothing but the path to the AF_UNIX socket.
|
||||
* We support a *Socket 0 syntax to explicitly disable if we enable by
|
||||
* default. To use this, pass a non-NULL list containing the default
|
||||
* paths into this function as the 2nd parameter, and if no config lines at all
|
||||
* are present they will be added to the output list. If the only config line
|
||||
* present is '0' the input list will be unmodified.
|
||||
*/
|
||||
static int
|
||||
parse_unix_socket_config(smartlist_t *out, const config_line_t *cfg,
|
||||
int listener_type)
|
||||
parse_unix_socket_config(smartlist_t *out, smartlist_t *defaults,
|
||||
const config_line_t *cfg, int listener_type)
|
||||
{
|
||||
/* We can say things like SocksSocket 0 or ControlSocket 0 to explicitly
|
||||
* disable this feature; use this to track if we've seen a disable line
|
||||
*/
|
||||
|
||||
int unix_socket_disable = 0;
|
||||
size_t len;
|
||||
smartlist_t *ports_to_add = NULL;
|
||||
|
||||
if (!out)
|
||||
return 0;
|
||||
|
||||
ports_to_add = smartlist_new();
|
||||
|
||||
for ( ; cfg; cfg = cfg->next) {
|
||||
size_t len = strlen(cfg->value);
|
||||
port_cfg_t *port = tor_malloc_zero(sizeof(port_cfg_t) + len + 1);
|
||||
port->is_unix_addr = 1;
|
||||
memcpy(port->unix_addr, cfg->value, len+1);
|
||||
port->type = listener_type;
|
||||
smartlist_add(out, port);
|
||||
if (strcmp(cfg->value, "0") != 0) {
|
||||
/* We have a non-disable; add it */
|
||||
len = strlen(cfg->value);
|
||||
port_cfg_t *port = tor_malloc_zero(sizeof(port_cfg_t) + len + 1);
|
||||
port->is_unix_addr = 1;
|
||||
memcpy(port->unix_addr, cfg->value, len+1);
|
||||
port->type = listener_type;
|
||||
if (listener_type == CONN_TYPE_AP_LISTENER) {
|
||||
/* Some more bits to twiddle for this case
|
||||
*
|
||||
* XXX this should support parsing the same options
|
||||
* parse_port_config() does, and probably that code should be
|
||||
* factored out into a function we can call from here. For
|
||||
* now, some reasonable defaults.
|
||||
*/
|
||||
|
||||
port->ipv4_traffic = 1;
|
||||
port->ipv6_traffic = 1;
|
||||
port->cache_ipv4_answers = 1;
|
||||
port->cache_ipv6_answers = 1;
|
||||
}
|
||||
smartlist_add(ports_to_add, port);
|
||||
} else {
|
||||
/* Keep track that we've seen a disable */
|
||||
unix_socket_disable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (unix_socket_disable) {
|
||||
if (smartlist_len(ports_to_add) > 0) {
|
||||
/* We saw a disable line and a path; bad news */
|
||||
SMARTLIST_FOREACH(ports_to_add, port_cfg_t *, port, tor_free(port));
|
||||
smartlist_free(ports_to_add);
|
||||
return -1;
|
||||
}
|
||||
/* else we have a disable and nothing else, so add nothing to out */
|
||||
} else {
|
||||
/* No disable; do we have any ports to add that we parsed? */
|
||||
if (smartlist_len(ports_to_add) > 0) {
|
||||
SMARTLIST_FOREACH_BEGIN(ports_to_add, port_cfg_t *, port) {
|
||||
smartlist_add(out, port);
|
||||
} SMARTLIST_FOREACH_END(port);
|
||||
} else if (defaults != NULL && smartlist_len(defaults) > 0) {
|
||||
/* No, but we have some defaults to copy */
|
||||
SMARTLIST_FOREACH_BEGIN(defaults, const port_cfg_t *, defport) {
|
||||
tor_assert(defport->is_unix_addr);
|
||||
tor_assert(defport->unix_addr);
|
||||
len = sizeof(port_cfg_t) + strlen(defport->unix_addr) + 1;
|
||||
port_cfg_t *port = tor_malloc_zero(len);
|
||||
memcpy(port, defport, len);
|
||||
smartlist_add(out, port);
|
||||
} SMARTLIST_FOREACH_END(defport);
|
||||
}
|
||||
|
||||
/* Free the temporary smartlist we used */
|
||||
smartlist_free(ports_to_add);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -6143,12 +6224,19 @@ parse_ports(or_options_t *options, int validate_only,
|
||||
"configuration");
|
||||
goto err;
|
||||
}
|
||||
if (parse_unix_socket_config(ports,
|
||||
|
||||
if (parse_unix_socket_config(ports, NULL,
|
||||
options->ControlSocket,
|
||||
CONN_TYPE_CONTROL_LISTENER) < 0) {
|
||||
*msg = tor_strdup("Invalid ControlSocket configuration");
|
||||
goto err;
|
||||
}
|
||||
if (parse_unix_socket_config(ports, NULL,
|
||||
options->SocksSocket,
|
||||
CONN_TYPE_AP_LISTENER) < 0) {
|
||||
*msg = tor_strdup("Invalid SocksSocket configuration");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (! options->ClientOnly) {
|
||||
if (parse_port_config(ports,
|
||||
@ -6192,6 +6280,8 @@ parse_ports(or_options_t *options, int validate_only,
|
||||
!! count_real_listeners(ports, CONN_TYPE_OR_LISTENER);
|
||||
options->SocksPort_set =
|
||||
!! count_real_listeners(ports, CONN_TYPE_AP_LISTENER);
|
||||
options->SocksSocket_set =
|
||||
!! count_real_listeners(ports, CONN_TYPE_AP_LISTENER);
|
||||
options->TransPort_set =
|
||||
!! count_real_listeners(ports, CONN_TYPE_AP_TRANS_LISTENER);
|
||||
options->NATDPort_set =
|
||||
|
@ -308,6 +308,8 @@ entry_connection_new(int type, int socket_family)
|
||||
entry_conn->ipv4_traffic_ok = 1;
|
||||
else if (socket_family == AF_INET6)
|
||||
entry_conn->ipv6_traffic_ok = 1;
|
||||
else if (socket_family == AF_UNIX)
|
||||
entry_conn->is_socks_socket = 1;
|
||||
return entry_conn;
|
||||
}
|
||||
|
||||
@ -516,9 +518,10 @@ connection_free_(connection_t *conn)
|
||||
buf_free(conn->outbuf);
|
||||
} else {
|
||||
if (conn->socket_family == AF_UNIX) {
|
||||
/* For now only control ports can be Unix domain sockets
|
||||
/* For now only control and SOCKS ports can be Unix domain sockets
|
||||
* and listeners at the same time */
|
||||
tor_assert(conn->type == CONN_TYPE_CONTROL_LISTENER);
|
||||
tor_assert(conn->type == CONN_TYPE_CONTROL_LISTENER ||
|
||||
conn->type == CONN_TYPE_AP_LISTENER);
|
||||
|
||||
if (unlink(conn->address) < 0 && errno != ENOENT) {
|
||||
log_warn(LD_NET, "Could not unlink %s: %s", conn->address,
|
||||
@ -915,13 +918,57 @@ warn_too_many_conns(void)
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
||||
#define UNIX_SOCKET_PURPOSE_CONTROL_SOCKET 0
|
||||
#define UNIX_SOCKET_PURPOSE_SOCKS_SOCKET 1
|
||||
|
||||
/** Check if the purpose isn't one of the ones we know what to do with */
|
||||
|
||||
static int
|
||||
is_valid_unix_socket_purpose(int purpose)
|
||||
{
|
||||
int valid = 0;
|
||||
|
||||
switch (purpose) {
|
||||
case UNIX_SOCKET_PURPOSE_CONTROL_SOCKET:
|
||||
case UNIX_SOCKET_PURPOSE_SOCKS_SOCKET:
|
||||
valid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/** Return a string description of a unix socket purpose */
|
||||
static const char *
|
||||
unix_socket_purpose_to_string(int purpose)
|
||||
{
|
||||
const char *s = "unknown-purpose socket";
|
||||
|
||||
switch (purpose) {
|
||||
case UNIX_SOCKET_PURPOSE_CONTROL_SOCKET:
|
||||
s = "control socket";
|
||||
break;
|
||||
case UNIX_SOCKET_PURPOSE_SOCKS_SOCKET:
|
||||
s = "SOCKS socket";
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Check whether we should be willing to open an AF_UNIX socket in
|
||||
* <b>path</b>. Return 0 if we should go ahead and -1 if we shouldn't. */
|
||||
static int
|
||||
check_location_for_unix_socket(const or_options_t *options, const char *path)
|
||||
check_location_for_unix_socket(const or_options_t *options, const char *path,
|
||||
int purpose)
|
||||
{
|
||||
int r = -1;
|
||||
char *p = tor_strdup(path);
|
||||
char *p = NULL;
|
||||
|
||||
tor_assert(is_valid_unix_socket_purpose(purpose));
|
||||
|
||||
p = tor_strdup(path);
|
||||
cpd_check_t flags = CPD_CHECK_MODE_ONLY;
|
||||
if (get_parent_directory(p)<0 || p[0] != '/') {
|
||||
log_warn(LD_GENERAL, "Bad unix socket address '%s'. Tor does not support "
|
||||
@ -929,18 +976,23 @@ check_location_for_unix_socket(const or_options_t *options, const char *path)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (options->ControlSocketsGroupWritable)
|
||||
if ((purpose == UNIX_SOCKET_PURPOSE_CONTROL_SOCKET &&
|
||||
options->ControlSocketsGroupWritable) ||
|
||||
(purpose == UNIX_SOCKET_PURPOSE_SOCKS_SOCKET &&
|
||||
options->SocksSocketsGroupWritable)) {
|
||||
flags |= CPD_GROUP_OK;
|
||||
}
|
||||
|
||||
if (check_private_dir(p, flags, options->User) < 0) {
|
||||
char *escpath, *escdir;
|
||||
escpath = esc_for_log(path);
|
||||
escdir = esc_for_log(p);
|
||||
log_warn(LD_GENERAL, "Before Tor can create a control socket in %s, the "
|
||||
"directory %s needs to exist, and to be accessible only by the "
|
||||
"user%s account that is running Tor. (On some Unix systems, "
|
||||
"anybody who can list a socket can connect to it, so Tor is "
|
||||
"being careful.)", escpath, escdir,
|
||||
log_warn(LD_GENERAL, "Before Tor can create a %s in %s, the directory "
|
||||
"%s needs to exist, and to be accessible only by the user%s "
|
||||
"account that is running Tor. (On some Unix systems, anybody "
|
||||
"who can list a socket can connect to it, so Tor is being "
|
||||
"careful.)",
|
||||
unix_socket_purpose_to_string(purpose), escpath, escdir,
|
||||
options->ControlSocketsGroupWritable ? " and group" : "");
|
||||
tor_free(escpath);
|
||||
tor_free(escdir);
|
||||
@ -1030,8 +1082,8 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
|
||||
if (listensockaddr->sa_family == AF_INET ||
|
||||
listensockaddr->sa_family == AF_INET6) {
|
||||
int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER);
|
||||
if (is_tcp)
|
||||
int is_stream = (type != CONN_TYPE_AP_DNS_LISTENER);
|
||||
if (is_stream)
|
||||
start_reading = 1;
|
||||
|
||||
tor_addr_from_sockaddr(&addr, listensockaddr, &usePort);
|
||||
@ -1040,10 +1092,10 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
conn_type_to_string(type), fmt_addrport(&addr, usePort));
|
||||
|
||||
s = tor_open_socket_nonblocking(tor_addr_family(&addr),
|
||||
is_tcp ? SOCK_STREAM : SOCK_DGRAM,
|
||||
is_tcp ? IPPROTO_TCP: IPPROTO_UDP);
|
||||
is_stream ? SOCK_STREAM : SOCK_DGRAM,
|
||||
is_stream ? IPPROTO_TCP: IPPROTO_UDP);
|
||||
if (!SOCKET_OK(s)) {
|
||||
log_warn(LD_NET,"Socket creation failed: %s",
|
||||
log_warn(LD_NET, "Socket creation failed: %s",
|
||||
tor_socket_strerror(tor_socket_errno(-1)));
|
||||
goto err;
|
||||
}
|
||||
@ -1100,7 +1152,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_tcp) {
|
||||
if (is_stream) {
|
||||
if (tor_listen(s) < 0) {
|
||||
log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort,
|
||||
tor_socket_strerror(tor_socket_errno(s)));
|
||||
@ -1123,15 +1175,25 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
tor_addr_from_sockaddr(&addr2, (struct sockaddr*)&ss, &gotPort);
|
||||
}
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
/*
|
||||
* AF_UNIX generic setup stuff (this covers both CONN_TYPE_CONTROL_LISTENER
|
||||
* and CONN_TYPE_AP_LISTENER cases)
|
||||
*/
|
||||
} else if (listensockaddr->sa_family == AF_UNIX) {
|
||||
/* We want to start reading for both AF_UNIX cases */
|
||||
start_reading = 1;
|
||||
|
||||
/* For now only control ports can be Unix domain sockets
|
||||
/* For now only control ports or SOCKS ports can be Unix domain sockets
|
||||
* and listeners at the same time */
|
||||
tor_assert(type == CONN_TYPE_CONTROL_LISTENER);
|
||||
tor_assert(type == CONN_TYPE_CONTROL_LISTENER ||
|
||||
type == CONN_TYPE_AP_LISTENER);
|
||||
|
||||
if (check_location_for_unix_socket(options, address) < 0)
|
||||
goto err;
|
||||
if (check_location_for_unix_socket(options, address,
|
||||
(type == CONN_TYPE_CONTROL_LISTENER) ?
|
||||
UNIX_SOCKET_PURPOSE_CONTROL_SOCKET :
|
||||
UNIX_SOCKET_PURPOSE_SOCKS_SOCKET) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
log_notice(LD_NET, "Opening %s on %s",
|
||||
conn_type_to_string(type), address);
|
||||
@ -1143,17 +1205,20 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
s = tor_open_socket_nonblocking(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (! SOCKET_OK(s)) {
|
||||
log_warn(LD_NET,"Socket creation failed: %s.", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (bind(s, listensockaddr, (socklen_t)sizeof(struct sockaddr_un)) == -1) {
|
||||
if (bind(s, listensockaddr,
|
||||
(socklen_t)sizeof(struct sockaddr_un)) == -1) {
|
||||
log_warn(LD_NET,"Bind to %s failed: %s.", address,
|
||||
tor_socket_strerror(tor_socket_errno(s)));
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
if (options->User) {
|
||||
pw = tor_getpwnam(options->User);
|
||||
@ -1168,13 +1233,27 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (options->ControlSocketsGroupWritable) {
|
||||
|
||||
if ((type == CONN_TYPE_CONTROL_LISTENER &&
|
||||
options->ControlSocketsGroupWritable) ||
|
||||
(type == CONN_TYPE_AP_LISTENER &&
|
||||
options->SocksSocketsGroupWritable)) {
|
||||
/* We need to use chmod; fchmod doesn't work on sockets on all
|
||||
* platforms. */
|
||||
if (chmod(address, 0660) < 0) {
|
||||
log_warn(LD_FS,"Unable to make %s group-writable.", address);
|
||||
goto err;
|
||||
}
|
||||
} else if ((type == CONN_TYPE_CONTROL_LISTENER &&
|
||||
!(options->ControlSocketsGroupWritable)) ||
|
||||
(type == CONN_TYPE_AP_LISTENER &&
|
||||
!(options->SocksSocketsGroupWritable))) {
|
||||
/* We need to use chmod; fchmod doesn't work on sockets on all
|
||||
* platforms. */
|
||||
if (chmod(address, 0600) < 0) {
|
||||
log_warn(LD_FS,"Unable to make %s group-writable.", address);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(s, SOMAXCONN) < 0) {
|
||||
@ -1182,8 +1261,6 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||
tor_socket_strerror(tor_socket_errno(s)));
|
||||
goto err;
|
||||
}
|
||||
#else
|
||||
(void)options;
|
||||
#endif /* HAVE_SYS_UN_H */
|
||||
} else {
|
||||
log_err(LD_BUG, "Got unexpected address family %d.",
|
||||
@ -1294,6 +1371,8 @@ check_sockaddr(const struct sockaddr *sa, int len, int level)
|
||||
"Address for new connection has address/port equal to zero.");
|
||||
ok = 0;
|
||||
}
|
||||
} else if (sa->sa_family == AF_UNIX) {
|
||||
ok = 1;
|
||||
} else {
|
||||
ok = 0;
|
||||
}
|
||||
@ -1378,7 +1457,8 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conn->socket_family == AF_INET || conn->socket_family == AF_INET6) {
|
||||
if (conn->socket_family == AF_INET || conn->socket_family == AF_INET6 ||
|
||||
(conn->socket_family == AF_UNIX && new_type == CONN_TYPE_AP)) {
|
||||
tor_addr_t addr;
|
||||
uint16_t port;
|
||||
if (check_sockaddr(remote, remotelen, LOG_INFO)<0) {
|
||||
@ -1419,7 +1499,16 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
||||
newconn->port = port;
|
||||
newconn->address = tor_dup_addr(&addr);
|
||||
|
||||
if (new_type == CONN_TYPE_AP) {
|
||||
if (new_type == CONN_TYPE_AP && conn->socket_family != AF_UNIX) {
|
||||
log_notice(LD_NET, "New SOCKS connection opened from %s.",
|
||||
fmt_and_decorate_addr(&addr));
|
||||
TO_ENTRY_CONN(newconn)->socks_request->socks_prefer_no_auth =
|
||||
TO_LISTENER_CONN(conn)->socks_prefer_no_auth;
|
||||
}
|
||||
if (new_type == CONN_TYPE_AP && conn->socket_family == AF_UNIX) {
|
||||
newconn->port = 0;
|
||||
newconn->address = tor_strdup(conn->address);
|
||||
log_info(LD_NET, "New SOCKS SocksSocket connection opened");
|
||||
TO_ENTRY_CONN(newconn)->socks_request->socks_prefer_no_auth =
|
||||
TO_LISTENER_CONN(conn)->socks_prefer_no_auth;
|
||||
}
|
||||
@ -1428,9 +1517,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
||||
fmt_and_decorate_addr(&addr));
|
||||
}
|
||||
|
||||
} else if (conn->socket_family == AF_UNIX) {
|
||||
/* For now only control ports can be Unix domain sockets
|
||||
* and listeners at the same time */
|
||||
} else if (conn->socket_family == AF_UNIX && conn->type != CONN_TYPE_AP) {
|
||||
tor_assert(conn->type == CONN_TYPE_CONTROL_LISTENER);
|
||||
tor_assert(new_type == CONN_TYPE_CONTROL);
|
||||
log_notice(LD_CONTROL, "New control connection opened.");
|
||||
@ -2392,6 +2479,7 @@ connection_is_rate_limited(connection_t *conn)
|
||||
return 0; /* Internal connection */
|
||||
else if (! options->CountPrivateBandwidth &&
|
||||
(tor_addr_family(&conn->addr) == AF_UNSPEC || /* no address */
|
||||
tor_addr_family(&conn->addr) == AF_UNIX || /* no address */
|
||||
tor_addr_is_internal(&conn->addr, 0)))
|
||||
return 0; /* Internal address */
|
||||
else
|
||||
|
@ -391,6 +391,10 @@ connection_remove(connection_t *conn)
|
||||
(int)conn->s, conn_type_to_string(conn->type),
|
||||
smartlist_len(connection_array));
|
||||
|
||||
if (conn->type == CONN_TYPE_AP && conn->socket_family == AF_UNIX) {
|
||||
log_info(LD_NET, "Closing SOCKS SocksSocket connection");
|
||||
}
|
||||
|
||||
control_event_conn_bandwidth(conn);
|
||||
|
||||
tor_assert(conn->conn_array_index >= 0);
|
||||
|
@ -1702,6 +1702,9 @@ typedef struct entry_connection_t {
|
||||
* do we prefer IPv6? */
|
||||
unsigned int prefer_ipv6_virtaddr : 1;
|
||||
|
||||
/** Are we a socks SocksSocket listener? */
|
||||
unsigned int is_socks_socket:1;
|
||||
|
||||
} entry_connection_t;
|
||||
|
||||
typedef enum {
|
||||
@ -3528,6 +3531,10 @@ typedef struct {
|
||||
* for control connections. */
|
||||
|
||||
int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */
|
||||
config_line_t *SocksSocket; /**< List of Unix Domain Sockets to listen on
|
||||
* for SOCKS connections. */
|
||||
|
||||
int SocksSocketsGroupWritable; /**< Boolean: Are SOCKS sockets g+rw? */
|
||||
/** Ports to listen on for directory connections. */
|
||||
config_line_t *DirPort_lines;
|
||||
config_line_t *DNSPort_lines; /**< Ports to listen on for DNS requests. */
|
||||
@ -3550,6 +3557,7 @@ typedef struct {
|
||||
*/
|
||||
unsigned int ORPort_set : 1;
|
||||
unsigned int SocksPort_set : 1;
|
||||
unsigned int SocksSocket_set : 1;
|
||||
unsigned int TransPort_set : 1;
|
||||
unsigned int NATDPort_set : 1;
|
||||
unsigned int ControlPort_set : 1;
|
||||
|
@ -1327,8 +1327,8 @@ connection_edge_process_relay_cell_not_open(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((family == AF_INET && ! entry_conn->ipv4_traffic_ok) ||
|
||||
(family == AF_INET6 && ! entry_conn->ipv6_traffic_ok)) {
|
||||
if (((family == AF_INET && ! entry_conn->ipv4_traffic_ok) ||
|
||||
(family == AF_INET6 && ! entry_conn->ipv6_traffic_ok))) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_APP,
|
||||
"Got a connected cell to %s with unsupported address family."
|
||||
" Closing.", fmt_addr(&addr));
|
||||
|
Loading…
Reference in New Issue
Block a user