Преглед изворни кода

Merge remote branch 'origin/maint-0.2.2'

Conflicts:
	src/or/config.c
Nick Mathewson пре 14 година
родитељ
комит
af7fab020a
10 измењених фајлова са 85 додато и 14 уклоњено
  1. 5 0
      changes/bug1751
  2. 3 0
      changes/bug1964
  3. 6 0
      doc/tor.1.txt
  4. 19 1
      src/or/config.c
  5. 5 6
      src/or/connection_edge.c
  6. 9 3
      src/or/dirserv.c
  7. 2 0
      src/or/geoip.c
  8. 7 4
      src/or/or.h
  9. 27 0
      src/or/router.c
  10. 2 0
      src/or/router.h

+ 5 - 0
changes/bug1751

@@ -0,0 +1,5 @@
+  o Major features:
+    - Exit relays now try harder to block exit attempts from unknown
+      relays, to make it harder for people to use them as one-hop proxies.
+      Controlled by the refuseunknownexits consensus parameter, or you
+      can override it with the RefuseUnknownExits torrc option.

+ 3 - 0
changes/bug1964

@@ -0,0 +1,3 @@
+  o Major bugfixes:
+    - Fix a segfault that can happen when using bridges. Fixes bug 1964;
+      bugfix on 0.2.2.15-alpha.

+ 6 - 0
doc/tor.1.txt

@@ -908,6 +908,12 @@ is non-zero):
     the next day. All times are local, and given in 24-hour time. (Defaults to
     "month 1 0:00".)
 
+**RefuseUnknownExits** **0**|**1**|**auto**::
+    Prevent nodes that don't appear in the consensus from exiting using this
+    relay.  If the option is 1, we always block exit attempts from such
+    nodes; if it's 0, we never do, and if the option is "auto", then we do
+    whatever the authorities suggest in the consensus. (Defaults to auto.)
+
 **ServerDNSResolvConfFile** __filename__::
     Overrides the default DNS configuration with the configuration in
     __filename__. The file format is the same as the standard Unix

+ 19 - 1
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"),
@@ -1242,6 +1242,18 @@ options_act(or_options_t *old_options)
     connection_bucket_init();
 #endif
 
+  /* 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());
 
@@ -3008,6 +3020,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.");

+ 5 - 6
src/or/connection_edge.c

@@ -2500,6 +2500,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
   char *address=NULL;
   uint16_t port;
   or_circuit_t *or_circ = NULL;
+  or_options_t *options = get_options();
 
   assert_circuit_ok(circ);
   if (!CIRCUIT_IS_ORIGIN(circ))
@@ -2512,7 +2513,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
    * that we have a stream connected to a circuit, and we don't connect to a
    * circuit until we have a pending/successful resolve. */
 
-  if (!server_mode(get_options()) &&
+  if (!server_mode(options) &&
       circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
            "Relay begin cell at non-server. Closing.");
@@ -2545,13 +2546,11 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
       tor_free(address);
       return 0;
     }
-    if (or_circ && or_circ->p_conn && !get_options()->AllowSingleHopExits &&
+    if (or_circ && or_circ->p_conn && !options->AllowSingleHopExits &&
         (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(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.
@@ -2571,7 +2570,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
       return 0;
     }
   } else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
-    if (!directory_permits_begindir_requests(get_options()) ||
+    if (!directory_permits_begindir_requests(options) ||
         circ->purpose != CIRCUIT_PURPOSE_OR) {
       relay_send_end_cell_from_edge(rh.stream_id, circ,
                                     END_STREAM_REASON_NOTDIRECTORY, NULL);

+ 9 - 3
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 exit attempts from unknown relays. */
+  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

+ 2 - 0
src/or/geoip.c

@@ -254,6 +254,8 @@ geoip_get_country_by_ip(uint32_t ipaddr)
 int
 geoip_get_n_countries(void)
 {
+  if (!geoip_countries)
+    init_geoip_countries();
   return (int) smartlist_len(geoip_countries);
 }
 

+ 7 - 4
src/or/or.h

@@ -2532,10 +2532,13 @@ 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, defaulting to 'refuse' if the consensus says
+   * nothing). */
+  char *RefuseUnknownExits;
+  /** Parsed version of RefuseUnknownExits. -1 for auto. */
+  int RefuseUnknownExits_;
 
   /** Application ports that require all nodes in circ to have sufficient
    * uptime. */

+ 27 - 0
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,19 @@ 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 the consensus 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)
+{
+  if (options->RefuseUnknownExits_ != -1) {
+    return options->RefuseUnknownExits_;
+  } else {
+    return networkstatus_get_param(NULL, "refuseunknownexits", 1);
+  }
+}
+
 /** Remember if we've advertised ourselves to the dirservers. */
 static int server_is_advertised=0;
 
@@ -1137,6 +1151,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 +1325,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;

+ 2 - 0
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);