diff options
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 194 |
1 files changed, 153 insertions, 41 deletions
diff --git a/src/or/config.c b/src/or/config.c index b6d9d4eb3d..23edd3a503 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -55,6 +55,16 @@ #include "procmon.h" +#ifdef HAVE_SYSTEMD +# if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) +/* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse + * Coverity. Here's a kludge to unconfuse it. + */ +# define __INCLUDE_LEVEL__ 2 +# endif +#include <systemd/sd-daemon.h> +#endif + /* From main.c */ extern int quiet_level; @@ -65,7 +75,6 @@ static config_abbrev_t option_abbrevs_[] = { PLURAL(AuthDirBadExitCC), PLURAL(AuthDirInvalidCC), PLURAL(AuthDirRejectCC), - PLURAL(ExitNode), PLURAL(EntryNode), PLURAL(ExcludeNode), PLURAL(FirewallPort), @@ -191,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), @@ -229,6 +240,7 @@ static config_var_t option_vars_[] = { V(ExitPolicyRejectPrivate, BOOL, "1"), V(ExitPortStatistics, BOOL, "0"), V(ExtendAllowPrivateAddresses, BOOL, "0"), + V(ExitRelay, AUTOBOOL, "auto"), VPORT(ExtORPort, LINELIST, NULL), V(ExtORPortCookieAuthFile, STRING, NULL), V(ExtORPortCookieAuthFileGroupReadable, BOOL, "0"), @@ -427,7 +439,7 @@ static config_var_t option_vars_[] = { VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword, NULL), VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL), - V(MinUptimeHidServDirectoryV2, INTERVAL, "25 hours"), + V(MinUptimeHidServDirectoryV2, INTERVAL, "96 hours"), V(VoteOnHidServDirectoriesV2, BOOL, "1"), V(TestingServerDownloadSchedule, CSV_INTERVAL, "0, 0, 0, 60, 60, 120, " "300, 900, 2147483647"), @@ -448,6 +460,7 @@ static config_var_t option_vars_[] = { V(TestingCertMaxDownloadTries, UINT, "8"), V(TestingDirAuthVoteExit, ROUTERSET, NULL), V(TestingDirAuthVoteGuard, ROUTERSET, NULL), + V(TestingDirAuthVoteHSDir, ROUTERSET, NULL), VAR("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_, "0"), { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL } @@ -496,6 +509,7 @@ static const config_var_t testing_tor_network_defaults[] = { V(TestingEnableCellStatsEvent, BOOL, "1"), V(TestingEnableTbEmptyEvent, BOOL, "1"), VAR("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_, "1"), + V(RendPostPeriod, INTERVAL, "2 minutes"), { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL } }; @@ -1016,6 +1030,11 @@ options_act_reversible(const or_options_t *old_options, char **msg) start_daemon(); } +#ifdef HAVE_SYSTEMD + /* Our PID may have changed, inform supervisor */ + sd_notifyf(0, "MAINPID=%ld\n", (long int)getpid()); +#endif + #ifndef HAVE_SYS_UN_H if (options->ControlSocket || options->ControlSocketsGroupWritable) { *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported " @@ -1030,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. */ @@ -2492,6 +2525,7 @@ compute_publishserverdescriptor(or_options_t *options) /** Lowest allowable value for RendPostPeriod; if this is too low, hidden * services can overload the directory system. */ #define MIN_REND_POST_PERIOD (10*60) +#define MIN_REND_POST_PERIOD_TESTING (5) /** Higest allowable value for PredictedPortsRelevanceTime; if this is * too high, our selection of exits will decrease for an extended @@ -2616,11 +2650,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. " @@ -2911,6 +2940,7 @@ options_validate(or_options_t *old_options, or_options_t *options, options->MaxMemInQueues = compute_real_max_mem_in_queues(options->MaxMemInQueues_raw, server_mode(options)); + options->MaxMemInQueues_low_threshold = (options->MaxMemInQueues / 4) * 3; options->AllowInvalid_ = 0; @@ -2975,10 +3005,13 @@ options_validate(or_options_t *old_options, or_options_t *options, options->MinUptimeHidServDirectoryV2 = 0; } - if (options->RendPostPeriod < MIN_REND_POST_PERIOD) { + const int min_rendpostperiod = + options->TestingTorNetwork ? + MIN_REND_POST_PERIOD_TESTING : MIN_REND_POST_PERIOD; + if (options->RendPostPeriod < min_rendpostperiod) { log_warn(LD_CONFIG, "RendPostPeriod option is too short; " - "raising to %d seconds.", MIN_REND_POST_PERIOD); - options->RendPostPeriod = MIN_REND_POST_PERIOD; + "raising to %d seconds.", min_rendpostperiod); + options->RendPostPeriod = min_rendpostperiod;; } if (options->RendPostPeriod > MAX_DIR_PERIOD) { @@ -3529,15 +3562,6 @@ options_validate(or_options_t *old_options, or_options_t *options, AF_INET6, 1, msg)<0) return -1; - if (options->AutomapHostsSuffixes) { - SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf, - { - size_t len = strlen(suf); - if (len && suf[len-1] == '.') - suf[len-1] = '\0'; - }); - } - if (options->TestingTorNetwork && !(options->DirAuthorities || (options->AlternateDirAuthority && @@ -3932,6 +3956,7 @@ options_transition_affects_descriptor(const or_options_t *old_options, !opt_streq(old_options->Nickname,new_options->Nickname) || !opt_streq(old_options->Address,new_options->Address) || !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) || + old_options->ExitRelay != new_options->ExitRelay || old_options->ExitPolicyRejectPrivate != new_options->ExitPolicyRejectPrivate || old_options->IPv6Exit != new_options->IPv6Exit || @@ -4147,17 +4172,24 @@ find_torrc_filename(config_line_t *cmd_arg, if (*using_default_fname) { /* didn't find one, try CONFDIR */ const char *dflt = get_default_conf_file(defaults_file); - if (dflt && file_status(dflt) == FN_FILE) { + file_status_t st = file_status(dflt); + if (dflt && (st == FN_FILE || st == FN_EMPTY)) { fname = tor_strdup(dflt); } else { #ifndef _WIN32 char *fn = NULL; - if (!defaults_file) + if (!defaults_file) { fn = expand_filename("~/.torrc"); - if (fn && file_status(fn) == FN_FILE) { - fname = fn; + } + if (fn) { + file_status_t hmst = file_status(fn); + if (hmst == FN_FILE || hmst == FN_EMPTY) { + fname = fn; + } else { + tor_free(fn); + fname = tor_strdup(dflt); + } } else { - tor_free(fn); fname = tor_strdup(dflt); } #else @@ -4184,16 +4216,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); + if (*fname_var == NULL) { + fname = find_torrc_filename(cmd_arg, defaults_file, + &using_default_torrc, &ignore_missing_torrc); + tor_assert(fname); + tor_free(*fname_var); + *fname_var = fname; + } else { + fname = *fname_var; + } log_debug(LD_CONFIG, "Opening config file \"%s\"", fname); - tor_free(*fname_var); - *fname_var = fname; - /* Open config file */ - if (file_status(fname) != FN_FILE || + file_status_t st = file_status(fname); + if (!(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) @@ -6012,22 +6048,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->entry_cfg.ipv4_traffic = 1; + port->entry_cfg.ipv6_traffic = 1; + port->entry_cfg.cache_ipv4_answers = 1; + port->entry_cfg.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; @@ -6121,12 +6222,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, @@ -6170,6 +6278,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 = @@ -6452,7 +6562,9 @@ write_configuration_file(const char *fname, const or_options_t *options) tor_assert(fname); switch (file_status(fname)) { + /* create backups of old config files, even if they're empty */ case FN_FILE: + case FN_EMPTY: old_val = read_file_to_str(fname, 0, NULL); if (!old_val || strcmpstart(old_val, GENERATED_FILE_PREFIX)) { rename_old = 1; |