[tor-commits] [tor/master] refuse excluded hidserv nodes if strictnodes

nickm at torproject.org nickm at torproject.org
Wed Apr 27 18:36:21 UTC 2011


commit 82178a81f6748c9b26bdc8a5da36dd34b689281b
Author: Roger Dingledine <arma at torproject.org>
Date:   Sat Oct 17 18:52:18 2009 -0400

    refuse excluded hidserv nodes if strictnodes
    
    Make hidden services more flaky for people who set both ExcludeNodes
    and StrictNodes. Not recommended, especially for hidden service operators.
---
 src/or/rendclient.c  |   56 +++++++++++++++++++++++++++++++++++++++++++++----
 src/or/rendservice.c |   14 +++++++++++-
 2 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 8ac909f..90304c3 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -22,6 +22,9 @@
 #include "rephist.h"
 #include "routerlist.h"
 
+static extend_info_t *rend_client_get_random_intro_impl(
+                         const rend_data_t *rend_query, const int strict);
+
 /** Called when we've established a circuit to an introduction point:
  * send the introduction request. */
 void
@@ -739,10 +742,31 @@ rend_client_desc_trynow(const char *query)
 extend_info_t *
 rend_client_get_random_intro(const rend_data_t *rend_query)
 {
+  extend_info_t *result;
+  /* See if we can get a node that complies with ExcludeNodes */
+  if ((result = rend_client_get_random_intro_impl(rend_query, 1)))
+    return result;
+  /* If not, and StrictNodes is not set, see if we can return any old node
+   */
+  if (!get_options()->StrictNodes)
+    return rend_client_get_random_intro_impl(rend_query, 0);
+  return NULL;
+}
+
+/** As rend_client_get_random_intro, except assume that StrictNodes is set
+ * iff <b>strict</b> is true.
+ */
+static extend_info_t *
+rend_client_get_random_intro_impl(const rend_data_t *rend_query,
+                                  const int strict)
+{
   int i;
   rend_cache_entry_t *entry;
   rend_intro_point_t *intro;
   routerinfo_t *router;
+  or_options_t *options = get_options();
+  smartlist_t *usable_nodes;
+  int n_excluded = 0;
 
   if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
     log_warn(LD_REND,
@@ -750,13 +774,26 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
              safe_str_client(rend_query->onion_address));
     return NULL;
   }
+  /* We'll keep a separate list of the usable nodes.  If this becomes empty,
+   * no nodes are usable.  */
+  usable_nodes = smartlist_create();
+  smartlist_add_all(usable_nodes, entry->parsed->intro_nodes);
 
  again:
-  if (smartlist_len(entry->parsed->intro_nodes) == 0)
+  if (smartlist_len(usable_nodes) == 0) {
+    if (n_excluded && get_options()->StrictNodes) {
+      /* We only want to warn if StrictNodes is really set. Otherwise
+       * we're just about to retry anyways.
+       */
+      log_warn(LD_REND, "All introduction points for hidden service are "
+               "at excluded relays, and StrictNodes is set. Skipping.");
+    }
+    smartlist_free(usable_nodes);
     return NULL;
+  }
 
-  i = crypto_rand_int(smartlist_len(entry->parsed->intro_nodes));
-  intro = smartlist_get(entry->parsed->intro_nodes, i);
+  i = crypto_rand_int(smartlist_len(usable_nodes));
+  intro = smartlist_get(usable_nodes, i);
   /* Do we need to look up the router or is the extend info complete? */
   if (!intro->extend_info->onion_key) {
     if (tor_digest_is_zero(intro->extend_info->identity_digest))
@@ -766,13 +803,22 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
     if (!router) {
       log_info(LD_REND, "Unknown router with nickname '%s'; trying another.",
                intro->extend_info->nickname);
-      rend_intro_point_free(intro);
-      smartlist_del(entry->parsed->intro_nodes, i);
+      smartlist_del(usable_nodes, i);
       goto again;
     }
     extend_info_free(intro->extend_info);
     intro->extend_info = extend_info_from_router(router);
   }
+  /* Check if we should refuse to talk to this router. */
+  if (options->ExcludeNodes && strict &&
+      routerset_contains_extendinfo(options->ExcludeNodes,
+                                    intro->extend_info)) {
+    n_excluded++;
+    smartlist_del(usable_nodes, i);
+    goto again;
+  }
+
+  smartlist_free(usable_nodes);
   return extend_info_dup(intro->extend_info);
 }
 
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 4503982..88f1ba3 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -848,6 +848,7 @@ clean_accepted_intros(rend_service_t *service, time_t now)
 /** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
  * rendezvous point.
  */
+ /* XXX022 this function sure could use some organizing. -RD */
 int
 rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
                        size_t request_len)
@@ -875,6 +876,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
   time_t now = time(NULL);
   char diffie_hellman_hash[DIGEST_LEN];
   time_t *access_time;
+  or_options_t *options = get_options();
+
   tor_assert(circuit->rend_data);
 
   base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
@@ -1047,6 +1050,15 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
     goto err;
   }
 
+  /* Check if we'd refuse to talk to this router */
+  if (options->ExcludeNodes && options->StrictNodes &&
+      routerset_contains_extendinfo(options->ExcludeNodes, extend_info)) {
+    log_warn(LD_REND, "Client asked to rendezvous at a relay that we "
+             "exclude, and StrictNodes is set. Refusing service.");
+    reason = END_CIRC_REASON_INTERNAL; /* XXX might leak why we refused */
+    goto err;
+  }
+
   r_cookie = ptr;
   base16_encode(hexcookie,9,r_cookie,4);
 
@@ -1394,7 +1406,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
 
 /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
  * live introduction point, and note that the service descriptor is
- * now out-of-date.*/
+ * now out-of-date. */
 int
 rend_service_intro_established(origin_circuit_t *circuit,
                                const uint8_t *request,





More information about the tor-commits mailing list