mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Unify parse_unix_socket_config and parse_port_config
This incidentally makes unix SocksSocket support all the same options as SocksPort. This patch breaks 'SocksSocket 0'; next will restore it. Resolves 14254.
This commit is contained in:
parent
bbad23bf37
commit
485fdcf826
@ -483,7 +483,7 @@ GENERAL OPTIONS
|
|||||||
in accordance to RFC 1929. Both username and password must be between 1 and
|
in accordance to RFC 1929. Both username and password must be between 1 and
|
||||||
255 characters.
|
255 characters.
|
||||||
|
|
||||||
[[SocksSocket]] **SocksSocket** __Path__::
|
[[SocksSocket]] **SocksSocket** __Path__ [_flags_] [_isolation flags_]::
|
||||||
Like SocksPort, but listens on a Unix domain socket, rather than a TCP
|
Like SocksPort, but listens on a Unix domain socket, rather than a TCP
|
||||||
socket. '0' disables SocksSocket (Unix and Unix-like systems only.)
|
socket. '0' disables SocksSocket (Unix and Unix-like systems only.)
|
||||||
|
|
||||||
|
150
src/or/config.c
150
src/or/config.c
@ -5509,9 +5509,10 @@ parse_dir_fallback_line(const char *line,
|
|||||||
|
|
||||||
/** Allocate and return a new port_cfg_t with reasonable defaults. */
|
/** Allocate and return a new port_cfg_t with reasonable defaults. */
|
||||||
static port_cfg_t *
|
static port_cfg_t *
|
||||||
port_cfg_new(void)
|
port_cfg_new(size_t namelen)
|
||||||
{
|
{
|
||||||
port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t));
|
tor_assert(namelen <= SIZE_T_CEILING - sizeof(port_cfg_t) - 1);
|
||||||
|
port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t) + namelen + 1);
|
||||||
cfg->entry_cfg.ipv4_traffic = 1;
|
cfg->entry_cfg.ipv4_traffic = 1;
|
||||||
cfg->entry_cfg.cache_ipv4_answers = 1;
|
cfg->entry_cfg.cache_ipv4_answers = 1;
|
||||||
cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
|
cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
|
||||||
@ -5621,6 +5622,7 @@ warn_nonlocal_controller_ports(smartlist_t *ports, unsigned forbid)
|
|||||||
#define CL_PORT_SERVER_OPTIONS (1u<<3)
|
#define CL_PORT_SERVER_OPTIONS (1u<<3)
|
||||||
#define CL_PORT_FORBID_NONLOCAL (1u<<4)
|
#define CL_PORT_FORBID_NONLOCAL (1u<<4)
|
||||||
#define CL_PORT_TAKES_HOSTNAMES (1u<<5)
|
#define CL_PORT_TAKES_HOSTNAMES (1u<<5)
|
||||||
|
#define CL_PORT_IS_UNIXSOCKET (1u<<6)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse port configuration for a single port type.
|
* Parse port configuration for a single port type.
|
||||||
@ -5668,7 +5670,7 @@ parse_port_config(smartlist_t *out,
|
|||||||
int listener_type,
|
int listener_type,
|
||||||
const char *defaultaddr,
|
const char *defaultaddr,
|
||||||
int defaultport,
|
int defaultport,
|
||||||
unsigned flags)
|
const unsigned flags)
|
||||||
{
|
{
|
||||||
smartlist_t *elts;
|
smartlist_t *elts;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
@ -5681,6 +5683,7 @@ parse_port_config(smartlist_t *out,
|
|||||||
const unsigned allow_spurious_listenaddr =
|
const unsigned allow_spurious_listenaddr =
|
||||||
flags & CL_PORT_ALLOW_EXTRA_LISTENADDR;
|
flags & CL_PORT_ALLOW_EXTRA_LISTENADDR;
|
||||||
const unsigned takes_hostnames = flags & CL_PORT_TAKES_HOSTNAMES;
|
const unsigned takes_hostnames = flags & CL_PORT_TAKES_HOSTNAMES;
|
||||||
|
const unsigned is_unix_socket = flags & CL_PORT_IS_UNIXSOCKET;
|
||||||
int got_zero_port=0, got_nonzero_port=0;
|
int got_zero_port=0, got_nonzero_port=0;
|
||||||
|
|
||||||
/* FooListenAddress is deprecated; let's make it work like it used to work,
|
/* FooListenAddress is deprecated; let's make it work like it used to work,
|
||||||
@ -5717,7 +5720,7 @@ parse_port_config(smartlist_t *out,
|
|||||||
|
|
||||||
if (use_server_options && out) {
|
if (use_server_options && out) {
|
||||||
/* Add a no_listen port. */
|
/* Add a no_listen port. */
|
||||||
port_cfg_t *cfg = port_cfg_new();
|
port_cfg_t *cfg = port_cfg_new(0);
|
||||||
cfg->type = listener_type;
|
cfg->type = listener_type;
|
||||||
cfg->port = mainport;
|
cfg->port = mainport;
|
||||||
tor_addr_make_unspec(&cfg->addr); /* Server ports default to 0.0.0.0 */
|
tor_addr_make_unspec(&cfg->addr); /* Server ports default to 0.0.0.0 */
|
||||||
@ -5737,7 +5740,7 @@ parse_port_config(smartlist_t *out,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (out) {
|
if (out) {
|
||||||
port_cfg_t *cfg = port_cfg_new();
|
port_cfg_t *cfg = port_cfg_new(0);
|
||||||
cfg->type = listener_type;
|
cfg->type = listener_type;
|
||||||
cfg->port = port ? port : mainport;
|
cfg->port = port ? port : mainport;
|
||||||
tor_addr_copy(&cfg->addr, &addr);
|
tor_addr_copy(&cfg->addr, &addr);
|
||||||
@ -5759,14 +5762,21 @@ parse_port_config(smartlist_t *out,
|
|||||||
return 0;
|
return 0;
|
||||||
} /* end if (listenaddrs) */
|
} /* end if (listenaddrs) */
|
||||||
|
|
||||||
|
|
||||||
/* No ListenAddress lines. If there's no FooPort, then maybe make a default
|
/* No ListenAddress lines. If there's no FooPort, then maybe make a default
|
||||||
* one. */
|
* one. */
|
||||||
if (! ports) {
|
if (! ports) {
|
||||||
if (defaultport && out) {
|
if (defaultport && defaultaddr && out) {
|
||||||
port_cfg_t *cfg = port_cfg_new();
|
port_cfg_t *cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
|
||||||
cfg->type = listener_type;
|
cfg->type = listener_type;
|
||||||
cfg->port = defaultport;
|
if (is_unix_socket) {
|
||||||
tor_addr_parse(&cfg->addr, defaultaddr);
|
tor_addr_make_unspec(&cfg->addr);
|
||||||
|
memcpy(cfg->unix_addr, defaultaddr, strlen(defaultaddr) + 1);
|
||||||
|
cfg->is_unix_addr = 1;
|
||||||
|
} else {
|
||||||
|
cfg->port = defaultport;
|
||||||
|
tor_addr_parse(&cfg->addr, defaultaddr);
|
||||||
|
}
|
||||||
cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
|
cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
|
||||||
cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
|
cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
|
||||||
smartlist_add(out, cfg);
|
smartlist_add(out, cfg);
|
||||||
@ -5809,7 +5819,10 @@ parse_port_config(smartlist_t *out,
|
|||||||
|
|
||||||
/* Now parse the addr/port value */
|
/* Now parse the addr/port value */
|
||||||
addrport = smartlist_get(elts, 0);
|
addrport = smartlist_get(elts, 0);
|
||||||
if (!strcmp(addrport, "auto")) {
|
if (is_unix_socket) {
|
||||||
|
/* leave it as it is. */
|
||||||
|
port = 1;
|
||||||
|
} else if (!strcmp(addrport, "auto")) {
|
||||||
port = CFG_AUTO_PORT;
|
port = CFG_AUTO_PORT;
|
||||||
tor_addr_parse(&addr, defaultaddr);
|
tor_addr_parse(&addr, defaultaddr);
|
||||||
} else if (!strcasecmpend(addrport, ":auto")) {
|
} else if (!strcasecmpend(addrport, ":auto")) {
|
||||||
@ -5994,9 +6007,16 @@ parse_port_config(smartlist_t *out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (out && port) {
|
if (out && port) {
|
||||||
port_cfg_t *cfg = port_cfg_new();
|
size_t namelen = is_unix_socket ? strlen(addrport) : 0;
|
||||||
tor_addr_copy(&cfg->addr, &addr);
|
port_cfg_t *cfg = port_cfg_new(namelen);
|
||||||
cfg->port = port;
|
if (is_unix_socket) {
|
||||||
|
tor_addr_make_unspec(&cfg->addr);
|
||||||
|
memcpy(cfg->unix_addr, addrport, strlen(addrport) + 1);
|
||||||
|
cfg->is_unix_addr = 1;
|
||||||
|
} else {
|
||||||
|
tor_addr_copy(&cfg->addr, &addr);
|
||||||
|
cfg->port = port;
|
||||||
|
}
|
||||||
cfg->type = listener_type;
|
cfg->type = listener_type;
|
||||||
cfg->entry_cfg.isolation_flags = isolation;
|
cfg->entry_cfg.isolation_flags = isolation;
|
||||||
cfg->entry_cfg.session_group = sessiongroup;
|
cfg->entry_cfg.session_group = sessiongroup;
|
||||||
@ -6032,7 +6052,7 @@ parse_port_config(smartlist_t *out,
|
|||||||
warn_nonlocal_client_ports(out, portname, listener_type);
|
warn_nonlocal_client_ports(out, portname, listener_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_zero_port && got_nonzero_port) {
|
if (!is_unix_socket && got_zero_port && got_nonzero_port) {
|
||||||
log_warn(LD_CONFIG, "You specified a nonzero %sPort along with '%sPort 0' "
|
log_warn(LD_CONFIG, "You specified a nonzero %sPort along with '%sPort 0' "
|
||||||
"in the same configuration. Did you mean to disable %sPort or "
|
"in the same configuration. Did you mean to disable %sPort or "
|
||||||
"not?", portname, portname, portname);
|
"not?", portname, portname, portname);
|
||||||
@ -6046,94 +6066,6 @@ parse_port_config(smartlist_t *out,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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.
|
|
||||||
* 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, 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) {
|
|
||||||
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->entry_cfg.ipv4_traffic = 1;
|
|
||||||
port->entry_cfg.ipv6_traffic = 1;
|
|
||||||
port->entry_cfg.cache_ipv4_answers = 0;
|
|
||||||
port->entry_cfg.cache_ipv6_answers = 0;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the number of ports which are actually going to listen with type
|
/** Return the number of ports which are actually going to listen with type
|
||||||
* <b>listenertype</b>. Do not count no_listen ports. Do not count unix
|
* <b>listenertype</b>. Do not count no_listen ports. Do not count unix
|
||||||
* sockets. */
|
* sockets. */
|
||||||
@ -6223,15 +6155,17 @@ parse_ports(or_options_t *options, int validate_only,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_unix_socket_config(ports, NULL,
|
if (parse_port_config(ports, options->ControlSocket, NULL,
|
||||||
options->ControlSocket,
|
"ControlSocket",
|
||||||
CONN_TYPE_CONTROL_LISTENER) < 0) {
|
CONN_TYPE_CONTROL_LISTENER, NULL, 0,
|
||||||
|
control_port_flags | CL_PORT_IS_UNIXSOCKET) < 0) {
|
||||||
*msg = tor_strdup("Invalid ControlSocket configuration");
|
*msg = tor_strdup("Invalid ControlSocket configuration");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (parse_unix_socket_config(ports, NULL,
|
if (parse_port_config(ports, options->SocksSocket, NULL,
|
||||||
options->SocksSocket,
|
"SocksSocket",
|
||||||
CONN_TYPE_AP_LISTENER) < 0) {
|
CONN_TYPE_AP_LISTENER, NULL, 0,
|
||||||
|
CL_PORT_IS_UNIXSOCKET) < 0) {
|
||||||
*msg = tor_strdup("Invalid SocksSocket configuration");
|
*msg = tor_strdup("Invalid SocksSocket configuration");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user