aboutsummaryrefslogtreecommitdiff
path: root/src/or/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/config.c')
-rw-r--r--src/or/config.c282
1 files changed, 107 insertions, 175 deletions
diff --git a/src/or/config.c b/src/or/config.c
index 5b8560b9e4..91fbe970d9 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -281,6 +281,7 @@ static config_var_t option_vars_[] = {
VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
+ VAR("HiddenServiceAllowUnknownPorts",LINELIST_S, RendConfigLines, NULL),
V(HiddenServiceStatistics, BOOL, "0"),
V(HidServAuth, LINELIST, NULL),
V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"),
@@ -2650,11 +2651,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
REJECT("Failed to resolve/guess local address. See logs for details.");
}
-#ifndef _WIN32
- if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
- REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
-#endif
-
if (server_mode(options) && options->RendConfigLines)
log_warn(LD_CONFIG,
"Tor is currently configured as a relay and a hidden service. "
@@ -4050,7 +4046,10 @@ get_windows_conf_root(void)
static const char *
get_default_conf_file(int defaults_file)
{
-#ifdef _WIN32
+#ifdef DISABLE_SYSTEM_TORRC
+ (void) defaults_file;
+ return NULL;
+#elif defined(_WIN32)
if (defaults_file) {
static char defaults_path[MAX_PATH+1];
tor_snprintf(defaults_path, MAX_PATH, "%s\\torrc-defaults",
@@ -4188,17 +4187,17 @@ find_torrc_filename(config_line_t *cmd_arg,
}
if (fn) {
file_status_t hmst = file_status(fn);
- if (hmst == FN_FILE || hmst == FN_EMPTY) {
+ if (hmst == FN_FILE || hmst == FN_EMPTY || dflt == NULL) {
fname = fn;
} else {
tor_free(fn);
fname = tor_strdup(dflt);
}
} else {
- fname = tor_strdup(dflt);
+ fname = dflt ? tor_strdup(dflt) : NULL;
}
#else
- fname = tor_strdup(dflt);
+ fname = dflt ? tor_strdup(dflt) : NULL;
#endif
}
}
@@ -4221,17 +4220,20 @@ load_torrc_from_disk(config_line_t *cmd_arg, int defaults_file)
int ignore_missing_torrc = 0;
char **fname_var = defaults_file ? &torrc_defaults_fname : &torrc_fname;
- fname = find_torrc_filename(cmd_arg, defaults_file,
- &using_default_torrc, &ignore_missing_torrc);
- tor_assert(fname);
- log_debug(LD_CONFIG, "Opening config file \"%s\"", fname);
-
- tor_free(*fname_var);
- *fname_var = fname;
+ if (*fname_var == NULL) {
+ fname = find_torrc_filename(cmd_arg, defaults_file,
+ &using_default_torrc, &ignore_missing_torrc);
+ tor_free(*fname_var);
+ *fname_var = fname;
+ } else {
+ fname = *fname_var;
+ }
+ log_debug(LD_CONFIG, "Opening config file \"%s\"", fname?fname:"<NULL>");
/* Open config file */
- file_status_t st = file_status(fname);
- if (!(st == FN_FILE || st == FN_EMPTY) ||
+ file_status_t st = fname ? file_status(fname) : FN_EMPTY;
+ if (fname == NULL ||
+ !(st == FN_FILE || st == FN_EMPTY) ||
!(cf = read_file_to_str(fname,0,NULL))) {
if (using_default_torrc == 1 || ignore_missing_torrc) {
if (!defaults_file)
@@ -4520,7 +4522,7 @@ options_init_from_string(const char *cf_defaults, const char *cf,
return err;
}
-/** Return the location for our configuration file.
+/** Return the location for our configuration file. May return NULL.
*/
const char *
get_torrc_fname(int defaults_fname)
@@ -5374,14 +5376,6 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
fingerprint, (int)strlen(fingerprint));
goto err;
}
- if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
- /* a known bad fingerprint. refuse to use it. We can remove this
- * clause once Tor 0.1.2.17 is obsolete. */
- log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
- "torrc file (%s), or reinstall Tor and use the default torrc.",
- get_torrc_fname(0));
- goto err;
- }
if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
log_warn(LD_CONFIG, "Unable to decode DirAuthority key digest.");
goto err;
@@ -5511,12 +5505,13 @@ parse_dir_fallback_line(const char *line,
/** Allocate and return a new port_cfg_t with reasonable defaults. */
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));
- cfg->ipv4_traffic = 1;
- cfg->cache_ipv4_answers = 1;
- cfg->prefer_ipv6_virtaddr = 1;
+ 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.cache_ipv4_answers = 1;
+ cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
return cfg;
}
@@ -5623,6 +5618,7 @@ warn_nonlocal_controller_ports(smartlist_t *ports, unsigned forbid)
#define CL_PORT_SERVER_OPTIONS (1u<<3)
#define CL_PORT_FORBID_NONLOCAL (1u<<4)
#define CL_PORT_TAKES_HOSTNAMES (1u<<5)
+#define CL_PORT_IS_UNIXSOCKET (1u<<6)
/**
* Parse port configuration for a single port type.
@@ -5670,7 +5666,7 @@ parse_port_config(smartlist_t *out,
int listener_type,
const char *defaultaddr,
int defaultport,
- unsigned flags)
+ const unsigned flags)
{
smartlist_t *elts;
int retval = -1;
@@ -5683,6 +5679,7 @@ parse_port_config(smartlist_t *out,
const unsigned allow_spurious_listenaddr =
flags & CL_PORT_ALLOW_EXTRA_LISTENADDR;
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;
/* FooListenAddress is deprecated; let's make it work like it used to work,
@@ -5719,14 +5716,14 @@ parse_port_config(smartlist_t *out,
if (use_server_options && out) {
/* 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->port = mainport;
tor_addr_make_unspec(&cfg->addr); /* Server ports default to 0.0.0.0 */
- cfg->no_listen = 1;
- cfg->bind_ipv4_only = 1;
- cfg->ipv4_traffic = 1;
- cfg->prefer_ipv6_virtaddr = 1;
+ cfg->server_cfg.no_listen = 1;
+ cfg->server_cfg.bind_ipv4_only = 1;
+ cfg->entry_cfg.ipv4_traffic = 1;
+ cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
smartlist_add(out, cfg);
}
@@ -5739,13 +5736,13 @@ parse_port_config(smartlist_t *out,
return -1;
}
if (out) {
- port_cfg_t *cfg = port_cfg_new();
+ port_cfg_t *cfg = port_cfg_new(0);
cfg->type = listener_type;
cfg->port = port ? port : mainport;
tor_addr_copy(&cfg->addr, &addr);
- cfg->session_group = SESSION_GROUP_UNSET;
- cfg->isolation_flags = ISO_DEFAULT;
- cfg->no_advertise = 1;
+ cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
+ cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
+ cfg->server_cfg.no_advertise = 1;
smartlist_add(out, cfg);
}
}
@@ -5761,16 +5758,23 @@ parse_port_config(smartlist_t *out,
return 0;
} /* end if (listenaddrs) */
+
/* No ListenAddress lines. If there's no FooPort, then maybe make a default
* one. */
if (! ports) {
- if (defaultport && out) {
- port_cfg_t *cfg = port_cfg_new();
+ if (defaultport && defaultaddr && out) {
+ port_cfg_t *cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
cfg->type = listener_type;
- cfg->port = defaultport;
- tor_addr_parse(&cfg->addr, defaultaddr);
- cfg->session_group = SESSION_GROUP_UNSET;
- cfg->isolation_flags = ISO_DEFAULT;
+ if (is_unix_socket) {
+ 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.isolation_flags = ISO_DEFAULT;
smartlist_add(out, cfg);
}
return 0;
@@ -5811,7 +5815,13 @@ parse_port_config(smartlist_t *out,
/* Now parse the addr/port value */
addrport = smartlist_get(elts, 0);
- if (!strcmp(addrport, "auto")) {
+ if (is_unix_socket) {
+ /* leave it as it is. */
+ if (!strcmp(addrport, "0"))
+ port = 0;
+ else
+ port = 1;
+ } else if (!strcmp(addrport, "auto")) {
port = CFG_AUTO_PORT;
tor_addr_parse(&addr, defaultaddr);
} else if (!strcasecmpend(addrport, ":auto")) {
@@ -5996,28 +6006,35 @@ parse_port_config(smartlist_t *out,
}
if (out && port) {
- port_cfg_t *cfg = port_cfg_new();
- tor_addr_copy(&cfg->addr, &addr);
- cfg->port = port;
+ size_t namelen = is_unix_socket ? strlen(addrport) : 0;
+ port_cfg_t *cfg = port_cfg_new(namelen);
+ 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->isolation_flags = isolation;
- cfg->session_group = sessiongroup;
- cfg->no_advertise = no_advertise;
- cfg->no_listen = no_listen;
- cfg->all_addrs = all_addrs;
- cfg->bind_ipv4_only = bind_ipv4_only;
- cfg->bind_ipv6_only = bind_ipv6_only;
- cfg->ipv4_traffic = ipv4_traffic;
- cfg->ipv6_traffic = ipv6_traffic;
- cfg->prefer_ipv6 = prefer_ipv6;
- cfg->cache_ipv4_answers = cache_ipv4;
- cfg->cache_ipv6_answers = cache_ipv6;
- cfg->use_cached_ipv4_answers = use_cached_ipv4;
- cfg->use_cached_ipv6_answers = use_cached_ipv6;
- cfg->prefer_ipv6_virtaddr = prefer_ipv6_automap;
- cfg->socks_prefer_no_auth = prefer_no_auth;
+ cfg->entry_cfg.isolation_flags = isolation;
+ cfg->entry_cfg.session_group = sessiongroup;
+ cfg->server_cfg.no_advertise = no_advertise;
+ cfg->server_cfg.no_listen = no_listen;
+ cfg->server_cfg.all_addrs = all_addrs;
+ cfg->server_cfg.bind_ipv4_only = bind_ipv4_only;
+ cfg->server_cfg.bind_ipv6_only = bind_ipv6_only;
+ cfg->entry_cfg.ipv4_traffic = ipv4_traffic;
+ cfg->entry_cfg.ipv6_traffic = ipv6_traffic;
+ cfg->entry_cfg.prefer_ipv6 = prefer_ipv6;
+ cfg->entry_cfg.cache_ipv4_answers = cache_ipv4;
+ cfg->entry_cfg.cache_ipv6_answers = cache_ipv6;
+ cfg->entry_cfg.use_cached_ipv4_answers = use_cached_ipv4;
+ cfg->entry_cfg.use_cached_ipv6_answers = use_cached_ipv6;
+ cfg->entry_cfg.prefer_ipv6_virtaddr = prefer_ipv6_automap;
+ cfg->entry_cfg.socks_prefer_no_auth = prefer_no_auth;
if (! (isolation & ISO_SOCKSAUTH))
- cfg->socks_prefer_no_auth = 1;
+ cfg->entry_cfg.socks_prefer_no_auth = 1;
smartlist_add(out, cfg);
}
@@ -6048,94 +6065,6 @@ parse_port_config(smartlist_t *out,
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->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;
-}
-
/** 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
* sockets. */
@@ -6144,7 +6073,7 @@ count_real_listeners(const smartlist_t *ports, int listenertype)
{
int n = 0;
SMARTLIST_FOREACH_BEGIN(ports, port_cfg_t *, port) {
- if (port->no_listen || port->is_unix_addr)
+ if (port->server_cfg.no_listen || port->is_unix_addr)
continue;
if (port->type != listenertype)
continue;
@@ -6225,15 +6154,17 @@ parse_ports(or_options_t *options, int validate_only,
goto err;
}
- if (parse_unix_socket_config(ports, NULL,
- options->ControlSocket,
- CONN_TYPE_CONTROL_LISTENER) < 0) {
+ if (parse_port_config(ports, options->ControlSocket, NULL,
+ "ControlSocket",
+ CONN_TYPE_CONTROL_LISTENER, NULL, 0,
+ control_port_flags | CL_PORT_IS_UNIXSOCKET) < 0) {
*msg = tor_strdup("Invalid ControlSocket configuration");
goto err;
}
- if (parse_unix_socket_config(ports, NULL,
- options->SocksSocket,
- CONN_TYPE_AP_LISTENER) < 0) {
+ if (parse_port_config(ports, options->SocksSocket, NULL,
+ "SocksSocket",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_IS_UNIXSOCKET) < 0) {
*msg = tor_strdup("Invalid SocksSocket configuration");
goto err;
}
@@ -6329,25 +6260,25 @@ check_server_ports(const smartlist_t *ports,
SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
if (port->type == CONN_TYPE_DIR_LISTENER) {
- if (! port->no_advertise)
+ if (! port->server_cfg.no_advertise)
++n_dirport_advertised;
- if (! port->no_listen)
+ if (! port->server_cfg.no_listen)
++n_dirport_listeners;
} else if (port->type == CONN_TYPE_OR_LISTENER) {
- if (! port->no_advertise) {
+ if (! port->server_cfg.no_advertise) {
++n_orport_advertised;
if (tor_addr_family(&port->addr) == AF_INET ||
(tor_addr_family(&port->addr) == AF_UNSPEC &&
- !port->bind_ipv6_only))
+ !port->server_cfg.bind_ipv6_only))
++n_orport_advertised_ipv4;
}
- if (! port->no_listen)
+ if (! port->server_cfg.no_listen)
++n_orport_listeners;
} else {
continue;
}
#ifndef _WIN32
- if (!port->no_listen && port->port < 1024)
+ if (!port->server_cfg.no_listen && port->port < 1024)
++n_low_port;
#endif
} SMARTLIST_FOREACH_END(port);
@@ -6425,7 +6356,7 @@ get_first_listener_addrport_string(int listener_type)
return NULL;
SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
- if (cfg->no_listen)
+ if (cfg->server_cfg.no_listen)
continue;
if (cfg->type == listener_type &&
@@ -6472,12 +6403,12 @@ get_first_advertised_port_by_type_af(int listener_type, int address_family)
return 0;
SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
if (cfg->type == listener_type &&
- !cfg->no_advertise &&
+ !cfg->server_cfg.no_advertise &&
(tor_addr_family(&cfg->addr) == address_family ||
tor_addr_family(&cfg->addr) == AF_UNSPEC)) {
if (tor_addr_family(&cfg->addr) != AF_UNSPEC ||
- (address_family == AF_INET && !cfg->bind_ipv6_only) ||
- (address_family == AF_INET6 && !cfg->bind_ipv4_only)) {
+ (address_family == AF_INET && !cfg->server_cfg.bind_ipv6_only) ||
+ (address_family == AF_INET6 && !cfg->server_cfg.bind_ipv4_only)) {
return cfg->port;
}
}
@@ -6561,7 +6492,8 @@ write_configuration_file(const char *fname, const or_options_t *options)
char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
int rename_old = 0, r;
- tor_assert(fname);
+ if (!fname)
+ return -1;
switch (file_status(fname)) {
/* create backups of old config files, even if they're empty */