Commit b560f852 authored by teor (Tim Wilson-Brown)'s avatar teor (Tim Wilson-Brown) Committed by Nick Mathewson
Browse files

Implement Prop #260: Single Onion Services

Add experimental OnionServiceSingleHopMode and
OnionServiceNonAnonymousMode options. When both are set to 1, every
hidden service on a tor instance becomes a non-anonymous Single Onion
Service. Single Onions make one-hop (direct) connections to their
introduction and renzedvous points. One-hop circuits make Single Onion
servers easily locatable, but clients remain location-anonymous.
This is compatible with the existing hidden service implementation, and
works on the current tor network without any changes to older relays or
clients.

Implements proposal #260, completes ticket #17178. Patch by teor & asn.

squash! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! Implement Prop #260: Single Onion Services

Redesign single onion service poisoning.

When in OnionServiceSingleHopMode, each hidden service key is poisoned
(marked as non-anonymous) on creation by creating a poison file in the
hidden service directory.

Existing keys are considered non-anonymous if this file exists, and
anonymous if it does not.

Tor refuses to launch in OnionServiceSingleHopMode if any existing keys
are anonymous. Similarly, it refuses to launch in anonymous client mode
if any existing keys are non-anonymous.

Rewrite the unit tests to match and be more comprehensive.
Adds a bonus unit test for rend_service_load_all_keys().
parent b494ccc3
o Major features (onion services):
- Add experimental OnionServiceSingleHopMode and
OnionServiceNonAnonymousMode options. When both are set to 1, every
hidden service on a tor instance becomes a non-anonymous Single Onion
Service. Single Onions make one-hop (direct) connections to their
introduction and renzedvous points. One-hop circuits make Single Onion
servers easily locatable, but clients remain location-anonymous.
This is compatible with the existing hidden service implementation, and
works on the current tor network without any changes to older relays or
clients.
Implements proposal #260, completes ticket #17178. Patch by teor & asn.
o Minor bug fixes (Tor2web):
- Prevent Tor2web clients running hidden services, these services are
not anonymous due to the one-hop client paths.
Fixes bug #19678. Patch by teor.
......@@ -1425,7 +1425,9 @@ The following options are useful only for clients (that is, if
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-tor2web-mode must be
specified. (Default: 0)
specified. Since Tor2webMode is non-anonymous, you can not run an
anonymous Hidden Service on a tor version compiled with Tor2webMode.
(Default: 0)
[[Tor2webRendezvousPoints]] **Tor2webRendezvousPoints** __node__,__node__,__...__::
A list of identity fingerprints, nicknames, country codes and
......@@ -2375,6 +2377,37 @@ The following options are used to configure a hidden service.
Number of introduction points the hidden service will have. You can't
have more than 10. (Default: 3)
[[OnionServiceSingleHopMode]] **OnionServiceSingleHopMode** **0**|**1**::
**Experimental - Non Anonymous** Hidden Services on a tor instance in
OnionServiceSingleHopMode make one-hop (direct) circuits between the onion
service server, and the introduction and rendezvous points. (Onion service
descriptors are still posted using 3-hop paths, to avoid onion service
directories blocking the service.)
This option makes every hidden service instance hosted by a tor instance a
Single Onion Service. One-hop circuits make Single Onion servers easily
locatable, but clients remain location-anonymous. However, the fact that a
client is accessing a Single Onion rather than a Hidden Service may be
statistically distinguishable.
**WARNING:** Once a hidden service directory has been used by a tor
instance in OnionServiceSingleHopMode, it can **NEVER** be used again for
a hidden service. It is best practice to create a new hidden service
directory, key, and address for each new Single Onion Service and Hidden
Service. It is not possible to run Single Onion Services and Hidden
Services from the same tor instance: they should be run on different
servers with different IP addresses.
OnionServiceSingleHopMode requires OnionServiceNonAnonymousMode to be set
to 1. Since a Single Onion is non-anonymous, you can not to run an
anonymous SOCKSPort on the same tor instance as a Single Onion service.
(Default: 0)
[[OnionServiceNonAnonymousMode]] **OnionServiceNonAnonymousMode** **0**|**1**::
Makes hidden services non-anonymous on this tor instance. Allows the
non-anonymous OnionServiceSingleHopMode. Enables direct connections in the
server-side hidden service protocol.
(Default: 0)
TESTING NETWORK OPTIONS
-----------------------
......
......@@ -28,6 +28,7 @@
#include "connection_edge.h"
#include "connection_or.h"
#include "control.h"
#include "crypto.h"
#include "directory.h"
#include "entrynodes.h"
#include "main.h"
......@@ -38,14 +39,14 @@
#include "onion_tap.h"
#include "onion_fast.h"
#include "policies.h"
#include "transports.h"
#include "relay.h"
#include "rendcommon.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
#include "crypto.h"
#include "transports.h"
static channel_t * channel_connect_for_circuit(const tor_addr_t *addr,
uint16_t port,
......@@ -1996,7 +1997,9 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei)
cpath_build_state_t *state = circ->build_state;
if (state->onehop_tunnel) {
log_debug(LD_CIRC, "Launching a one-hop circuit for dir tunnel.");
log_debug(LD_CIRC, "Launching a one-hop circuit for dir tunnel%s.",
(rend_allow_non_anonymous_connection(get_options()) ?
", or intro or rendezvous connection" : ""));
state->desired_path_len = 1;
} else {
int r = new_route_len(circ->base_.purpose, exit_ei, nodelist_get_list());
......
......@@ -21,6 +21,8 @@
#include "control.h"
#include "main.h"
#include "networkstatus.h"
#include "rendclient.h"
#include "rendservice.h"
#include "statefile.h"
#undef log
......@@ -81,12 +83,14 @@ get_circuit_build_timeout_ms(void)
/**
* This function decides if CBT learning should be disabled. It returns
* true if one or more of the following four conditions are met:
* true if one or more of the following conditions are met:
*
* 1. If the cbtdisabled consensus parameter is set.
* 2. If the torrc option LearnCircuitBuildTimeout is false.
* 3. If we are a directory authority
* 4. If we fail to write circuit build time history to our state file.
* 5. If we are compiled or configured in Tor2web mode
* 6. If we are configured in Single Onion mode
*/
int
circuit_build_times_disabled(void)
......@@ -94,14 +98,30 @@ circuit_build_times_disabled(void)
if (unit_tests) {
return 0;
} else {
const or_options_t *options = get_options();
int consensus_disabled = networkstatus_get_param(NULL, "cbtdisabled",
0, 0, 1);
int config_disabled = !get_options()->LearnCircuitBuildTimeout;
int dirauth_disabled = get_options()->AuthoritativeDir;
int config_disabled = !options->LearnCircuitBuildTimeout;
int dirauth_disabled = options->AuthoritativeDir;
int state_disabled = did_last_state_file_write_fail() ? 1 : 0;
/* LearnCircuitBuildTimeout and Tor2webMode/OnionServiceSingleHopMode are
* incompatible in two ways:
*
* - LearnCircuitBuildTimeout results in a low CBT, which
* Single Onion use of one-hop intro and 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
* these modes with LearnCircuitBuildTimeout on again. */
int tor2web_disabled = rend_client_allow_non_anonymous_connection(options);
int single_onion_disabled = rend_service_allow_non_anonymous_connection(
options);
if (consensus_disabled || config_disabled || dirauth_disabled ||
state_disabled) {
state_disabled || tor2web_disabled || single_onion_disabled) {
#if 0
log_debug(LD_CIRC,
"CircuitBuildTime learning is disabled. "
......
......@@ -18,6 +18,7 @@
#include "circuitlist.h"
#include "circuitmux.h"
#include "circuitmux_ewma.h"
#include "circuitstats.h"
#include "config.h"
#include "connection.h"
#include "connection_edge.h"
......@@ -297,6 +298,8 @@ static config_var_t option_vars_[] = {
V(HidServAuth, LINELIST, NULL),
V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"),
V(CloseHSServiceRendCircuitsImmediatelyOnTimeout, BOOL, "0"),
V(OnionServiceSingleHopMode, BOOL, "0"),
V(OnionServiceNonAnonymousMode,BOOL, "0"),
V(HTTPProxy, STRING, NULL),
V(HTTPProxyAuthenticator, STRING, NULL),
V(HTTPSProxy, STRING, NULL),
......@@ -1558,10 +1561,10 @@ options_act(const or_options_t *old_options)
if (consider_adding_dir_servers(options, old_options) < 0)
return -1;
#ifdef NON_ANONYMOUS_MODE_ENABLED
log_warn(LD_GENERAL, "This copy of Tor was compiled to run in a "
"non-anonymous mode. It will provide NO ANONYMITY.");
#endif
if (rend_non_anonymous_mode_enabled(options)) {
log_warn(LD_GENERAL, "This copy of Tor was compiled or configured to run "
"in a non-anonymous mode. It will provide NO ANONYMITY.");
}
#ifdef ENABLE_TOR2WEB_MODE
/* LCOV_EXCL_START */
......@@ -1723,8 +1726,27 @@ options_act(const or_options_t *old_options)
monitor_owning_controller_process(options->OwningControllerProcess);
/* We must create new keys after we poison the directories, because our
* poisoning code checks for existing keys, and refuses to modify their
* directories. */
/* If we use the insecure OnionServiceSingleHopMode, make sure we poison any
new hidden service directories, so that we never accidentally launch the
non-anonymous hidden services thinking they are anonymous. */
if (running_tor && rend_service_allow_non_anonymous_connection(options)) {
if (options->RendConfigLines && !num_rend_services()) {
log_warn(LD_BUG,"Error: hidden services configured, but not parsed.");
return -1;
}
if (rend_service_poison_new_single_onion_dirs(NULL) < 0) {
log_warn(LD_GENERAL,"Failed to mark new hidden services as Single "
"Onion.");
return -1;
}
}
/* reload keys as needed for rendezvous services. */
if (rend_service_load_all_keys()<0) {
if (rend_service_load_all_keys(NULL)<0) {
log_warn(LD_GENERAL,"Error loading rendezvous service keys");
return -1;
}
......@@ -2796,6 +2818,88 @@ warn_about_relative_paths(or_options_t *options)
}
}
/* Validate options related to OnionServiceSingleHopMode.
* Modifies some options that are incompatible with OnionServiceSingleHopMode.
* On failure returns -1, and sets *msg to an error string.
* Returns 0 on success. */
STATIC int
options_validate_single_onion(or_options_t *options, char **msg)
{
/* You must set OnionServiceNonAnonymousMode to 1 to use
* OnionServiceSingleHopMode */
if (options->OnionServiceSingleHopMode &&
!rend_service_non_anonymous_mode_enabled(options)) {
REJECT("OnionServiceSingleHopMode does not provide any server anonymity. "
"It must be used with OnionServiceNonAnonymousMode set to 1.");
}
/* If you have OnionServiceNonAnonymousMode set, you must use
* OnionServiceSingleHopMode. */
if (rend_service_non_anonymous_mode_enabled(options) &&
!options->OnionServiceSingleHopMode) {
REJECT("OnionServiceNonAnonymousMode does not provide any server "
"anonymity. It must be used with OnionServiceSingleHopMode set to "
"1.");
}
/* If you run an anonymous client with an active Single Onion service, the
* client loses anonymity. */
const int client_port_set = (options->SocksPort_set ||
options->TransPort_set ||
options->NATDPort_set ||
options->DNSPort_set);
if (options->OnionServiceSingleHopMode && client_port_set &&
!options->Tor2webMode) {
REJECT("OnionServiceSingleHopMode is incompatible with using Tor as an "
"anonymous client. Please set Socks/Trans/NATD/DNSPort to 0, or "
"OnionServiceSingleHopMode to 0, or use the non-anonymous "
"Tor2webMode.");
}
/* If you run a hidden service in non-anonymous mode, the hidden service
* loses anonymity, even if SOCKSPort / Tor2web mode isn't used. */
if (!options->OnionServiceSingleHopMode && options->RendConfigLines
&& options->Tor2webMode) {
REJECT("Non-anonymous (Tor2web) mode is incompatible with using Tor as a "
"hidden service. Please remove all HiddenServiceDir lines, or use "
"a version of tor compiled without --enable-tor2web-mode, or use "
"the non-anonymous OnionServiceSingleHopMode.");
}
if (options->OnionServiceSingleHopMode
&& options->UseEntryGuards) {
/* Single Onion services do not (and should not) use entry guards
* in any meaningful way. Further, Single Onions causes the hidden
* service code to do things which break the path bias
* detector, and it's far easier to turn off entry guards (and
* thus the path bias detector with it) than to figure out how to
* make a piece of code which cannot possibly help Single Onions,
* compatible with OnionServiceSingleHopMode.
*/
log_notice(LD_CONFIG,
"OnionServiceSingleHopMode is enabled; disabling "
"UseEntryGuards.");
options->UseEntryGuards = 0;
}
/* Check if existing hidden service keys were created with a different
* setting of OnionServiceNonAnonymousMode, and refuse to launch if they
* have. We'll poison new keys in options_act() just before we create them.
*/
if (rend_service_list_verify_single_onion_poison(NULL, options) < 0) {
log_warn(LD_GENERAL, "We are configured with OnionServiceSingleHopMode "
"%d, but one or more hidden service keys were created in %s "
"mode. This is not allowed.",
rend_service_non_anonymous_mode_enabled(options) ? 1 : 0,
rend_service_non_anonymous_mode_enabled(options) ?
"an anonymous" : "a non-anonymous"
);
return -1;
}
return 0;
}
/** Return 0 if every setting in <b>options</b> is reasonable, is a
* permissible transition from <b>old_options</b>, and none of the
* testing-only settings differ from <b>default_options</b> unless in
......@@ -3291,25 +3395,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
options->PredictedPortsRelevanceTime = MAX_PREDICTED_CIRCS_RELEVANCE;
}
#ifdef ENABLE_TOR2WEB_MODE
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;
}
/* Check the Single Onion Service options */
if (options_validate_single_onion(options, msg) < 0)
return -1;
#ifdef ENABLE_TOR2WEB_MODE
if (options->Tor2webMode && options->UseEntryGuards) {
/* tor2web mode clients do not (and should not) use entry guards
* in any meaningful way. Further, tor2web mode causes the hidden
......@@ -3353,6 +3443,17 @@ options_validate(or_options_t *old_options, or_options_t *options,
return -1;
}
/* OnionServiceSingleHopMode: one hop between the onion service server and
* intro and rendezvous points */
if (options->OnionServiceSingleHopMode) {
log_warn(LD_CONFIG,
"OnionServiceSingleHopMode is set. Every hidden service on this "
"tor instance is NON-ANONYMOUS. If OnionServiceSingleHopMode is "
"disabled, Tor will refuse to launch hidden services from the "
"same directories, to protect against config errors. This "
"setting is for experimental use only.");
}
if (!options->LearnCircuitBuildTimeout && options->CircuitBuildTimeout &&
options->CircuitBuildTimeout < RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT) {
log_warn(LD_CONFIG,
......@@ -4295,6 +4396,19 @@ options_transition_allowed(const or_options_t *old,
return -1;
}
if (old->OnionServiceSingleHopMode != new_val->OnionServiceSingleHopMode) {
*msg = tor_strdup("While Tor is running, changing "
"OnionServiceSingleHopMode is not allowed.");
return -1;
}
if (old->OnionServiceNonAnonymousMode !=
new_val->OnionServiceNonAnonymousMode) {
*msg = tor_strdup("While Tor is running, changing "
"OnionServiceNonAnonymousMode is not allowed.");
return -1;
}
if (old->DisableDebuggerAttachment &&
!new_val->DisableDebuggerAttachment) {
*msg = tor_strdup("While Tor is running, disabling "
......
......@@ -166,6 +166,8 @@ extern struct config_format_t options_format;
STATIC port_cfg_t *port_cfg_new(size_t namelen);
STATIC void port_cfg_free(port_cfg_t *port);
STATIC void or_options_free(or_options_t *options);
STATIC int options_validate_single_onion(or_options_t *options,
char **msg);
STATIC int options_validate(or_options_t *old_options,
or_options_t *options,
or_options_t *default_options,
......
......@@ -27,6 +27,7 @@
#include "control.h"
#include "dns.h"
#include "dnsserv.h"
#include "directory.h"
#include "dirserv.h"
#include "hibernate.h"
#include "main.h"
......@@ -2271,6 +2272,7 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
char payload[CELL_PAYLOAD_SIZE];
int payload_len;
int begin_type;
const or_options_t *options = get_options();
origin_circuit_t *circ;
edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(ap_conn);
connection_t *base_conn = TO_CONN(edge_conn);
......@@ -2314,10 +2316,31 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
begin_type = ap_conn->use_begindir ?
RELAY_COMMAND_BEGIN_DIR : RELAY_COMMAND_BEGIN;
/* Check that circuits are anonymised, based on their type. */
if (begin_type == RELAY_COMMAND_BEGIN) {
#ifndef NON_ANONYMOUS_MODE_ENABLED
tor_assert(circ->build_state->onehop_tunnel == 0);
#endif
/* This connection is a standard OR connection.
* Make sure its path length is anonymous, or that we're in a
* non-anonymous mode. */
assert_circ_anonymity_ok(circ, options);
} else if (begin_type == RELAY_COMMAND_BEGIN_DIR) {
/* This connection is a begindir directory connection.
* Look at the linked directory connection to access the directory purpose.
* (This must be non-NULL, because we're doing begindir.) */
tor_assert(base_conn->linked);
connection_t *linked_dir_conn_base = base_conn->linked_conn;
tor_assert(linked_dir_conn_base);
/* Sensitive directory connections must have an anonymous path length.
* Otherwise, directory connections are typically one-hop.
* This matches the earlier check for directory connection path anonymity
* in directory_initiate_command_rend(). */
if (is_sensitive_dir_purpose(linked_dir_conn_base->purpose)) {
assert_circ_anonymity_ok(circ, options);
}
} else {
/* This code was written for the two connection types BEGIN and BEGIN_DIR
*/
tor_assert_unreached();
}
if (connection_edge_send_command(edge_conn, begin_type,
......
......@@ -1085,7 +1085,7 @@ directory_initiate_command(const tor_addr_t *or_addr, uint16_t or_port,
* <b>dir_purpose</b> reveals sensitive information about a Tor
* instance's client activities. (Such connections must be performed
* through normal three-hop Tor circuits.) */
static int
int
is_sensitive_dir_purpose(uint8_t dir_purpose)
{
return ((dir_purpose == DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2) ||
......@@ -1140,12 +1140,10 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port,
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
if (is_sensitive_dir_purpose(dir_purpose)) {
tor_assert(anonymized_connection ||
rend_non_anonymous_mode_enabled(options));
}
/* use encrypted begindir connections for everything except relays
* this provides better protection for directory fetches */
......
......@@ -132,7 +132,10 @@ int download_status_get_n_failures(const download_status_t *dls);
int download_status_get_n_attempts(const download_status_t *dls);
time_t download_status_get_next_attempt_at(const download_status_t *dls);
/* Yes, these two functions are confusingly similar.
* Let's sort that out in #20077. */
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose);
int is_sensitive_dir_purpose(uint8_t dir_purpose);
#ifdef TOR_UNIT_TESTS
/* Used only by directory.c and test_dir.c */
......
......@@ -2833,11 +2833,6 @@ tor_init(int argc, char *argv[])
"Expect more bugs than usual.");
}
#ifdef NON_ANONYMOUS_MODE_ENABLED
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;
......@@ -2849,6 +2844,14 @@ tor_init(int argc, char *argv[])
return -1;
}
/* The options are now initialised */
const or_options_t *options = get_options();
if (rend_non_anonymous_mode_enabled(options)) {
log_warn(LD_GENERAL, "This copy of Tor was compiled or configured to run "
"in a non-anonymous mode. It will provide NO ANONYMITY.");
}
#ifndef _WIN32
if (geteuid()==0)
log_warn(LD_GENERAL,"You are running Tor as root. You don't need to, "
......
......@@ -3701,6 +3701,27 @@ typedef struct {
* they reach the normal circuit-build timeout. */
int CloseHSServiceRendCircuitsImmediatelyOnTimeout;
/** Onion Services in OnionServiceSingleHopMode make one-hop (direct)
* circuits between the onion service server, and the introduction and
* rendezvous points. (Onion service descriptors are still posted using
* 3-hop paths, to avoid onion service directories blocking the service.)
* This option makes every hidden service instance hosted by
* this tor instance a Single Onion Service. One-hop circuits make Single
* Onion servers easily locatable, but clients remain location-anonymous.
* OnionServiceSingleHopMode requires OnionServiceNonAnonymousMode to be set
* to 1.
* Use rend_service_allow_non_anonymous_connection() or
* rend_service_reveal_startup_time() instead of using this option directly.
*/
int OnionServiceSingleHopMode;
/* Makes hidden service clients and servers non-anonymous on this tor
* instance. Allows the non-anonymous OnionServiceSingleHopMode. Enables
* direct connections in the hidden service protocol.
* Use rend_service_non_anonymous_mode() instead of using this option
* directly.
*/
int OnionServiceNonAnonymousMode;
int ConnLimit; /**< Demanded minimum number of simultaneous connections. */
int ConnLimit_; /**< Maximum allowed number of simultaneous connections. */
int ConnLimit_high_thresh; /**< start trying to lower socket usage if we
......
......@@ -134,6 +134,7 @@ int
rend_client_send_introduction(origin_circuit_t *introcirc,
origin_circuit_t *rendcirc)
{
const or_options_t *options = get_options();
size_t payload_len;
int r, v3_shift = 0;
char payload[RELAY_PAYLOAD_SIZE];
......@@ -150,10 +151,8 @@ 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
assert_circ_anonymity_ok(introcirc, options);
assert_circ_anonymity_ok(rendcirc, options);
r = rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
&entry);
......@@ -387,6 +386,7 @@ int
rend_client_introduction_acked(origin_circuit_t *circ,
const uint8_t *request, size_t request_len)
{
const or_options_t *options = get_options();
origin_circuit_t *rendcirc;
(void) request; // XXXX Use this.
......@@ -398,10 +398,9 @@ rend_client_introduction_acked(origin_circuit_t *circ,
return -1;
}
tor_assert(circ->build_state);
tor_assert(circ->build_state->chosen_exit);
#ifndef NON_ANONYMOUS_MODE_ENABLED
tor_assert(!(circ->build_state->onehop_tunnel));
#endif
assert_circ_anonymity_ok(circ, options);
tor_assert(circ->rend_data);
/* For path bias: This circuit was used successfully. Valid
......@@ -416,9 +415,7 @@ rend_client_introduction_acked(origin_circuit_t *circ,
log_info(LD_REND,"Received ack. Telling rend circ...");
rendcirc = circuit_get_ready_rend_circ_by_rend_data(circ->rend_data);
if (rendcirc) { /* remember the ack */
#ifndef NON_ANONYMOUS_MODE_ENABLED
tor_assert(!(rendcirc->build_state->onehop_tunnel));
#endif
assert_circ_anonymity_ok(rendcirc, options);
circuit_change_purpose(TO_CIRCUIT(rendcirc),
CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
/* Set timestamp_dirty, because circuit_expire_building expects
......@@ -1552,3 +1549,35 @@ rend_parse_service_authorization(const or_options_t *options,
return res;
}
/* Can Tor client code make direct (non-anonymous) connections to introduction
* or rendezvous points?
* Returns true if tor was compiled with NON_ANONYMOUS_MODE_ENABLED, and is
* configured in Tor2web mode. */
int
rend_client_allow_non_anonymous_connection(const or_options_t *options)
{
/* Tor2web support needs to be compiled in to a tor binary. */
#ifdef NON_ANONYMOUS_MODE_ENABLED
/* Tor2web */
return options->Tor2webMode ? 1 : 0;
#else
(void)options;
return 0;
#endif
}
/* At compile-time, was non-anonymous mode enabled via
* NON_ANONYMOUS_MODE_ENABLED ? */
int
rend_client_non_anonymous_mode_enabled(const or_options_t *options)
{
(void)options;
/* Tor2web support needs to be compiled in to a tor binary. */
#ifdef NON_ANONYMOUS_MODE_ENABLED
/* Tor2web */
return 1;
#else
return 0;
#endif
}
......@@ -51,5 +51,8 @@ rend_service_authorization_t *rend_client_lookup_service_authorization(
const char *onion_address);
void rend_service_authorization_free_all(void);
int rend_client_allow_non_anonymous_connection(const or_options_t *options);
int rend_client_non_anonymous_mode_enabled(const or_options_t *options);
#endif
......@@ -1067,3 +1067,51 @@ rend_auth_decode_cookie(const char *cookie_in, uint8_t *cookie_out,