Browse Source

Merge branch 'feature2553-v4-rebased'

Nick Mathewson 14 years ago
parent
commit
d04f21bf39
10 changed files with 104 additions and 1 deletions
  1. 7 0
      configure.in
  2. 7 0
      doc/tor.1.txt
  3. 6 0
      src/or/circuituse.c
  4. 41 0
      src/or/config.c
  5. 10 0
      src/or/connection_edge.c
  6. 4 0
      src/or/directory.c
  7. 5 0
      src/or/main.c
  8. 9 0
      src/or/or.h
  9. 9 1
      src/or/rendclient.c
  10. 6 0
      src/or/rendservice.c

+ 7 - 0
configure.in

@@ -145,6 +145,13 @@ if test "$enable_local_appdata" = "yes"; then
             [Defined if we default to host local appdata paths on Windows])
 fi
 
+# Tor2web mode flag
+AC_ARG_ENABLE(tor2web-mode,
+     AS_HELP_STRING(--enable-tor2web-mode, support tor2web non-anonymous mode),
+[if test x$enableval = xyes; then
+    CFLAGS="$CFLAGS -D ENABLE_TOR2WEB_MODE=1"
+fi])
+
 AC_ARG_ENABLE(bufferevents,
      AS_HELP_STRING(--enable-bufferevents, use Libevent's buffered IO.))
 

+ 7 - 0
doc/tor.1.txt

@@ -1016,6 +1016,13 @@ The following options are useful only for clients (that is, if
     Tor will look at the UseOptimisticData parameter in the networkstatus.
     (Default: auto)
 
+**Tor2webMode** **0**|**1**::
+    When this option is set, Tor connects to hidden services
+    **non-anonymously**.  This option also disables client connections to
+    non-hidden-service hostnames through Tor. It **must only** be used when
+    running a tor2web Hidden Service web proxy.
+    To enable this option the compile time flag --enable-tor2webmode must be
+    specified. (Default: 0)
 
 SERVER OPTIONS
 --------------

+ 6 - 0
src/or/circuituse.c

@@ -1492,6 +1492,12 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
     else
       new_circ_purpose = desired_circuit_purpose;
 
+    if (options->Tor2webMode &&
+        (new_circ_purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND ||
+         new_circ_purpose == CIRCUIT_PURPOSE_C_INTRODUCING)) {
+      want_onehop = 1;
+    }
+
     {
       int flags = CIRCLAUNCH_NEED_CAPACITY;
       if (want_onehop) flags |= CIRCLAUNCH_ONEHOP_TUNNEL;

+ 41 - 0
src/or/config.c

@@ -397,6 +397,7 @@ static config_var_t _option_vars[] = {
   V(TestSocks,                   BOOL,     "0"),
   OBSOLETE("TestVia"),
   V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
+  V(Tor2webMode,                 BOOL,     "0"),
   V(TrackHostExits,              CSV,      NULL),
   V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
   OBSOLETE("TrafficShaping"),
@@ -1339,6 +1340,28 @@ options_act(const or_options_t *old_options)
   if (consider_adding_dir_authorities(options, old_options) < 0)
     return -1;
 
+#ifdef NON_ANONYMOUS_MODE_ENABLED
+  log(LOG_WARN, LD_GENERAL, "This copy of Tor was compiled to run in a "
+      "non-anonymous mode. It will provide NO ANONYMITY.");
+#endif
+
+#ifdef ENABLE_TOR2WEB_MODE
+  if (!options->Tor2webMode) {
+    log_err(LD_CONFIG, "This copy of Tor was compiled to run in "
+            "'tor2web mode'. It can only be run with the Tor2webMode torrc "
+            "option enabled.");
+    return -1;
+  }
+#else
+  if (options->Tor2webMode) {
+    log_err(LD_CONFIG, "This copy of Tor was not compiled to run in "
+            "'tor2web mode'. It cannot be run with the Tor2webMode torrc "
+            "option enabled. To enable Tor2webMode recompile with the "
+            "--enable-tor2webmode option.");
+    return -1;
+  }
+#endif
+
   if (options->Bridges) {
     mark_bridge_list();
     for (cl = options->Bridges; cl; cl = cl->next) {
@@ -3617,6 +3640,24 @@ options_validate(or_options_t *old_options, or_options_t *options,
     options->RendPostPeriod = MAX_DIR_PERIOD;
   }
 
+  if (options->Tor2webMode && options->LearnCircuitBuildTimeout) {
+    /* LearnCircuitBuildTimeout and Tor2webMode are incompatible in
+     * two ways:
+     *
+     * - LearnCircuitBuildTimeout results in a low CBT, which
+     *   Tor2webMode's use of one-hop rendezvous circuits lowers
+     *   much further, producing *far* too many timeouts.
+     *
+     * - The adaptive CBT code does not update its timeout estimate
+     *   using build times for single-hop circuits.
+     *
+     * If we fix both of these issues someday, we should test
+     * Tor2webMode with LearnCircuitBuildTimeout on again. */
+    log_notice(LD_CONFIG,"Tor2webMode is enabled; turning "
+               "LearnCircuitBuildTimeout off.");
+    options->LearnCircuitBuildTimeout = 0;
+  }
+
   if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
     log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
              "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);

+ 10 - 0
src/or/connection_edge.c

@@ -1973,6 +1973,14 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
       return -1;
     }
 
+    if (options->Tor2webMode) {
+      log_warn(LD_APP, "Refusing to connect to non-hidden-service hostname %s "
+               "because tor2web mode is enabled.",
+               safe_str_client(socks->address));
+      connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
+      return -1;
+    }
+
     if (socks->command == SOCKS_COMMAND_RESOLVE) {
       uint32_t answer;
       struct in_addr in;
@@ -2534,7 +2542,9 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
   begin_type = ap_conn->use_begindir ?
                  RELAY_COMMAND_BEGIN_DIR : RELAY_COMMAND_BEGIN;
   if (begin_type == RELAY_COMMAND_BEGIN) {
+#ifndef NON_ANONYMOUS_MODE_ENABLED
     tor_assert(circ->build_state->onehop_tunnel == 0);
+#endif
   }
 
   if (connection_edge_send_command(edge_conn, begin_type,

+ 4 - 0
src/or/directory.c

@@ -907,8 +907,12 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
 
   log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
 
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(is_sensitive_dir_purpose(dir_purpose) &&
                !anonymized_connection));
+#else
+  (void)is_sensitive_dir_purpose;
+#endif
 
   /* ensure that we don't make direct connections when a SOCKS server is
    * configured. */

+ 5 - 0
src/or/main.c

@@ -2285,6 +2285,11 @@ tor_init(int argc, char *argv[])
                  "Expect more bugs than usual.");
   }
 
+#ifdef NON_ANONYMOUS_MODE_ENABLED
+  log(LOG_WARN, LD_GENERAL, "This copy of Tor was compiled to run in a "
+      "non-anonymous mode. It will provide NO ANONYMITY.");
+#endif
+
   if (network_init()<0) {
     log_err(LD_BUG,"Error initializing network; exiting.");
     return -1;

+ 9 - 0
src/or/or.h

@@ -130,6 +130,10 @@
 #define cell_t tor_cell_t
 #endif
 
+#ifdef ENABLE_TOR2WEB_MODE
+#define NON_ANONYMOUS_MODE_ENABLED 1
+#endif
+
 /** Length of longest allowable configured nickname. */
 #define MAX_NICKNAME_LEN 19
 /** Length of a router identity encoded as a hexadecimal digest, plus
@@ -3043,6 +3047,11 @@ typedef struct {
   int AllDirActionsPrivate; /**< Should every directory action be sent
                              * through a Tor circuit? */
 
+  /** Run in 'tor2web mode'? (I.e. only make client connections to hidden
+   * services, and use a single hop for all hidden-service-related
+   * circuits.) */
+  int Tor2webMode;
+
   int ConnLimit; /**< Demanded minimum number of simultaneous connections. */
   int _ConnLimit; /**< Maximum allowed number of simultaneous connections. */
   int RunAsDaemon; /**< If true, run in the background. (Unix only) */

+ 9 - 1
src/or/rendclient.c

@@ -139,8 +139,10 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
   tor_assert(rendcirc->rend_data);
   tor_assert(!rend_cmp_service_ids(introcirc->rend_data->onion_address,
                                    rendcirc->rend_data->onion_address));
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(introcirc->build_state->onehop_tunnel));
   tor_assert(!(rendcirc->build_state->onehop_tunnel));
+#endif
 
   if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
                               &entry) < 1) {
@@ -331,7 +333,9 @@ rend_client_introduction_acked(origin_circuit_t *circ,
   }
 
   tor_assert(circ->build_state->chosen_exit);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circ->build_state->onehop_tunnel));
+#endif
   tor_assert(circ->rend_data);
 
   if (request_len == 0) {
@@ -343,7 +347,9 @@ rend_client_introduction_acked(origin_circuit_t *circ,
     rendcirc = circuit_get_by_rend_query_and_purpose(
                circ->rend_data->onion_address, CIRCUIT_PURPOSE_C_REND_READY);
     if (rendcirc) { /* remember the ack */
+#ifndef NON_ANONYMOUS_MODE_ENABLED
       tor_assert(!(rendcirc->build_state->onehop_tunnel));
+#endif
       rendcirc->_base.purpose = CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED;
       /* Set timestamp_dirty, because circuit_expire_building expects
        * it to specify when a circuit entered the
@@ -529,6 +535,7 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
   char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
   time_t now = time(NULL);
   char descriptor_cookie_base64[3*REND_DESC_COOKIE_LEN_BASE64];
+  int tor2web_mode = get_options()->Tor2webMode;
   tor_assert(desc_id);
   tor_assert(rend_query);
   /* Determine responsible dirs. Even if we can't get all we want,
@@ -587,7 +594,8 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
   directory_initiate_command_routerstatus_rend(hs_dir,
                                           DIR_PURPOSE_FETCH_RENDDESC_V2,
                                           ROUTER_PURPOSE_GENERAL,
-                                          1, desc_id_base32, NULL, 0, 0,
+                                          !tor2web_mode, desc_id_base32,
+                                          NULL, 0, 0,
                                           rend_query);
   log_info(LD_REND, "Sending fetch request for v2 descriptor for "
                     "service '%s' with descriptor ID '%s', auth type %d, "

+ 6 - 0
src/or/rendservice.c

@@ -952,7 +952,9 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
   time_t *access_time;
   const or_options_t *options = get_options();
 
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->rend_data);
 
   base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
@@ -1440,7 +1442,9 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
   crypto_pk_env_t *intro_key;
 
   tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->cpath);
   tor_assert(circuit->rend_data);
 
@@ -1597,7 +1601,9 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
   tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
   tor_assert(circuit->cpath);
   tor_assert(circuit->build_state);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->rend_data);
   hop = circuit->build_state->pending_final_cpath;
   tor_assert(hop);