[tor-commits] [tor/master] Allow asking a bridge's own descriptor over one-hop connection

nickm at torproject.org nickm at torproject.org
Wed Oct 26 12:39:48 UTC 2016


commit 8cc528c75067567ef32822e5bdb39535cea5d5e8
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Oct 25 19:30:50 2016 -0400

    Allow asking a bridge's own descriptor over one-hop connection
    
    When we refactored purpose_needs_anonymity(), we made it so _all_
    bridge requests required anonymity.  But that missed the case
    that we are allowed to ask a bridge for its own descriptor.
    
    With this patch, we consider the resource, and allow "authority.z"
    ("your own descriptor, compressed") for a bridge's server descriptor
    to be non-anonymous.
    
    Fix for bug 20410; bug not in any released Tor.
---
 src/or/connection_edge.c |  4 +++-
 src/or/directory.c       | 22 ++++++++++++++------
 src/or/directory.h       |  3 ++-
 src/or/routerlist.c      |  3 ++-
 src/test/test_dir.c      | 52 +++++++++++++++++++++++++++++++++---------------
 5 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 44dfcef..1ee0c0f 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2434,7 +2434,9 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
      * Otherwise, directory connections are typically one-hop.
      * This matches the earlier check for directory connection path anonymity
      * in directory_initiate_command_rend(). */
-    if (purpose_needs_anonymity(linked_dir_conn_base->purpose, 0)) {
+    if (purpose_needs_anonymity(linked_dir_conn_base->purpose,
+                    TO_DIR_CONN(linked_dir_conn_base)->router_purpose,
+                    TO_DIR_CONN(linked_dir_conn_base)->requested_resource)) {
       assert_circ_anonymity_ok(circ, options);
     }
   } else {
diff --git a/src/or/directory.c b/src/or/directory.c
index facd588..a73680a 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -127,14 +127,23 @@ static void connection_dir_close_consensus_fetches(
  * specifically been configured to be over an anonymous connection,
  * or 3) if the router is a bridge */
 int
-purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
+purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
+                        const char *resource)
 {
   if (get_options()->AllDirActionsPrivate)
     return 1;
 
-  if (router_purpose == ROUTER_PURPOSE_BRIDGE)
+  if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
+    if (dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC
+        && resource && !strcmp(resource, "authority.z")) {
+      /* We are asking a bridge for its own descriptor. That doesn't need
+         anonymity. */
+      return 0;
+    }
+    /* Assume all other bridge stuff needs anonymity. */
     return 1; /* if no circuits yet, this might break bootstrapping, but it's
                * needed to be safe. */
+  }
 
   switch (dir_purpose)
   {
@@ -364,7 +373,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
         log_info(LD_DIR, "Uploading an extrainfo too (length %d)",
                  (int) extrainfo_len);
       }
-      if (purpose_needs_anonymity(dir_purpose, router_purpose)) {
+      if (purpose_needs_anonymity(dir_purpose, router_purpose, NULL)) {
         indirection = DIRIND_ANONYMOUS;
       } else if (!fascist_firewall_allows_dir_server(ds,
                                                      FIREWALL_DIR_CONNECTION,
@@ -458,7 +467,8 @@ MOCK_IMPL(void, directory_get_from_dirserver, (
   int prefer_authority = (directory_fetches_from_authorities(options)
                           || want_authority == DL_WANT_AUTHORITY);
   int require_authority = 0;
-  int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose);
+  int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose,
+                                            resource);
   dirinfo_type_t type = dir_fetch_type(dir_purpose, router_purpose, resource);
   time_t if_modified_since = 0;
 
@@ -592,7 +602,7 @@ MOCK_IMPL(void, directory_get_from_dirserver, (
                "While fetching directory info, "
                "no running dirservers known. Will try again later. "
                "(purpose %d)", dir_purpose);
-    if (!purpose_needs_anonymity(dir_purpose, router_purpose)) {
+    if (!purpose_needs_anonymity(dir_purpose, router_purpose, resource)) {
       /* remember we tried them all and failed. */
       directory_all_unreachable(time(NULL));
     }
@@ -1142,7 +1152,7 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port,
 
   log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
 
-  if (purpose_needs_anonymity(dir_purpose, router_purpose)) {
+  if (purpose_needs_anonymity(dir_purpose, router_purpose, resource)) {
     tor_assert(anonymized_connection ||
                rend_non_anonymous_mode_enabled(options));
   }
diff --git a/src/or/directory.h b/src/or/directory.h
index f04e7ab..f1cdd9f 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -132,7 +132,8 @@ int download_status_get_n_failures(const download_status_t *dls);
 int download_status_get_n_attempts(const download_status_t *dls);
 time_t download_status_get_next_attempt_at(const download_status_t *dls);
 
-int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose);
+int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
+                            const char *resource);
 
 #ifdef TOR_UNIT_TESTS
 /* Used only by directory.c and test_dir.c */
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 83a2587..6f182d3 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -929,7 +929,8 @@ authority_certs_fetch_resource_impl(const char *resource,
                                     const routerstatus_t *rs)
 {
   const or_options_t *options = get_options();
-  int get_via_tor = purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0);
+  int get_via_tor = purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0,
+                                            resource);
 
   /* Make sure bridge clients never connect to anything but a bridge */
   if (options->UseBridges) {
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index d9c565c..419aa24 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -3258,7 +3258,7 @@ test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
   (void)arg;
 
   tor_capture_bugs_(1);
-  tt_int_op(1, ==, purpose_needs_anonymity(0, 0));
+  tt_int_op(1, ==, purpose_needs_anonymity(0, 0, NULL));
   tt_int_op(1, ==, smartlist_len(tor_get_captured_bug_log_()));
   tor_end_capture_bugs_();
  done: ;
@@ -3269,9 +3269,21 @@ test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
 {
   (void)arg;
 
-  tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE));
+  tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
+  tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
+                                           "foobar"));
   tt_int_op(1, ==, purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
-                                   ROUTER_PURPOSE_BRIDGE));
+                                           ROUTER_PURPOSE_BRIDGE, NULL));
+ done: ;
+}
+
+static void
+test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
+{
+  (void)arg;
+  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
+                                           ROUTER_PURPOSE_BRIDGE,
+                                           "authority.z"));
  done: ;
 }
 
@@ -3282,11 +3294,11 @@ test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg)
 
   tt_int_op(1, ==, purpose_needs_anonymity(
                     DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
-                    ROUTER_PURPOSE_GENERAL));
+                    ROUTER_PURPOSE_GENERAL, NULL));
   tt_int_op(1, ==, purpose_needs_anonymity(
-                      DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0));
+                    DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0,  NULL));
   tt_int_op(1, ==, purpose_needs_anonymity(
-                      DIR_PURPOSE_FETCH_RENDDESC_V2, 0));
+                    DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL));
  done: ;
 }
 
@@ -3296,17 +3308,24 @@ test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
   (void)arg;
 
   tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
-                                           ROUTER_PURPOSE_GENERAL));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0));
+                                           ROUTER_PURPOSE_GENERAL, NULL));
+  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
   tt_int_op(0, ==, purpose_needs_anonymity(
-                    DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0));
-  tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0));
+                    DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
+  tt_int_op(0, ==,
+            purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
   done: ;
 }
 
@@ -5512,6 +5531,7 @@ struct testcase_t dir_tests[] = {
   DIR(dirserv_set_routerstatus_testing, 0),
   DIR(http_handling, 0),
   DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
+  DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
   DIR(purpose_needs_anonymity_returns_true_by_default, 0),
   DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0),
   DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),





More information about the tor-commits mailing list