diff options
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 110 |
1 files changed, 100 insertions, 10 deletions
diff --git a/src/or/config.c b/src/or/config.c index beab4bf3a9..3b82c1e064 100644 --- a/src/or/config.c +++ b/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 = |