|
@@ -308,6 +308,7 @@ static config_var_t option_vars_[] = {
|
|
|
V(Socks5ProxyUsername, STRING, NULL),
|
|
|
V(Socks5ProxyPassword, STRING, NULL),
|
|
|
V(KeepalivePeriod, INTERVAL, "5 minutes"),
|
|
|
+ V(KeepCapabilities, AUTOBOOL, "auto"),
|
|
|
VAR("Log", LINELIST, Logs, NULL),
|
|
|
V(LogMessageDomains, BOOL, "0"),
|
|
|
V(LogTimeGranularity, MSEC_INTERVAL, "1 second"),
|
|
@@ -567,7 +568,8 @@ static int parse_ports(or_options_t *options, int validate_only,
|
|
|
char **msg_out, int *n_ports_out,
|
|
|
int *world_writable_control_socket);
|
|
|
static int check_server_ports(const smartlist_t *ports,
|
|
|
- const or_options_t *options);
|
|
|
+ const or_options_t *options,
|
|
|
+ int *num_low_ports_out);
|
|
|
|
|
|
static int validate_data_directory(or_options_t *options);
|
|
|
static int write_configuration_file(const char *fname,
|
|
@@ -1045,6 +1047,9 @@ consider_adding_dir_servers(const or_options_t *options,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/* Helps determine flags to pass to switch_id. */
|
|
|
+static int have_low_ports = -1;
|
|
|
+
|
|
|
/** Fetch the active option list, and take actions based on it. All of the
|
|
|
* things we do should survive being done repeatedly. If present,
|
|
|
* <b>old_options</b> contains the previous value of the options.
|
|
@@ -1178,8 +1183,14 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
|
|
}
|
|
|
|
|
|
/* Setuid/setgid as appropriate */
|
|
|
+ tor_assert(have_low_ports != -1);
|
|
|
if (options->User) {
|
|
|
- if (switch_id(options->User) != 0) {
|
|
|
+ unsigned switch_id_flags = 0;
|
|
|
+ if (options->KeepCapabilities == 1 ||
|
|
|
+ (options->KeepCapabilities == -1 && have_low_ports)) {
|
|
|
+ switch_id_flags |= SWITCH_ID_KEEP_BINDLOW;
|
|
|
+ }
|
|
|
+ if (switch_id(options->User, switch_id_flags) != 0) {
|
|
|
/* No need to roll back, since you can't change the value. */
|
|
|
*msg = tor_strdup("Problem with User value. See logs for details.");
|
|
|
goto done;
|
|
@@ -3997,6 +4008,12 @@ options_transition_allowed(const or_options_t *old,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+ if (old->KeepCapabilities != new_val->KeepCapabilities) {
|
|
|
+ *msg = tor_strdup("While Tor is running, changing KeepCapabilities is "
|
|
|
+ "not allowed.");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
if (!opt_streq(old->SyslogIdentityTag, new_val->SyslogIdentityTag)) {
|
|
|
*msg = tor_strdup("While Tor is running, changing "
|
|
|
"SyslogIdentityTag is not allowed.");
|
|
@@ -6535,10 +6552,13 @@ parse_ports(or_options_t *options, int validate_only,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (check_server_ports(ports, options) < 0) {
|
|
|
+ int n_low_ports = 0;
|
|
|
+ if (check_server_ports(ports, options, &n_low_ports) < 0) {
|
|
|
*msg = tor_strdup("Misconfigured server ports");
|
|
|
goto err;
|
|
|
}
|
|
|
+ if (have_low_ports < 0)
|
|
|
+ have_low_ports = (n_low_ports > 0);
|
|
|
|
|
|
*n_ports_out = smartlist_len(ports);
|
|
|
|
|
@@ -6592,10 +6612,12 @@ parse_ports(or_options_t *options, int validate_only,
|
|
|
}
|
|
|
|
|
|
/** Given a list of <b>port_cfg_t</b> in <b>ports</b>, check them for internal
|
|
|
- * consistency and warn as appropriate. */
|
|
|
+ * consistency and warn as appropriate. Set *<b>n_low_port</b> to the number
|
|
|
+ * of sub-1024 ports we will be binding. */
|
|
|
static int
|
|
|
check_server_ports(const smartlist_t *ports,
|
|
|
- const or_options_t *options)
|
|
|
+ const or_options_t *options,
|
|
|
+ int *n_low_ports_out)
|
|
|
{
|
|
|
int n_orport_advertised = 0;
|
|
|
int n_orport_advertised_ipv4 = 0;
|
|
@@ -6658,16 +6680,24 @@ check_server_ports(const smartlist_t *ports,
|
|
|
r = -1;
|
|
|
}
|
|
|
|
|
|
- if (n_low_port && options->AccountingMax) {
|
|
|
+ if (n_low_port && options->AccountingMax &&
|
|
|
+ (!have_capability_support() || options->KeepCapabilities == 0)) {
|
|
|
+ const char *extra = "";
|
|
|
+ if (options->KeepCapabilities == 0 && have_capability_support())
|
|
|
+ extra = ", and you have disabled KeepCapabilities.";
|
|
|
log_warn(LD_CONFIG,
|
|
|
"You have set AccountingMax to use hibernation. You have also "
|
|
|
- "chosen a low DirPort or OrPort. This combination can make Tor stop "
|
|
|
+ "chosen a low DirPort or OrPort%s."
|
|
|
+ "This combination can make Tor stop "
|
|
|
"working when it tries to re-attach the port after a period of "
|
|
|
"hibernation. Please choose a different port or turn off "
|
|
|
"hibernation unless you know this combination will work on your "
|
|
|
- "platform.");
|
|
|
+ "platform.", extra);
|
|
|
}
|
|
|
|
|
|
+ if (n_low_ports_out)
|
|
|
+ *n_low_ports_out = n_low_port;
|
|
|
+
|
|
|
return r;
|
|
|
}
|
|
|
|