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])
             [Defined if we default to host local appdata paths on Windows])
 fi
 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,
 AC_ARG_ENABLE(bufferevents,
      AS_HELP_STRING(--enable-bufferevents, use Libevent's buffered IO.))
      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.
     Tor will look at the UseOptimisticData parameter in the networkstatus.
     (Default: auto)
     (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
 SERVER OPTIONS
 --------------
 --------------

+ 6 - 0
src/or/circuituse.c

@@ -1492,6 +1492,12 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
     else
     else
       new_circ_purpose = desired_circuit_purpose;
       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;
       int flags = CIRCLAUNCH_NEED_CAPACITY;
       if (want_onehop) flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
       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"),
   V(TestSocks,                   BOOL,     "0"),
   OBSOLETE("TestVia"),
   OBSOLETE("TestVia"),
   V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
   V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
+  V(Tor2webMode,                 BOOL,     "0"),
   V(TrackHostExits,              CSV,      NULL),
   V(TrackHostExits,              CSV,      NULL),
   V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
   V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
   OBSOLETE("TrafficShaping"),
   OBSOLETE("TrafficShaping"),
@@ -1339,6 +1340,28 @@ options_act(const or_options_t *old_options)
   if (consider_adding_dir_authorities(options, old_options) < 0)
   if (consider_adding_dir_authorities(options, old_options) < 0)
     return -1;
     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) {
   if (options->Bridges) {
     mark_bridge_list();
     mark_bridge_list();
     for (cl = options->Bridges; cl; cl = cl->next) {
     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;
     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) {
   if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
     log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
     log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
              "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
              "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;
       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) {
     if (socks->command == SOCKS_COMMAND_RESOLVE) {
       uint32_t answer;
       uint32_t answer;
       struct in_addr in;
       struct in_addr in;
@@ -2534,7 +2542,9 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
   begin_type = ap_conn->use_begindir ?
   begin_type = ap_conn->use_begindir ?
                  RELAY_COMMAND_BEGIN_DIR : RELAY_COMMAND_BEGIN;
                  RELAY_COMMAND_BEGIN_DIR : RELAY_COMMAND_BEGIN;
   if (begin_type == RELAY_COMMAND_BEGIN) {
   if (begin_type == RELAY_COMMAND_BEGIN) {
+#ifndef NON_ANONYMOUS_MODE_ENABLED
     tor_assert(circ->build_state->onehop_tunnel == 0);
     tor_assert(circ->build_state->onehop_tunnel == 0);
+#endif
   }
   }
 
 
   if (connection_edge_send_command(edge_conn, begin_type,
   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));
   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) &&
   tor_assert(!(is_sensitive_dir_purpose(dir_purpose) &&
                !anonymized_connection));
                !anonymized_connection));
+#else
+  (void)is_sensitive_dir_purpose;
+#endif
 
 
   /* ensure that we don't make direct connections when a SOCKS server is
   /* ensure that we don't make direct connections when a SOCKS server is
    * configured. */
    * configured. */

+ 5 - 0
src/or/main.c

@@ -2285,6 +2285,11 @@ tor_init(int argc, char *argv[])
                  "Expect more bugs than usual.");
                  "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) {
   if (network_init()<0) {
     log_err(LD_BUG,"Error initializing network; exiting.");
     log_err(LD_BUG,"Error initializing network; exiting.");
     return -1;
     return -1;

+ 9 - 0
src/or/or.h

@@ -130,6 +130,10 @@
 #define cell_t tor_cell_t
 #define cell_t tor_cell_t
 #endif
 #endif
 
 
+#ifdef ENABLE_TOR2WEB_MODE
+#define NON_ANONYMOUS_MODE_ENABLED 1
+#endif
+
 /** Length of longest allowable configured nickname. */
 /** Length of longest allowable configured nickname. */
 #define MAX_NICKNAME_LEN 19
 #define MAX_NICKNAME_LEN 19
 /** Length of a router identity encoded as a hexadecimal digest, plus
 /** 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
   int AllDirActionsPrivate; /**< Should every directory action be sent
                              * through a Tor circuit? */
                              * 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; /**< Demanded minimum number of simultaneous connections. */
   int _ConnLimit; /**< Maximum allowed number of simultaneous connections. */
   int _ConnLimit; /**< Maximum allowed number of simultaneous connections. */
   int RunAsDaemon; /**< If true, run in the background. (Unix only) */
   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(rendcirc->rend_data);
   tor_assert(!rend_cmp_service_ids(introcirc->rend_data->onion_address,
   tor_assert(!rend_cmp_service_ids(introcirc->rend_data->onion_address,
                                    rendcirc->rend_data->onion_address));
                                    rendcirc->rend_data->onion_address));
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(introcirc->build_state->onehop_tunnel));
   tor_assert(!(introcirc->build_state->onehop_tunnel));
   tor_assert(!(rendcirc->build_state->onehop_tunnel));
   tor_assert(!(rendcirc->build_state->onehop_tunnel));
+#endif
 
 
   if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
   if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
                               &entry) < 1) {
                               &entry) < 1) {
@@ -331,7 +333,9 @@ rend_client_introduction_acked(origin_circuit_t *circ,
   }
   }
 
 
   tor_assert(circ->build_state->chosen_exit);
   tor_assert(circ->build_state->chosen_exit);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circ->build_state->onehop_tunnel));
   tor_assert(!(circ->build_state->onehop_tunnel));
+#endif
   tor_assert(circ->rend_data);
   tor_assert(circ->rend_data);
 
 
   if (request_len == 0) {
   if (request_len == 0) {
@@ -343,7 +347,9 @@ rend_client_introduction_acked(origin_circuit_t *circ,
     rendcirc = circuit_get_by_rend_query_and_purpose(
     rendcirc = circuit_get_by_rend_query_and_purpose(
                circ->rend_data->onion_address, CIRCUIT_PURPOSE_C_REND_READY);
                circ->rend_data->onion_address, CIRCUIT_PURPOSE_C_REND_READY);
     if (rendcirc) { /* remember the ack */
     if (rendcirc) { /* remember the ack */
+#ifndef NON_ANONYMOUS_MODE_ENABLED
       tor_assert(!(rendcirc->build_state->onehop_tunnel));
       tor_assert(!(rendcirc->build_state->onehop_tunnel));
+#endif
       rendcirc->_base.purpose = CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED;
       rendcirc->_base.purpose = CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED;
       /* Set timestamp_dirty, because circuit_expire_building expects
       /* Set timestamp_dirty, because circuit_expire_building expects
        * it to specify when a circuit entered the
        * 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];
   char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
   time_t now = time(NULL);
   time_t now = time(NULL);
   char descriptor_cookie_base64[3*REND_DESC_COOKIE_LEN_BASE64];
   char descriptor_cookie_base64[3*REND_DESC_COOKIE_LEN_BASE64];
+  int tor2web_mode = get_options()->Tor2webMode;
   tor_assert(desc_id);
   tor_assert(desc_id);
   tor_assert(rend_query);
   tor_assert(rend_query);
   /* Determine responsible dirs. Even if we can't get all we want,
   /* 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,
   directory_initiate_command_routerstatus_rend(hs_dir,
                                           DIR_PURPOSE_FETCH_RENDDESC_V2,
                                           DIR_PURPOSE_FETCH_RENDDESC_V2,
                                           ROUTER_PURPOSE_GENERAL,
                                           ROUTER_PURPOSE_GENERAL,
-                                          1, desc_id_base32, NULL, 0, 0,
+                                          !tor2web_mode, desc_id_base32,
+                                          NULL, 0, 0,
                                           rend_query);
                                           rend_query);
   log_info(LD_REND, "Sending fetch request for v2 descriptor for "
   log_info(LD_REND, "Sending fetch request for v2 descriptor for "
                     "service '%s' with descriptor ID '%s', auth type %d, "
                     "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;
   time_t *access_time;
   const or_options_t *options = get_options();
   const or_options_t *options = get_options();
 
 
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->rend_data);
   tor_assert(circuit->rend_data);
 
 
   base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
   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;
   crypto_pk_env_t *intro_key;
 
 
   tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
   tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->cpath);
   tor_assert(circuit->cpath);
   tor_assert(circuit->rend_data);
   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->_base.purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
   tor_assert(circuit->cpath);
   tor_assert(circuit->cpath);
   tor_assert(circuit->build_state);
   tor_assert(circuit->build_state);
+#ifndef NON_ANONYMOUS_MODE_ENABLED
   tor_assert(!(circuit->build_state->onehop_tunnel));
   tor_assert(!(circuit->build_state->onehop_tunnel));
+#endif
   tor_assert(circuit->rend_data);
   tor_assert(circuit->rend_data);
   hop = circuit->build_state->pending_final_cpath;
   hop = circuit->build_state->pending_final_cpath;
   tor_assert(hop);
   tor_assert(hop);