From b2212bf9b4e7f06d7383eb9235392cbdf735bbdb Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 1 Jun 2011 07:03:01 -0700 Subject: [PATCH 01/11] Add Tor2webMode configuration option --- doc/tor.1.txt | 4 ++++ src/or/config.c | 1 + src/or/or.h | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/doc/tor.1.txt b/doc/tor.1.txt index f5be391052..22c8e88062 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -957,6 +957,10 @@ 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. (Default: 0) SERVER OPTIONS -------------- diff --git a/src/or/config.c b/src/or/config.c index 06d7d5c022..b2de15e7f0 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -394,6 +394,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"), diff --git a/src/or/or.h b/src/or/or.h index 67ba62bdd6..8515db6673 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3008,6 +3008,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) */ From 543a36a55ba04e860582e6db53d17e49814ebb81 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 23 Nov 2011 16:58:15 -0800 Subject: [PATCH 02/11] Add a compile-time #define to control whether Tor runs in 'tor2web mode' The Tor2webMode torrc option is still required to run a Tor client in 'tor2web mode', but now it can't be turned on at runtime in a normal build of Tor. (And a tor2web build of Tor can't be used as a normal Tor client, so we don't have to worry as much about someone distributing packages with this particular pistol accessible to normal users.) --- src/or/config.c | 16 ++++++++++++++++ src/or/or.h | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/src/or/config.c b/src/or/config.c index b2de15e7f0..bddae6fc22 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1294,6 +1294,22 @@ options_act(const or_options_t *old_options) if (consider_adding_dir_authorities(options, old_options) < 0) return -1; +#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."); + return -1; + } +#endif + if (options->Bridges) { mark_bridge_list(); for (cl = options->Bridges; cl; cl = cl->next) { diff --git a/src/or/or.h b/src/or/or.h index 8515db6673..8117ee1f86 100644 --- a/src/or/or.h +++ b/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 From 5f3e6eb0b9b450c81bd54d5dd87ff786a6d1ffea Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 23 Nov 2011 16:46:38 -0800 Subject: [PATCH 03/11] Warn loudly on startup and SIGHUP if Tor is built for a non-anonymous mode --- src/or/config.c | 5 +++++ src/or/main.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/or/config.c b/src/or/config.c index bddae6fc22..734efdf74e 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1294,6 +1294,11 @@ 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 " diff --git a/src/or/main.c b/src/or/main.c index 7008d388a1..266356a966 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2256,6 +2256,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; From ebf524b48b0340ed3b2bfc1d652e3d65b3aee11c Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Tue, 31 May 2011 07:05:40 -0700 Subject: [PATCH 04/11] Don't allow tor2web-mode Tors to connect to non-HS addresses The client's anonymity when accessing a non-HS address in tor2web-mode would be easily nuked by inserting an inline image with a .onion URL, so don't even pretend to access non-HS addresses through Tor. --- src/or/connection_edge.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index efaad79b6a..bba666d3b9 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1892,6 +1892,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; From 29287ed0edf925fd9e05d5fbed53eb37bc8799c7 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 1 Jun 2011 01:45:24 -0700 Subject: [PATCH 05/11] Perform single-hop HS desc fetches when in tor2web mode --- src/or/rendclient.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 6a45207e29..fae9df0d52 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -529,6 +529,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 +588,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, " From 826f1d5b0ab1faa0c75d2fd6560b4983adec33c8 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 1 Jun 2011 02:00:59 -0700 Subject: [PATCH 06/11] Use single-hop intro and rend circuits when in tor2web mode --- src/or/circuituse.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 23efe05348..f9931d88d6 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1489,6 +1489,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; From a364f88477105075a202e55b2e44dafa4bf2be51 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 23 Nov 2011 14:07:46 -0800 Subject: [PATCH 07/11] Add ifdefs to disable #3332 assertions --- src/or/directory.c | 4 ++++ src/or/rendclient.c | 6 ++++++ src/or/rendservice.c | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/src/or/directory.c b/src/or/directory.c index 776b7a25f9..073b88717a 100644 --- a/src/or/directory.c +++ b/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. */ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index fae9df0d52..e7ef313abe 100644 --- a/src/or/rendclient.c +++ b/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 diff --git a/src/or/rendservice.c b/src/or/rendservice.c index e0c1a8c87a..34d255ac1f 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -910,7 +910,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, @@ -1394,7 +1396,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); @@ -1550,7 +1554,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); From 328c9582a90f65c5f21d05f2de889bc2286dc0ff Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 23 Nov 2011 14:10:46 -0800 Subject: [PATCH 08/11] Add ifdefs to disable assertion in connection_ap_handshake_send_begin --- src/or/connection_edge.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index bba666d3b9..dc15721b6c 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2461,7 +2461,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, From c90c33fd53463b67810b4e2b4c994e952e087698 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Tue, 14 Jun 2011 01:40:02 -0700 Subject: [PATCH 09/11] Turn off LearnCircuitBuildTimeout when tor2web mode is on --- src/or/config.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/or/config.c b/src/or/config.c index 734efdf74e..1dd5ed72c4 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -3524,6 +3524,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); From 6db69d9d612462489600df641b91e6ae49dfd382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20Filast=C3=B2?= Date: Thu, 24 Nov 2011 07:53:04 +0100 Subject: [PATCH 10/11] Add support for tor2web mode via configure --- configure.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configure.in b/configure.in index 64d9d6db7b..b723f610f7 100644 --- a/configure.in +++ b/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.)) From db648fe886fd8ae4f42bb13d0219ca7fa690bdc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20Filast=C3=B2?= Date: Thu, 24 Nov 2011 10:28:38 +0100 Subject: [PATCH 11/11] Add some more documentation --- doc/tor.1.txt | 5 ++++- src/or/config.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 22c8e88062..c73b8d326e 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -960,7 +960,10 @@ The following options are useful only for clients (that is, if **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. (Default: 0) + 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 -------------- diff --git a/src/or/config.c b/src/or/config.c index 1dd5ed72c4..adfde8138a 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1310,7 +1310,8 @@ options_act(const or_options_t *old_options) 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."); + "option enabled. To enable Tor2webMode recompile with the " + "--enable-tor2webmode option."); return -1; } #endif