aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-03-09 13:57:32 -0500
committerNick Mathewson <nickm@torproject.org>2012-03-09 13:57:32 -0500
commitd4526e1d4a02b3faa6b7b6030a634cbe20bea9f2 (patch)
tree5e2fb5ff731ed5c75fb369e8cee8eaa155913c59
parentc13dc5170f09473ec2255501cbb1c0433bd959e5 (diff)
parenta574f7f3fe7b4f7300c1ced5f67d8e014e04ffbd (diff)
downloadtor-d4526e1d4a02b3faa6b7b6030a634cbe20bea9f2.tar
tor-d4526e1d4a02b3faa6b7b6030a634cbe20bea9f2.tar.gz
Merge remote-tracking branch 'origin/maint-0.2.2'
Conflicts: src/or/routerlist.c
-rw-r--r--changes/bug53437
-rw-r--r--src/or/routerlist.c29
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),