diff options
-rw-r--r-- | changes/bug14917 | 5 | ||||
-rw-r--r-- | src/or/config.c | 14 | ||||
-rw-r--r-- | src/or/routerset.c | 11 | ||||
-rw-r--r-- | src/or/routerset.h | 1 |
4 files changed, 31 insertions, 0 deletions
diff --git a/changes/bug14917 b/changes/bug14917 new file mode 100644 index 0000000000..92a985ca7b --- /dev/null +++ b/changes/bug14917 @@ -0,0 +1,5 @@ + o Major bugfix + - For an hidden service, it is now prohibited to use one single + EntryNodes to avoid a very easy guard discovery attack. For more + details, see the ticket description here: + https://trac.torproject.org/projects/tor/ticket/14917. Fixes #14917. diff --git a/src/or/config.c b/src/or/config.c index cb0abab613..02b3477eaf 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -3173,6 +3173,20 @@ options_validate(or_options_t *old_options, or_options_t *options, "http://freehaven.net/anonbib/#hs-attack06 for details."); } + if (routerset_is_list(options->EntryNodes) && + (routerset_len(options->EntryNodes) == 1) && + (options->RendConfigLines != NULL)) { + tor_asprintf(msg, + "You have one single EntryNodes and at least one hidden service " + "configured. This is bad because it's very easy to locate your " + "entry guard which can then lead to the deanonymization of your " + "hidden service -- for more details, see " + "https://trac.torproject.org/projects/tor/ticket/14917. " + "For this reason, the use of one EntryNodes with an hidden " + "service is prohibited until a better solution is found."); + return -1; + } + if (!options->LearnCircuitBuildTimeout && options->CircuitBuildTimeout && options->CircuitBuildTimeout < RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT) { log_warn(LD_CONFIG, diff --git a/src/or/routerset.c b/src/or/routerset.c index 99de11ed5e..9fe5dffdeb 100644 --- a/src/or/routerset.c +++ b/src/or/routerset.c @@ -162,6 +162,17 @@ routerset_is_empty(const routerset_t *set) return !set || smartlist_len(set->list) == 0; } +/** Return the number of entries in <b>set</b>. This does NOT return a + * negative value. */ +int +routerset_len(const routerset_t *set) +{ + if (!set) { + return 0; + } + return smartlist_len(set->list); +} + /** Helper. Return true iff <b>set</b> contains a router based on the other * provided fields. Return higher values for more specific subentries: a * single router is more specific than an address range of routers, which is diff --git a/src/or/routerset.h b/src/or/routerset.h index 8d41de8b6b..aca7c6e74e 100644 --- a/src/or/routerset.h +++ b/src/or/routerset.h @@ -38,6 +38,7 @@ void routerset_subtract_nodes(smartlist_t *out, char *routerset_to_string(const routerset_t *routerset); int routerset_equal(const routerset_t *old, const routerset_t *new); void routerset_free(routerset_t *routerset); +int routerset_len(const routerset_t *set); #ifdef ROUTERSET_PRIVATE STATIC char * routerset_get_countryname(const char *c); |