mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
MyFamily config string is now a list. #4998
This commit is contained in:
parent
b081a7ed21
commit
fa04fe1674
@ -1813,14 +1813,15 @@ is non-zero):
|
|||||||
If we have more onionskins queued for processing than we can process in
|
If we have more onionskins queued for processing than we can process in
|
||||||
this amount of time, reject new ones. (Default: 1750 msec)
|
this amount of time, reject new ones. (Default: 1750 msec)
|
||||||
|
|
||||||
[[MyFamily]] **MyFamily** __node__,__node__,__...__::
|
[[MyFamily]] **MyFamily** __node__::
|
||||||
Declare that this Tor server is controlled or administered by a group or
|
Declare that this Tor server is controlled or administered by a group or
|
||||||
organization identical or similar to that of the other servers, defined by
|
organization identical or similar to that of the other servers, defined by
|
||||||
their identity fingerprints. When two servers both declare
|
their identity fingerprints. This option can be repeated many times, for
|
||||||
that they are in the same \'family', Tor clients will not use them in the
|
multiple families. When two servers both declare that they are in the
|
||||||
same circuit. (Each server only needs to list the other servers in its
|
same \'family', Tor clients will not use them in the same circuit. (Each
|
||||||
family; it doesn't need to list itself, but it won't hurt.) Do not list
|
server only needs to list the other servers in its family; it doesn't need to
|
||||||
any bridge relay as it would compromise its concealment. +
|
list itself, but it won't hurt.) Do not list any bridge relay as it would
|
||||||
|
compromise its concealment. +
|
||||||
+
|
+
|
||||||
When listing a node, it's better to list it by fingerprint than by
|
When listing a node, it's better to list it by fingerprint than by
|
||||||
nickname: fingerprints are more reliable.
|
nickname: fingerprints are more reliable.
|
||||||
|
@ -395,7 +395,7 @@ static config_var_t option_vars_[] = {
|
|||||||
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
|
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
|
||||||
V(MaxUnparseableDescSizeToLog, MEMUNIT, "10 MB"),
|
V(MaxUnparseableDescSizeToLog, MEMUNIT, "10 MB"),
|
||||||
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
|
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
|
||||||
V(MyFamily, STRING, NULL),
|
V(MyFamily, LINELIST, NULL),
|
||||||
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
|
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
|
||||||
OBSOLETE("NamingAuthoritativeDirectory"),
|
OBSOLETE("NamingAuthoritativeDirectory"),
|
||||||
V(NATDListenAddress, LINELIST, NULL),
|
V(NATDListenAddress, LINELIST, NULL),
|
||||||
@ -707,7 +707,8 @@ static int options_transition_affects_workers(
|
|||||||
const or_options_t *old_options, const or_options_t *new_options);
|
const or_options_t *old_options, const or_options_t *new_options);
|
||||||
static int options_transition_affects_descriptor(
|
static int options_transition_affects_descriptor(
|
||||||
const or_options_t *old_options, const or_options_t *new_options);
|
const or_options_t *old_options, const or_options_t *new_options);
|
||||||
static int check_nickname_list(char **lst, const char *name, char **msg);
|
static int normalize_nickname_list(config_line_t **lst, const char *name,
|
||||||
|
char **msg);
|
||||||
static char *get_bindaddr_from_transport_listen_line(const char *line,
|
static char *get_bindaddr_from_transport_listen_line(const char *line,
|
||||||
const char *transport);
|
const char *transport);
|
||||||
static int parse_ports(or_options_t *options, int validate_only,
|
static int parse_ports(or_options_t *options, int validate_only,
|
||||||
@ -3885,7 +3886,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
"You should also make sure you aren't listing this bridge's "
|
"You should also make sure you aren't listing this bridge's "
|
||||||
"fingerprint in any other MyFamily.");
|
"fingerprint in any other MyFamily.");
|
||||||
}
|
}
|
||||||
if (check_nickname_list(&options->MyFamily, "MyFamily", msg))
|
if (normalize_nickname_list(&options->MyFamily, "MyFamily", msg))
|
||||||
return -1;
|
return -1;
|
||||||
for (cl = options->NodeFamilies; cl; cl = cl->next) {
|
for (cl = options->NodeFamilies; cl; cl = cl->next) {
|
||||||
routerset_t *rs = routerset_new();
|
routerset_t *rs = routerset_new();
|
||||||
@ -4593,7 +4594,7 @@ options_transition_affects_descriptor(const or_options_t *old_options,
|
|||||||
get_effective_bwburst(old_options) !=
|
get_effective_bwburst(old_options) !=
|
||||||
get_effective_bwburst(new_options) ||
|
get_effective_bwburst(new_options) ||
|
||||||
!opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
|
!opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
|
||||||
!opt_streq(old_options->MyFamily, new_options->MyFamily) ||
|
!config_lines_eq(old_options->MyFamily, new_options->MyFamily) ||
|
||||||
!opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
|
!opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
|
||||||
old_options->AccountingMax != new_options->AccountingMax ||
|
old_options->AccountingMax != new_options->AccountingMax ||
|
||||||
old_options->AccountingRule != new_options->AccountingRule ||
|
old_options->AccountingRule != new_options->AccountingRule ||
|
||||||
@ -4689,27 +4690,33 @@ get_default_conf_file(int defaults_file)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Verify whether lst is a string containing valid-looking comma-separated
|
/** Verify whether lst is a list of strings containing valid-looking
|
||||||
* nicknames, or NULL. Will normalise <b>lst</b> to prefix '$' to any nickname
|
* comma-separated nicknames, or NULL. Will normalise <b>lst</b> to prefix '$'
|
||||||
* or fingerprint that needs it. Return 0 on success.
|
* to any nickname or fingerprint that needs it. Also splits comma-separated
|
||||||
|
* list elements into multiple elements. Return 0 on success.
|
||||||
* Warn and return -1 on failure.
|
* Warn and return -1 on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_nickname_list(char **lst, const char *name, char **msg)
|
normalize_nickname_list(config_line_t **lst, const char *name, char **msg)
|
||||||
{
|
{
|
||||||
int r = 0;
|
|
||||||
smartlist_t *sl;
|
|
||||||
int changes = 0;
|
|
||||||
|
|
||||||
if (!*lst)
|
if (!*lst)
|
||||||
return 0;
|
return 0;
|
||||||
sl = smartlist_new();
|
|
||||||
|
|
||||||
smartlist_split_string(sl, *lst, ",",
|
config_line_t *new_nicknames = NULL;
|
||||||
|
config_line_t *new_nicknames_last = NULL;
|
||||||
|
config_line_t *cl;
|
||||||
|
for (cl = *lst; cl; cl = cl->next) {
|
||||||
|
char *line = cl->value;
|
||||||
|
if (!line)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int valid_line = 1;
|
||||||
|
smartlist_t *sl = smartlist_new();
|
||||||
|
smartlist_split_string(sl, line, ",",
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
|
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(sl, char *, s)
|
SMARTLIST_FOREACH_BEGIN(sl, char *, s)
|
||||||
{
|
{
|
||||||
|
char *normalized = NULL;
|
||||||
if (!is_legal_nickname_or_hexdigest(s)) {
|
if (!is_legal_nickname_or_hexdigest(s)) {
|
||||||
// check if first char is dollar
|
// check if first char is dollar
|
||||||
if (s[0] != '$') {
|
if (s[0] != '$') {
|
||||||
@ -4718,36 +4725,53 @@ check_nickname_list(char **lst, const char *name, char **msg)
|
|||||||
tor_asprintf(&prepended, "$%s", s);
|
tor_asprintf(&prepended, "$%s", s);
|
||||||
|
|
||||||
if (is_legal_nickname_or_hexdigest(prepended)) {
|
if (is_legal_nickname_or_hexdigest(prepended)) {
|
||||||
// The nickname is valid when it's prepended, swap the current
|
// The nickname is valid when it's prepended, set it as the
|
||||||
// version with a prepended one
|
// normalized version
|
||||||
tor_free(s);
|
normalized = prepended;
|
||||||
SMARTLIST_REPLACE_CURRENT(sl, s, prepended);
|
} else {
|
||||||
changes = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Still not valid, free and fallback to error message
|
// Still not valid, free and fallback to error message
|
||||||
tor_free(prepended);
|
tor_free(prepended);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!normalized) {
|
||||||
tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
|
tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
|
||||||
r = -1;
|
valid_line = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
normalized = tor_strdup(s);
|
||||||
}
|
}
|
||||||
SMARTLIST_FOREACH_END(s);
|
|
||||||
|
|
||||||
// Replace the caller's nickname list with a fixed one
|
config_line_t *next = tor_malloc_zero(sizeof(*next));
|
||||||
if (changes && r == 0) {
|
next->key = tor_strdup(cl->key);
|
||||||
char *newNicknames = smartlist_join_strings(sl, ", ", 0, NULL);
|
next->value = normalized;
|
||||||
tor_free(*lst);
|
next->next = NULL;
|
||||||
*lst = newNicknames;
|
|
||||||
|
if (!new_nicknames) {
|
||||||
|
new_nicknames = next;
|
||||||
|
new_nicknames_last = next;
|
||||||
|
} else {
|
||||||
|
new_nicknames_last->next = next;
|
||||||
|
new_nicknames_last = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} SMARTLIST_FOREACH_END(s);
|
||||||
|
|
||||||
SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
|
SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
|
|
||||||
return r;
|
if (!valid_line) {
|
||||||
|
config_free_lines(new_nicknames);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the caller's nickname list with the normalized one
|
||||||
|
config_free_lines(*lst);
|
||||||
|
*lst = new_nicknames;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Learn config file name from command line arguments, or use the default.
|
/** Learn config file name from command line arguments, or use the default.
|
||||||
|
@ -3951,7 +3951,7 @@ typedef struct {
|
|||||||
/** If set, use these bridge authorities and not the default one. */
|
/** If set, use these bridge authorities and not the default one. */
|
||||||
config_line_t *AlternateBridgeAuthority;
|
config_line_t *AlternateBridgeAuthority;
|
||||||
|
|
||||||
char *MyFamily; /**< Declared family for this OR. */
|
config_line_t *MyFamily; /**< Declared family for this OR. */
|
||||||
config_line_t *NodeFamilies; /**< List of config lines for
|
config_line_t *NodeFamilies; /**< List of config lines for
|
||||||
* node families */
|
* node families */
|
||||||
smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */
|
smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */
|
||||||
|
@ -2278,14 +2278,12 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options->MyFamily && ! options->BridgeRelay) {
|
if (options->MyFamily && ! options->BridgeRelay) {
|
||||||
smartlist_t *family;
|
|
||||||
if (!warned_nonexistent_family)
|
if (!warned_nonexistent_family)
|
||||||
warned_nonexistent_family = smartlist_new();
|
warned_nonexistent_family = smartlist_new();
|
||||||
family = smartlist_new();
|
|
||||||
ri->declared_family = smartlist_new();
|
ri->declared_family = smartlist_new();
|
||||||
smartlist_split_string(family, options->MyFamily, ",",
|
config_line_t *family;
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
|
for (family = options->MyFamily; family; family = family->next) {
|
||||||
SMARTLIST_FOREACH_BEGIN(family, char *, name) {
|
char *name = family->value;
|
||||||
const node_t *member;
|
const node_t *member;
|
||||||
if (!strcasecmp(name, options->Nickname))
|
if (!strcasecmp(name, options->Nickname))
|
||||||
goto skip; /* Don't list ourself, that's redundant */
|
goto skip; /* Don't list ourself, that's redundant */
|
||||||
@ -2324,13 +2322,11 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
|
|||||||
}
|
}
|
||||||
skip:
|
skip:
|
||||||
tor_free(name);
|
tor_free(name);
|
||||||
} SMARTLIST_FOREACH_END(name);
|
}
|
||||||
|
|
||||||
/* remove duplicates from the list */
|
/* remove duplicates from the list */
|
||||||
smartlist_sort_strings(ri->declared_family);
|
smartlist_sort_strings(ri->declared_family);
|
||||||
smartlist_uniq_strings(ri->declared_family);
|
smartlist_uniq_strings(ri->declared_family);
|
||||||
|
|
||||||
smartlist_free(family);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now generate the extrainfo. */
|
/* Now generate the extrainfo. */
|
||||||
|
@ -854,9 +854,23 @@ static void
|
|||||||
test_config_fix_my_family(void *arg)
|
test_config_fix_my_family(void *arg)
|
||||||
{
|
{
|
||||||
char *err = NULL;
|
char *err = NULL;
|
||||||
const char *family = "$1111111111111111111111111111111111111111, "
|
config_line_t *family = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
family->key = tor_strdup("MyFamily");
|
||||||
|
family->value = tor_strdup("$1111111111111111111111111111111111111111, "
|
||||||
"1111111111111111111111111111111111111112, "
|
"1111111111111111111111111111111111111112, "
|
||||||
"$1111111111111111111111111111111111111113";
|
"$1111111111111111111111111111111111111113");
|
||||||
|
|
||||||
|
config_line_t *family2 = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
family2->key = tor_strdup("MyFamily");
|
||||||
|
family2->value = tor_strdup("1111111111111111111111111111111111111114");
|
||||||
|
|
||||||
|
config_line_t *family3 = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
family3->key = tor_strdup("MyFamily");
|
||||||
|
family3->value = tor_strdup("$1111111111111111111111111111111111111115");
|
||||||
|
|
||||||
|
family->next = family2;
|
||||||
|
family2->next = family3;
|
||||||
|
family3->next = NULL;
|
||||||
|
|
||||||
or_options_t* options = options_new();
|
or_options_t* options = options_new();
|
||||||
or_options_t* defaults = options_new();
|
or_options_t* defaults = options_new();
|
||||||
@ -864,7 +878,7 @@ test_config_fix_my_family(void *arg)
|
|||||||
|
|
||||||
options_init(options);
|
options_init(options);
|
||||||
options_init(defaults);
|
options_init(defaults);
|
||||||
options->MyFamily = tor_strdup(family);
|
options->MyFamily = family;
|
||||||
|
|
||||||
options_validate(NULL, options, defaults, 0, &err) ;
|
options_validate(NULL, options, defaults, 0, &err) ;
|
||||||
|
|
||||||
@ -872,10 +886,18 @@ test_config_fix_my_family(void *arg)
|
|||||||
TT_FAIL(("options_validate failed: %s", err));
|
TT_FAIL(("options_validate failed: %s", err));
|
||||||
}
|
}
|
||||||
|
|
||||||
tt_str_op(options->MyFamily,OP_EQ,
|
const char *valid[] = { "$1111111111111111111111111111111111111111",
|
||||||
"$1111111111111111111111111111111111111111, "
|
"$1111111111111111111111111111111111111112",
|
||||||
"$1111111111111111111111111111111111111112, "
|
"$1111111111111111111111111111111111111113",
|
||||||
"$1111111111111111111111111111111111111113");
|
"$1111111111111111111111111111111111111114",
|
||||||
|
"$1111111111111111111111111111111111111115" };
|
||||||
|
int ret_size = 0;
|
||||||
|
config_line_t *ret;
|
||||||
|
for (ret = options->MyFamily; ret && ret_size < 5; ret = ret->next) {
|
||||||
|
tt_str_op(ret->value, OP_EQ, valid[ret_size]);
|
||||||
|
ret_size++;
|
||||||
|
}
|
||||||
|
tt_int_op(ret_size, OP_EQ, 5);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user