diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-03-09 13:57:32 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-03-09 13:57:32 -0500 |
commit | d4526e1d4a02b3faa6b7b6030a634cbe20bea9f2 (patch) | |
tree | 5e2fb5ff731ed5c75fb369e8cee8eaa155913c59 | |
parent | c13dc5170f09473ec2255501cbb1c0433bd959e5 (diff) | |
parent | a574f7f3fe7b4f7300c1ced5f67d8e014e04ffbd (diff) | |
download | tor-d4526e1d4a02b3faa6b7b6030a634cbe20bea9f2.tar tor-d4526e1d4a02b3faa6b7b6030a634cbe20bea9f2.tar.gz |
Merge remote-tracking branch 'origin/maint-0.2.2'
Conflicts:
src/or/routerlist.c
-rw-r--r-- | changes/bug5343 | 7 | ||||
-rw-r--r-- | src/or/routerlist.c | 29 |
2 files changed, 31 insertions, 5 deletions
diff --git a/changes/bug5343 b/changes/bug5343 new file mode 100644 index 000000000..e4e14897f --- /dev/null +++ b/changes/bug5343 @@ -0,0 +1,7 @@ + o Security fixes: + - Only build circuits if we have a sufficient threshold of the total + descriptors marked in the consensus with the "Exit" flag. This + mitigates an attack proposed by wanoskarnet, in which all of a + client's bridges collude to restrict the exit nodes that the + client knows about. Fixes bug 5343. + diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d0ef662ca..a9946b8f9 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -4891,19 +4891,22 @@ get_dir_info_status_string(void) * them seem like ones we'd use, and how many of <em>those</em> we have * descriptors for. Store the former in *<b>num_usable</b> and the latter in * *<b>num_present</b>. If <b>in_set</b> is non-NULL, only consider those - * routers in <b>in_set</b>. + * routers in <b>in_set</b>. If <b>exit_only</b> is true, only consider nodes + * with the Exit flag. */ static void count_usable_descriptors(int *num_present, int *num_usable, const networkstatus_t *consensus, const or_options_t *options, time_t now, - routerset_t *in_set) + routerset_t *in_set, int exit_only) { const int md = (consensus->flavor == FLAV_MICRODESC); *num_present = 0, *num_usable=0; SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, routerstatus_t *, rs) { + if (exit_only && ! rs->is_exit) + continue; if (in_set && ! routerset_contains_routerstatus(in_set, rs, -1)) continue; if (client_would_use_router(rs, now, options)) { @@ -4941,7 +4944,7 @@ count_loading_descriptors_progress(void) return 0; /* can't count descriptors if we have no list of them */ count_usable_descriptors(&num_present, &num_usable, - consensus, get_options(), now, NULL); + consensus, get_options(), now, NULL, 0); if (num_usable == 0) return 0; /* don't div by 0 */ @@ -4960,6 +4963,7 @@ static void update_router_have_minimum_dir_info(void) { int num_present = 0, num_usable=0; + int num_exit_present = 0, num_exit_usable = 0; time_t now = time(NULL); int res; const or_options_t *options = get_options(); @@ -4989,7 +4993,9 @@ update_router_have_minimum_dir_info(void) using_md = consensus->flavor == FLAV_MICRODESC; count_usable_descriptors(&num_present, &num_usable, consensus, options, now, - NULL); + NULL, 0); + count_usable_descriptors(&num_exit_present, &num_exit_usable, + consensus, options, now, options->ExitNodes, 1); if (num_present < num_usable/4) { tor_snprintf(dir_info_status, sizeof(dir_info_status), @@ -5004,12 +5010,25 @@ update_router_have_minimum_dir_info(void) num_present, using_md ? "micro" : "", num_present ? "" : "s"); res = 0; goto done; + } else if (num_exit_present < num_exit_usable / 3) { + tor_snprintf(dir_info_status, sizeof(dir_info_status), + "We have only %d/%d usable exit node descriptors.", + num_exit_present, num_exit_usable); + res = 0; + control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0); + goto done; + } else if (num_exit_present < 2) { + tor_snprintf(dir_info_status, sizeof(dir_info_status), + "Only %d descriptor%s here and believed reachable!", + num_exit_present, num_exit_present ? "" : "s"); + res = 0; + goto done; } /* Check for entry nodes. */ if (options->EntryNodes) { count_usable_descriptors(&num_present, &num_usable, consensus, options, - now, options->EntryNodes); + now, options->EntryNodes, 0); if (!num_usable || !num_present) { tor_snprintf(dir_info_status, sizeof(dir_info_status), |