[or-cvs] [tor/maint-0.2.2 1/2] First cut of code to enable RefuseUnknownExits

nickm at torproject.org nickm at torproject.org
Mon Sep 27 21:06:07 UTC 2010


Author: Nick Mathewson <nickm at torproject.org>
Date: Tue, 21 Sep 2010 01:03:29 -0400
Subject: First cut of code to enable RefuseUnknownExits
Commit: ef5925237d4712c40fb6d69b8de882ab39e6798f

The RefuseUnknownExits config option is now a tristate, with "1"
meaning "enable it no matter what the consensus says", "0" meaning
"disable it no matter what the consensus says", and "auto" meaning "do
what the consensus says".  If the consensus is silent, we enable
RefuseUnknownExits.

This patch also changes the dirserv logic so that refuseunknownexits
won't make us cache unless we're an exit.
---
 src/or/config.c          |   21 ++++++++++++++++++++-
 src/or/connection_edge.c |    4 +---
 src/or/dirserv.c         |   12 +++++++++---
 src/or/or.h              |   10 ++++++----
 src/or/router.c          |   30 ++++++++++++++++++++++++++++++
 src/or/router.h          |    2 ++
 6 files changed, 68 insertions(+), 11 deletions(-)

diff --git a/src/or/config.c b/src/or/config.c
index 6b3bcf6..30a4d0f 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -327,7 +327,7 @@ static config_var_t _option_vars[] = {
   V(RecommendedClientVersions,   LINELIST, NULL),
   V(RecommendedServerVersions,   LINELIST, NULL),
   OBSOLETE("RedirectExit"),
-  V(RefuseUnknownExits,          BOOL,     "0"),
+  V(RefuseUnknownExits,          STRING,   "auto"),
   V(RejectPlaintextPorts,        CSV,      ""),
   V(RelayBandwidthBurst,         MEMUNIT,  "0"),
   V(RelayBandwidthRate,          MEMUNIT,  "0"),
@@ -1228,6 +1228,19 @@ options_act(or_options_t *old_options)
   if (accounting_is_enabled(options))
     configure_accounting(time(NULL));
 
+  /* parse RefuseUnknownExits tristate */
+  if (!strcmp(options->RefuseUnknownExits, "0"))
+    options->RefuseUnknownExits_ = 0;
+  else if (!strcmp(options->RefuseUnknownExits, "1"))
+    options->RefuseUnknownExits_ = 1;
+  else if (!strcmp(options->RefuseUnknownExits, "auto"))
+    options->RefuseUnknownExits_ = -1;
+  else {
+    /* Should have caught this in options_validate */
+    return -1;
+  }
+
+
   /* Change the cell EWMA settings */
   cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
 
@@ -2994,6 +3007,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
       REJECT("Failed to resolve/guess local address. See logs for details.");
   }
 
+  if (strcmp(options->RefuseUnknownExits, "0") &&
+      strcmp(options->RefuseUnknownExits, "1") &&
+      strcmp(options->RefuseUnknownExits, "auto")) {
+    REJECT("RefuseUnknownExits must be 0, 1, or auto");
+  }
+
 #ifndef MS_WINDOWS
   if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
     REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 6a3a5ef..6359515 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2537,9 +2537,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
         (or_circ->is_first_hop ||
          (!connection_or_digest_is_known_relay(
                                        or_circ->p_conn->identity_digest) &&
-//        XXX022 commented out so we can test it first in 0.2.2.11 -RD
-//        networkstatus_get_param(NULL, "refuseunknownexits", 1)))) {
-          get_options()->RefuseUnknownExits))) {
+          should_refuse_unknown_exits(get_options())))) {
       /* Don't let clients use us as a single-hop proxy, unless the user
        * has explicitly allowed that in the config. It attracts attackers
        * and users who'd be better off with, well, single-hop proxies.
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 3fcf178..6dca0d1 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1153,18 +1153,21 @@ directory_fetches_from_authorities(or_options_t *options)
 {
   routerinfo_t *me;
   uint32_t addr;
+  int refuseunknown;
   if (options->FetchDirInfoEarly)
     return 1;
   if (options->BridgeRelay == 1)
     return 0;
   if (server_mode(options) && router_pick_published_address(options, &addr)<0)
     return 1; /* we don't know our IP address; ask an authority. */
-  if (options->DirPort == 0 && !options->RefuseUnknownExits)
+  refuseunknown = router_my_exit_policy_is_reject_star() &&
+    should_refuse_unknown_exits(options);
+  if (options->DirPort == 0 && !refuseunknown)
     return 0;
   if (!server_mode(options) || !advertised_server_mode())
     return 0;
   me = router_get_my_routerinfo();
-  if (!me || (!me->dir_port && !options->RefuseUnknownExits))
+  if (!me || (!me->dir_port && !refuseunknown))
     return 0; /* if dirport not advertised, return 0 too */
   return 1;
 }
@@ -1208,7 +1211,10 @@ directory_caches_dir_info(or_options_t *options)
     return 1;
   if (!server_mode(options) || !advertised_server_mode())
     return 0;
-  return options->RefuseUnknownExits;
+  /* We need an up-to-date view of network info if we're going to try to
+   * block unknown exits. */
+  return router_my_exit_policy_is_reject_star() &&
+    should_refuse_unknown_exits(options);
 }
 
 /** Return 1 if we want to allow remote people to ask us directory
diff --git a/src/or/or.h b/src/or/or.h
index 3c10973..6c1c8ef 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2468,10 +2468,12 @@ typedef struct {
   int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */
   uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */
 
-  /** Whether we should drop exit streams from Tors that we don't know
-   * are relays. XXX022 In here for 0.2.2.11 as a temporary test before
-   * we switch over to putting it in consensusparams. -RD */
-  int RefuseUnknownExits;
+  /** Whether we should drop exit streams from Tors that we don't know are
+   * relays.  One of "0" (never refuse), "1" (always refuse), or "auto" (do
+   * what the consensus says). -RD */
+  const char *RefuseUnknownExits;
+  /** Parsed version of RefuseUnknownExits. -1 for auto. */
+  int RefuseUnknownExits_;
 
   /** Application ports that require all nodes in circ to have sufficient
    * uptime. */
diff --git a/src/or/router.c b/src/or/router.c
index 978078b..6ae2ed0 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -18,6 +18,7 @@
 #include "geoip.h"
 #include "hibernate.h"
 #include "main.h"
+#include "networkstatus.h"
 #include "policies.h"
 #include "relay.h"
 #include "rephist.h"
@@ -975,6 +976,22 @@ server_mode(or_options_t *options)
   return (options->ORPort != 0 || options->ORListenAddress);
 }
 
+/** Return true iff the combination of options in <b>options</b> and parameters
+ * in <b>consensus</b> mean that we don't want to allow exits from circuits
+ * we got from addresses not known to be servers. */
+int
+should_refuse_unknown_exits(or_options_t *options)
+{
+  networkstatus_t *consensus;
+  if (options->RefuseUnknownExits_ != -1) {
+    return options->RefuseUnknownExits_;
+  } else if ((consensus = networkstatus_get_latest_consensus()) != NULL) {
+    return networkstatus_get_param(consensus, "refuseunknownexits", 1);
+  } else {
+    return 1;
+  }
+}
+
 /** Remember if we've advertised ourselves to the dirservers. */
 static int server_is_advertised=0;
 
@@ -1137,6 +1154,17 @@ router_compare_to_my_exit_policy(edge_connection_t *conn)
                    desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
 }
 
+/** Return true iff my exit policy is reject *:*.  Return -1 if we don't
+ * have a descriptor */
+int
+router_my_exit_policy_is_reject_star(void)
+{
+  if (!router_get_my_routerinfo()) /* make sure desc_routerinfo exists */
+    return -1;
+
+  return desc_routerinfo->policy_is_reject_star;
+}
+
 /** Return true iff I'm a server and <b>digest</b> is equal to
  * my identity digest. */
 int
@@ -1300,6 +1328,8 @@ router_rebuild_descriptor(int force)
   policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
                              options->ExitPolicyRejectPrivate,
                              ri->address, !options->BridgeRelay);
+  ri->policy_is_reject_star =
+    policy_is_reject_star(ri->exit_policy);
 
   if (desc_routerinfo) { /* inherit values */
     ri->is_valid = desc_routerinfo->is_valid;
diff --git a/src/or/router.h b/src/or/router.h
index d90a7cf..c17fc78 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -51,6 +51,7 @@ int server_mode(or_options_t *options);
 int advertised_server_mode(void);
 int proxy_mode(or_options_t *options);
 void consider_publishable_server(int force);
+int should_refuse_unknown_exits(or_options_t *options);
 
 void router_upload_dir_desc_to_dirservers(int force);
 void mark_my_descriptor_dirty_if_older_than(time_t when);
@@ -60,6 +61,7 @@ void check_descriptor_ipaddress_changed(time_t now);
 void router_new_address_suggestion(const char *suggestion,
                                    const dir_connection_t *d_conn);
 int router_compare_to_my_exit_policy(edge_connection_t *conn);
+int router_my_exit_policy_is_reject_star(void);
 routerinfo_t *router_get_my_routerinfo(void);
 extrainfo_t *router_get_my_extrainfo(void);
 const char *router_get_my_descriptor(void);
-- 
1.7.1




More information about the tor-commits mailing list