aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app/config/config.c3
-rw-r--r--src/app/config/or_options_st.h3
-rw-r--r--src/app/main/shutdown.c2
-rw-r--r--src/core/mainloop/connection.c1
-rw-r--r--src/core/or/circuitlist.c2
-rw-r--r--src/core/or/circuitstats.c1
-rw-r--r--src/core/or/circuituse.c7
-rw-r--r--src/core/or/connection_edge.c82
-rw-r--r--src/core/or/connection_edge.h1
-rw-r--r--src/core/or/crypt_path.c4
-rw-r--r--src/feature/control/control_cmd.c5
-rw-r--r--src/feature/control/control_getinfo.c30
-rw-r--r--src/feature/dirclient/dirclient.c13
-rw-r--r--src/feature/dircommon/directory.c1
-rw-r--r--src/feature/hs/hs_circuit.c5
-rw-r--r--src/feature/hs/hs_client.c32
-rw-r--r--src/feature/hs/hs_common.c5
-rw-r--r--src/feature/hs/hs_config.c6
-rw-r--r--src/feature/rend/include.am2
-rw-r--r--src/feature/rend/rendclient.c1322
-rw-r--r--src/feature/rend/rendclient.h54
-rw-r--r--src/feature/rend/rendcommon.c2
-rw-r--r--src/feature/rend/rendservice.c1
-rw-r--r--src/test/test_config.c1
-rw-r--r--src/test/test_entryconn.c41
-rw-r--r--src/test/test_hs_common.c15
-rw-r--r--src/test/test_options.c8
27 files changed, 26 insertions, 1623 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 1e4d18116c..dec4890e70 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -103,7 +103,7 @@
#include "feature/relay/routermode.h"
#include "feature/relay/relay_config.h"
#include "feature/relay/transport_config.h"
-#include "feature/rend/rendclient.h"
+#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "lib/geoip/geoip.h"
#include "feature/stats/geoip_stats.h"
@@ -504,7 +504,6 @@ static const config_var_t option_vars_[] = {
VAR("HiddenServiceOnionBalanceInstance",
LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceStatistics", BOOL, HiddenServiceStatistics_option, "1"),
- V(HidServAuth, LINELIST, NULL),
V(ClientOnionAuthDir, FILENAME, NULL),
OBSOLETE("CloseHSClientCircuitsImmediatelyOnTimeout"),
OBSOLETE("CloseHSServiceRendCircuitsImmediatelyOnTimeout"),
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 714034b28d..f9c6dae2b6 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -428,9 +428,6 @@ struct or_options_t {
int NumCPUs; /**< How many CPUs should we try to use? */
struct config_line_t *RendConfigLines; /**< List of configuration lines
* for rendezvous services. */
- struct config_line_t *HidServAuth; /**< List of configuration lines for
- * client-side authorizations for hidden
- * services */
char *ClientOnionAuthDir; /**< Directory to keep client
* onion service authorization secret keys */
char *ContactInfo; /**< Contact info to be published in the directory. */
diff --git a/src/app/main/shutdown.c b/src/app/main/shutdown.c
index 4a556333db..fe80a92991 100644
--- a/src/app/main/shutdown.c
+++ b/src/app/main/shutdown.c
@@ -46,7 +46,6 @@
#include "feature/relay/ext_orport.h"
#include "feature/relay/relay_config.h"
#include "feature/rend/rendcache.h"
-#include "feature/rend/rendclient.h"
#include "feature/stats/bwhist.h"
#include "feature/stats/geoip_stats.h"
#include "feature/stats/rephist.h"
@@ -120,7 +119,6 @@ tor_free_all(int postfork)
addressmap_free_all();
dirserv_free_all();
rend_cache_free_all();
- rend_service_authorization_free_all();
rep_hist_free_all();
bwhist_free_all();
circuit_free_all();
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index f90872ec22..376994f1c1 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -106,7 +106,6 @@
#include "feature/relay/dns.h"
#include "feature/relay/ext_orport.h"
#include "feature/relay/routermode.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/stats/connstats.h"
#include "feature/stats/rephist.h"
diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c
index bd36683880..f6d9fcf534 100644
--- a/src/core/or/circuitlist.c
+++ b/src/core/or/circuitlist.c
@@ -88,7 +88,7 @@
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "core/crypto/relay_crypto.h"
-#include "feature/rend/rendclient.h"
+#include "feature/rend/rendcache.h"
#include "feature/rend/rendcommon.h"
#include "feature/stats/predict_ports.h"
#include "feature/stats/bwhist.h"
diff --git a/src/core/or/circuitstats.c b/src/core/or/circuitstats.c
index b7f5216d72..7f3b5007b3 100644
--- a/src/core/or/circuitstats.c
+++ b/src/core/or/circuitstats.c
@@ -34,7 +34,6 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"
#include "feature/relay/router.h"
#include "app/config/statefile.h"
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
index 11ba059b0e..26c4711a5b 100644
--- a/src/core/or/circuituse.c
+++ b/src/core/or/circuituse.c
@@ -58,7 +58,6 @@
#include "feature/nodelist/routerlist.h"
#include "feature/relay/routermode.h"
#include "feature/relay/selftest.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "feature/stats/predict_ports.h"
@@ -2448,11 +2447,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
extend_info = hs_client_get_random_intro_from_edge(edge_conn);
if (!extend_info) {
log_info(LD_REND, "No intro points: re-fetching service descriptor.");
- if (edge_conn->rend_data) {
- rend_client_refetch_v2_renddesc(edge_conn->rend_data);
- } else {
- hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
- }
+ hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
connection_ap_mark_as_waiting_for_renddesc(conn);
return 0;
}
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index aa48d16b7c..37cc24672e 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -96,7 +96,6 @@
#include "feature/relay/dns.h"
#include "feature/relay/router.h"
#include "feature/relay/routermode.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "feature/stats/predict_ports.h"
@@ -251,24 +250,9 @@ connection_mark_unattached_ap_,(entry_connection_t *conn, int endreason,
int line, const char *file))
{
connection_t *base_conn = ENTRY_TO_CONN(conn);
- edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
tor_assert(base_conn->type == CONN_TYPE_AP);
ENTRY_TO_EDGE_CONN(conn)->edge_has_sent_end = 1; /* no circ yet */
- /* If this is a rendezvous stream and it is failing without ever
- * being attached to a circuit, assume that an attempt to connect to
- * the destination hidden service has just ended.
- *
- * XXXX This condition doesn't limit to only streams failing
- * without ever being attached. That sloppiness should be harmless,
- * but we should fix it someday anyway. */
- if ((edge_conn->on_circuit != NULL || edge_conn->edge_has_sent_end) &&
- connection_edge_is_rendezvous_stream(edge_conn)) {
- if (edge_conn->rend_data) {
- rend_client_note_connection_attempt_ended(edge_conn->rend_data);
- }
- }
-
if (base_conn->marked_for_close) {
/* This call will warn as appropriate. */
connection_mark_for_close_(base_conn, line, file);
@@ -1636,12 +1620,12 @@ consider_plaintext_ports(entry_connection_t *conn, uint16_t port)
* The possible recognized forms are (where true is returned):
*
* If address is of the form "y.onion" with a well-formed handle y:
- * Put a NUL after y, lower-case it, and return ONION_V2_HOSTNAME or
- * ONION_V3_HOSTNAME depending on the HS version.
+ * Put a NUL after y, lower-case it, and return ONION_V3_HOSTNAME
+ * depending on the HS version.
*
* If address is of the form "x.y.onion" with a well-formed handle x:
* Drop "x.", put a NUL after y, lower-case it, and return
- * ONION_V2_HOSTNAME or ONION_V3_HOSTNAME depending on the HS version.
+ * ONION_V3_HOSTNAME depending on the HS version.
*
* If address is of the form "y.onion" with a badly-formed handle y:
* Return BAD_HOSTNAME and log a message.
@@ -1691,14 +1675,6 @@ parse_extended_hostname(char *address, hostname_type_t *type_out)
if (q != address) {
memmove(address, q, strlen(q) + 1 /* also get \0 */);
}
- /* v2 onion address check. */
- if (strlen(query) == REND_SERVICE_ID_LEN_BASE32) {
- *type_out = ONION_V2_HOSTNAME;
- if (rend_valid_v2_service_id(query)) {
- goto success;
- }
- goto failed;
- }
/* v3 onion address check. */
if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) {
@@ -1718,8 +1694,7 @@ parse_extended_hostname(char *address, hostname_type_t *type_out)
failed:
/* otherwise, return to previous state and return 0 */
*s = '.';
- const bool is_onion = (*type_out == ONION_V2_HOSTNAME) ||
- (*type_out == ONION_V3_HOSTNAME);
+ const bool is_onion = (*type_out == ONION_V3_HOSTNAME);
log_warn(LD_APP, "Invalid %shostname %s; rejecting",
is_onion ? "onion " : "",
safe_str_client(address));
@@ -2004,41 +1979,7 @@ connection_ap_handle_onion(entry_connection_t *conn,
int rend_cache_lookup_result = -ENOENT;
int descriptor_is_usable = 0;
- if (addresstype == ONION_V2_HOSTNAME) { /* it's a v2 hidden service */
- rend_cache_entry_t *entry = NULL;
- /* Look up if we have client authorization configured for this hidden
- * service. If we do, associate it with the rend_data. */
- rend_service_authorization_t *client_auth =
- rend_client_lookup_service_authorization(socks->address);
-
- const uint8_t *cookie = NULL;
- rend_auth_type_t auth_type = REND_NO_AUTH;
- if (client_auth) {
- log_info(LD_REND, "Using previously configured client authorization "
- "for hidden service request.");
- auth_type = client_auth->auth_type;
- cookie = client_auth->descriptor_cookie;
- }
-
- /* Fill in the rend_data field so we can start doing a connection to
- * a hidden service. */
- rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data =
- rend_data_client_create(socks->address, NULL, (char *) cookie,
- auth_type);
- if (rend_data == NULL) {
- return -1;
- }
- onion_address = rend_data_get_address(rend_data);
- log_info(LD_REND,"Got a hidden service request for ID '%s'",
- safe_str_client(onion_address));
-
- rend_cache_lookup_result = rend_cache_lookup_entry(onion_address,-1,
- &entry);
- if (!rend_cache_lookup_result && entry) {
- descriptor_is_usable = rend_client_any_intro_points_usable(entry);
- }
- } else { /* it's a v3 hidden service */
- tor_assert(addresstype == ONION_V3_HOSTNAME);
+ if (addresstype == ONION_V3_HOSTNAME) {
const hs_descriptor_t *cached_desc = NULL;
int retval;
/* Create HS conn identifier with HS pubkey */
@@ -2108,13 +2049,7 @@ connection_ap_handle_onion(entry_connection_t *conn,
edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
connection_ap_mark_as_non_pending_circuit(conn);
base_conn->state = AP_CONN_STATE_RENDDESC_WAIT;
- if (addresstype == ONION_V2_HOSTNAME) {
- tor_assert(edge_conn->rend_data);
- rend_client_refetch_v2_renddesc(edge_conn->rend_data);
- /* Whatever the result of the refetch, we don't go further. */
- return 0;
- } else {
- tor_assert(addresstype == ONION_V3_HOSTNAME);
+ if (addresstype == ONION_V3_HOSTNAME) {
tor_assert(edge_conn->hs_ident);
/* Attempt to fetch the hsv3 descriptor. Check the retval to see how it
* went and act accordingly. */
@@ -2313,7 +2248,7 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
}
/* Now, we handle everything that isn't a .onion address. */
- if (addresstype != ONION_V2_HOSTNAME && addresstype != ONION_V3_HOSTNAME) {
+ if (addresstype != ONION_V3_HOSTNAME) {
/* Not a hidden-service request. It's either a hostname or an IP,
* possibly with a .exit that we stripped off. We're going to check
* if we're allowed to connect/resolve there, and then launch the
@@ -2579,8 +2514,7 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
return 0;
} else {
/* If we get here, it's a request for a .onion address! */
- tor_assert(addresstype == ONION_V2_HOSTNAME ||
- addresstype == ONION_V3_HOSTNAME);
+ tor_assert(addresstype == ONION_V3_HOSTNAME);
tor_assert(!automap);
return connection_ap_handle_onion(conn, socks, circ, addresstype);
}
diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h
index c9433adade..701812b9bb 100644
--- a/src/core/or/connection_edge.h
+++ b/src/core/or/connection_edge.h
@@ -80,7 +80,6 @@ typedef enum hostname_type_t {
BAD_HOSTNAME,
EXIT_HOSTNAME,
NORMAL_HOSTNAME,
- ONION_V2_HOSTNAME,
ONION_V3_HOSTNAME,
} hostname_type_t;
diff --git a/src/core/or/crypt_path.c b/src/core/or/crypt_path.c
index e1bbd81251..f035cf461a 100644
--- a/src/core/or/crypt_path.c
+++ b/src/core/or/crypt_path.c
@@ -15,10 +15,6 @@
* some more effort:
*
* - circuit_list_path_impl()
- * - Functions dealing with cpaths in HSv2 create_rend_cpath() and
- * create_rend_cpath_legacy()
- * - The cpath related parts of rend_service_receive_introduction() and
- * rend_client_send_introduction().
**/
#define CRYPT_PATH_PRIVATE
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
index 623c6d2eae..737a5927e9 100644
--- a/src/feature/control/control_cmd.c
+++ b/src/feature/control/control_cmd.c
@@ -37,7 +37,6 @@
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerinfo.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendparse.h"
#include "feature/rend/rendservice.h"
@@ -1520,9 +1519,7 @@ handle_control_hsfetch(control_connection_t *conn,
/* Trigger the fetch using the built rend query and possibly a list of HS
* directory to use. This function ignores the client cache thus this will
* always send a fetch command. */
- if (version == HS_VERSION_TWO) {
- rend_client_fetch_v2_desc(rend_query, hsdirs);
- } else if (version == HS_VERSION_THREE) {
+ if (version == HS_VERSION_THREE) {
hs_control_hsfetch_command(&v3_pk, hsdirs);
}
diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c
index 5feadd23d1..75d5418d19 100644
--- a/src/feature/control/control_getinfo.c
+++ b/src/feature/control/control_getinfo.c
@@ -542,25 +542,14 @@ getinfo_helper_dir(control_connection_t *control_conn,
hostname_type_t addr_type;
question += strlen("hs/client/desc/id/");
- if (rend_valid_v2_service_id(question)) {
- addr_type = ONION_V2_HOSTNAME;
- } else if (hs_address_is_valid(question)) {
+ if (hs_address_is_valid(question)) {
addr_type = ONION_V3_HOSTNAME;
} else {
*errmsg = "Invalid address";
return -1;
}
- if (addr_type == ONION_V2_HOSTNAME) {
- rend_cache_entry_t *e = NULL;
- if (!rend_cache_lookup_entry(question, -1, &e)) {
- /* Descriptor found in cache */
- *answer = tor_strdup(e->desc);
- } else {
- *errmsg = "Not found in cache";
- return -1;
- }
- } else {
+ if (addr_type == ONION_V3_HOSTNAME) {
ed25519_public_key_t service_pk;
const char *desc;
@@ -584,25 +573,14 @@ getinfo_helper_dir(control_connection_t *control_conn,
hostname_type_t addr_type;
question += strlen("hs/service/desc/id/");
- if (rend_valid_v2_service_id(question)) {
- addr_type = ONION_V2_HOSTNAME;
- } else if (hs_address_is_valid(question)) {
+ if (hs_address_is_valid(question)) {
addr_type = ONION_V3_HOSTNAME;
} else {
*errmsg = "Invalid address";
return -1;
}
- rend_cache_entry_t *e = NULL;
- if (addr_type == ONION_V2_HOSTNAME) {
- if (!rend_cache_lookup_v2_desc_as_service(question, &e)) {
- /* Descriptor found in cache */
- *answer = tor_strdup(e->desc);
- } else {
- *errmsg = "Not found in cache";
- return -1;
- }
- } else {
+ if (addr_type == ONION_V3_HOSTNAME) {
ed25519_public_key_t service_pk;
char *desc;
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index a5dd856729..dd7af9dbfc 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -48,7 +48,6 @@
#include "feature/relay/routermode.h"
#include "feature/relay/selftest.h"
#include "feature/rend/rendcache.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
#include "feature/stats/predict_ports.h"
@@ -2861,7 +2860,6 @@ handle_response_fetch_renddesc_v2(dir_connection_t *conn,
conn->identity_digest,
body);
conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2;
- rend_client_desc_trynow(service_id);
memwipe(service_id, 0, sizeof(service_id));
}
break;
@@ -3024,17 +3022,6 @@ connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
{
connection_t *conn = TO_CONN(dir_conn);
- /* If we were trying to fetch a v2 rend desc and did not succeed, retry as
- * needed. (If a fetch is successful, the connection state is changed to
- * DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 or DIR_PURPOSE_HAS_FETCHED_HSDESC to
- * mark that refetching is unnecessary.) */
- if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2 &&
- dir_conn->rend_data &&
- rend_valid_v2_service_id(
- rend_data_get_address(dir_conn->rend_data))) {
- rend_client_refetch_v2_renddesc(dir_conn->rend_data);
- }
-
/* Check for v3 rend desc fetch */
if (conn->purpose == DIR_PURPOSE_FETCH_HSDESC &&
dir_conn->hs_ident &&
diff --git a/src/feature/dircommon/directory.c b/src/feature/dircommon/directory.c
index b276ac3441..0029eb37a1 100644
--- a/src/feature/dircommon/directory.c
+++ b/src/feature/dircommon/directory.c
@@ -68,7 +68,6 @@
* router_upload_dir_desc_to_dirservers() in router.c
* upload_service_descriptor() in rendservice.c
* - directory_get_from_dirserver(), called from
- * rend_client_refetch_renddesc() in rendclient.c
* run_scheduled_events() in main.c
* do_hup() in main.c
* - connection_dir_process_inbuf(), called from
diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index f0059a1a7c..b246ab423c 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -29,7 +29,6 @@
#include "feature/nodelist/describe.h"
#include "feature/nodelist/nodelist.h"
#include "feature/rend/rendservice.h"
-#include "feature/rend/rendclient.h"
#include "feature/stats/rephist.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_rand.h"
@@ -647,9 +646,7 @@ cleanup_on_free_client_circ(circuit_t *circ)
{
tor_assert(circ);
- if (circuit_is_hs_v2(circ)) {
- rend_client_circuit_cleanup_on_free(circ);
- } else if (circuit_is_hs_v3(circ)) {
+ if (circuit_is_hs_v3(circ)) {
hs_client_circuit_cleanup_on_free(circ);
}
/* It is possible the circuit has an HS purpose but no identifier (rend_data
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 3b03bda1f5..28bbe72459 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -34,7 +34,6 @@
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
-#include "feature/rend/rendclient.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
@@ -1959,9 +1958,6 @@ hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */
note_connection_attempt_succeeded(conn->hs_ident);
return;
- } else if (conn->rend_data) { /* It's v2: pass it to the legacy handler */
- rend_client_note_connection_attempt_ended(conn->rend_data);
- return;
}
}
@@ -2087,9 +2083,7 @@ int
hs_client_send_introduce1(origin_circuit_t *intro_circ,
origin_circuit_t *rend_circ)
{
- return (intro_circ->hs_ident) ? send_introduce1(intro_circ, rend_circ) :
- rend_client_send_introduction(intro_circ,
- rend_circ);
+ return send_introduce1(intro_circ, rend_circ);
}
/** Called when the client circuit circ has been established. It can be either
@@ -2106,15 +2100,11 @@ hs_client_circuit_has_opened(origin_circuit_t *circ)
case CIRCUIT_PURPOSE_C_INTRODUCING:
if (circ->hs_ident) {
client_intro_circ_has_opened(circ);
- } else {
- rend_client_introcirc_has_opened(circ);
}
break;
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
if (circ->hs_ident) {
client_rendezvous_circ_has_opened(circ);
- } else {
- rend_client_rendcirc_has_opened(circ);
}
break;
default:
@@ -2428,9 +2418,7 @@ hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn)
{
tor_assert(edge_conn);
- return (edge_conn->hs_ident) ?
- client_get_random_intro(&edge_conn->hs_ident->identity_pk) :
- rend_client_get_random_intro(edge_conn->rend_data);
+ return client_get_random_intro(&edge_conn->hs_ident->identity_pk);
}
/** Called when get an INTRODUCE_ACK cell on the introduction circuit circ.
@@ -2452,9 +2440,7 @@ hs_client_receive_introduce_ack(origin_circuit_t *circ,
goto end;
}
- ret = (circ->hs_ident) ? handle_introduce_ack(circ, payload, payload_len) :
- rend_client_introduction_acked(circ, payload,
- payload_len);
+ ret = handle_introduce_ack(circ, payload, payload_len);
/* For path bias: This circuit was used successfully. NACK or ACK counts. */
pathbias_mark_use_success(circ);
@@ -2488,9 +2474,8 @@ hs_client_receive_rendezvous2(origin_circuit_t *circ,
log_info(LD_REND, "Got RENDEZVOUS2 cell from hidden service on circuit %u.",
TO_CIRCUIT(circ)->n_circ_id);
- ret = (circ->hs_ident) ? handle_rendezvous2(circ, payload, payload_len) :
- rend_client_receive_rendezvous(circ, payload,
- payload_len);
+ ret = handle_rendezvous2(circ, payload, payload_len);
+
end:
return ret;
}
@@ -2511,9 +2496,7 @@ hs_client_reextend_intro_circuit(origin_circuit_t *circ)
tor_assert(circ);
- ei = (circ->hs_ident) ?
- client_get_random_intro(&circ->hs_ident->identity_pk) :
- rend_client_get_random_intro(circ->rend_data);
+ ei = client_get_random_intro(&circ->hs_ident->identity_pk);
if (ei == NULL) {
log_warn(LD_REND, "No usable introduction points left. Closing.");
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
@@ -2591,9 +2574,6 @@ hs_client_free_all(void)
void
hs_client_purge_state(void)
{
- /* v2 subsystem. */
- rend_client_purge_state();
-
/* Cancel all descriptor fetches. Do this first so once done we are sure
* that our descriptor cache won't modified. */
cancel_descriptor_fetches();
diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c
index fa27ac5223..91cb6d529b 100644
--- a/src/feature/hs/hs_common.c
+++ b/src/feature/hs/hs_common.c
@@ -1559,9 +1559,8 @@ hs_clean_last_hid_serv_requests(time_t now)
* <b>req_key_str</b> from the history of times of requests to hidden service
* directories.
*
- * This is called from rend_client_note_connection_attempt_ended(), which
- * must be idempotent, so any future changes to this function must leave it
- * idempotent too. */
+ * This is called from purge_hid_serv_request(), which must be idempotent, so
+ * any future changes to this function must leave it idempotent too. */
void
hs_purge_hid_serv_from_last_hid_serv_requests(const char *req_key_str)
{
diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c
index 7ffc7ecb96..403ea151c4 100644
--- a/src/feature/hs/hs_config.c
+++ b/src/feature/hs/hs_config.c
@@ -28,7 +28,6 @@
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_ob.h"
#include "feature/hs/hs_service.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"
#include "lib/encoding/confline.h"
#include "lib/conf/confdecl.h"
@@ -717,11 +716,6 @@ hs_config_client_auth_all(const or_options_t *options, int validate_only)
{
int ret = -1;
- /* Configure v2 authorization. */
- if (rend_parse_service_authorization(options, validate_only) < 0) {
- goto done;
- }
-
/* Configure v3 authorization. */
if (hs_config_client_authorization(options, validate_only) < 0) {
goto done;
diff --git a/src/feature/rend/include.am b/src/feature/rend/include.am
index fb12439a90..8ad85bd7b1 100644
--- a/src/feature/rend/include.am
+++ b/src/feature/rend/include.am
@@ -2,7 +2,6 @@
# ADD_C_FILE: INSERT SOURCES HERE.
LIBTOR_APP_A_SOURCES += \
src/feature/rend/rendcache.c \
- src/feature/rend/rendclient.c \
src/feature/rend/rendcommon.c \
src/feature/rend/rendmid.c \
src/feature/rend/rendparse.c \
@@ -15,7 +14,6 @@ noinst_HEADERS += \
src/feature/rend/rend_intro_point_st.h \
src/feature/rend/rend_service_descriptor_st.h \
src/feature/rend/rendcache.h \
- src/feature/rend/rendclient.h \
src/feature/rend/rendcommon.h \
src/feature/rend/rendmid.h \
src/feature/rend/rendparse.h \
diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c
deleted file mode 100644
index 3dda7cd46d..0000000000
--- a/src/feature/rend/rendclient.c
+++ /dev/null
@@ -1,1322 +0,0 @@
-/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2020, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file rendclient.c
- * \brief Client code to access location-hidden services.
- **/
-
-#include "core/or/or.h"
-#include "app/config/config.h"
-#include "core/mainloop/connection.h"
-#include "core/mainloop/mainloop.h"
-#include "core/or/circuitbuild.h"
-#include "core/or/circuitlist.h"
-#include "core/or/circuituse.h"
-#include "core/or/connection_edge.h"
-#include "core/or/extendinfo.h"
-#include "core/or/relay.h"
-#include "feature/client/circpathbias.h"
-#include "feature/control/control_events.h"
-#include "feature/dirclient/dirclient.h"
-#include "feature/dircommon/directory.h"
-#include "feature/hs/hs_circuit.h"
-#include "feature/hs/hs_client.h"
-#include "feature/hs/hs_common.h"
-#include "feature/nodelist/describe.h"
-#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/nodelist.h"
-#include "feature/nodelist/routerlist.h"
-#include "feature/nodelist/routerset.h"
-#include "feature/rend/rendclient.h"
-#include "feature/rend/rendcommon.h"
-#include "feature/stats/rephist.h"
-#include "lib/crypt_ops/crypto_dh.h"
-#include "lib/crypt_ops/crypto_rand.h"
-#include "lib/crypt_ops/crypto_util.h"
-#include "lib/encoding/confline.h"
-
-#include "core/or/cpath_build_state_st.h"
-#include "core/or/crypt_path_st.h"
-#include "feature/dircommon/dir_connection_st.h"
-#include "core/or/entry_connection_st.h"
-#include "core/or/extend_info_st.h"
-#include "core/or/origin_circuit_st.h"
-#include "feature/rend/rend_intro_point_st.h"
-#include "feature/rend/rend_service_descriptor_st.h"
-#include "feature/nodelist/routerstatus_st.h"
-
-static extend_info_t *rend_client_get_random_intro_impl(
- const rend_cache_entry_t *rend_query,
- const int strict, const int warnings);
-
-/** Purge all potentially remotely-detectable state held in the hidden
- * service client code. Called on SIGNAL NEWNYM. */
-void
-rend_client_purge_state(void)
-{
- rend_cache_purge();
- rend_cache_failure_purge();
- rend_client_cancel_descriptor_fetches();
- hs_purge_last_hid_serv_requests();
-}
-
-/** Called when we've established a circuit to an introduction point:
- * send the introduction request. */
-void
-rend_client_introcirc_has_opened(origin_circuit_t *circ)
-{
- tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
- tor_assert(circ->cpath);
-
- log_info(LD_REND,"introcirc is open");
- connection_ap_attach_pending(1);
-}
-
-/** Send the establish-rendezvous cell along a rendezvous circuit. if
- * it fails, mark the circ for close and return -1. else return 0.
- */
-static int
-rend_client_send_establish_rendezvous(origin_circuit_t *circ)
-{
- tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
- tor_assert(circ->rend_data);
- log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
-
- crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN);
-
- /* Set timestamp_dirty, because circuit_expire_building expects it,
- * and the rend cookie also means we've used the circ. */
- circ->base_.timestamp_dirty = time(NULL);
-
- /* We've attempted to use this circuit. Probe it if we fail */
- pathbias_count_use_attempt(circ);
-
- if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
- RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
- circ->rend_data->rend_cookie,
- REND_COOKIE_LEN,
- circ->cpath->prev)<0) {
- /* circ is already marked for close */
- log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
- return -1;
- }
-
- return 0;
-}
-
-/** Called when we're trying to connect an ap conn; sends an INTRODUCE1 cell
- * down introcirc if possible.
- */
-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];
- char tmp[RELAY_PAYLOAD_SIZE];
- rend_cache_entry_t *entry = NULL;
- crypt_path_t *cpath;
- ptrdiff_t dh_offset;
- crypto_pk_t *intro_key = NULL;
- int status = 0;
- const char *onion_address;
-
- tor_assert(introcirc->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
- tor_assert(rendcirc->base_.purpose == CIRCUIT_PURPOSE_C_REND_READY);
- tor_assert(introcirc->rend_data);
- tor_assert(rendcirc->rend_data);
- tor_assert(!rend_cmp_service_ids(rend_data_get_address(introcirc->rend_data),
- rend_data_get_address(rendcirc->rend_data)));
- assert_circ_anonymity_ok(introcirc, options);
- assert_circ_anonymity_ok(rendcirc, options);
- onion_address = rend_data_get_address(introcirc->rend_data);
-
- r = rend_cache_lookup_entry(onion_address, -1, &entry);
- /* An invalid onion address is not possible else we have a big issue. */
- tor_assert(r != -EINVAL);
- if (r < 0 || !rend_client_any_intro_points_usable(entry)) {
- /* If the descriptor is not found or the intro points are not usable
- * anymore, trigger a fetch. */
- log_info(LD_REND,
- "query %s didn't have valid rend desc in cache. "
- "Refetching descriptor.",
- safe_str_client(onion_address));
- rend_client_refetch_v2_renddesc(introcirc->rend_data);
- {
- connection_t *conn;
-
- while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
- AP_CONN_STATE_CIRCUIT_WAIT, onion_address))) {
- connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
- }
- }
-
- status = -1;
- goto cleanup;
- }
-
- /* first 20 bytes of payload are the hash of the service's pk */
- intro_key = NULL;
- SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
- intro, {
- if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest,
- intro->extend_info->identity_digest, DIGEST_LEN)) {
- intro_key = intro->intro_key;
- break;
- }
- });
- if (!intro_key) {
- log_info(LD_REND, "Could not find intro key for %s at %s; we "
- "have a v2 rend desc with %d intro points. "
- "Trying a different intro point...",
- safe_str_client(onion_address),
- safe_str_client(extend_info_describe(
- introcirc->build_state->chosen_exit)),
- smartlist_len(entry->parsed->intro_nodes));
-
- if (hs_client_reextend_intro_circuit(introcirc)) {
- status = -2;
- goto perm_err;
- } else {
- status = -1;
- goto cleanup;
- }
- }
- if (crypto_pk_get_digest(intro_key, payload)<0) {
- log_warn(LD_BUG, "Internal error: couldn't hash public key.");
- status = -2;
- goto perm_err;
- }
-
- /* Initialize the pending_final_cpath and start the DH handshake. */
- cpath = rendcirc->build_state->pending_final_cpath;
- if (!cpath) {
- cpath = rendcirc->build_state->pending_final_cpath =
- tor_malloc_zero(sizeof(crypt_path_t));
- cpath->magic = CRYPT_PATH_MAGIC;
- if (!(cpath->rend_dh_handshake_state = crypto_dh_new(DH_TYPE_REND))) {
- log_warn(LD_BUG, "Internal error: couldn't allocate DH.");
- status = -2;
- goto perm_err;
- }
- if (crypto_dh_generate_public(cpath->rend_dh_handshake_state)<0) {
- log_warn(LD_BUG, "Internal error: couldn't generate g^x.");
- status = -2;
- goto perm_err;
- }
- }
-
- /* If version is 3, write (optional) auth data and timestamp. */
- if (entry->parsed->protocols & (1<<3)) {
- tmp[0] = 3; /* version 3 of the cell format */
- /* auth type, if any */
- tmp[1] = (uint8_t) TO_REND_DATA_V2(introcirc->rend_data)->auth_type;
- v3_shift = 1;
- if (tmp[1] != REND_NO_AUTH) {
- set_uint16(tmp+2, htons(REND_DESC_COOKIE_LEN));
- memcpy(tmp+4, TO_REND_DATA_V2(introcirc->rend_data)->descriptor_cookie,
- REND_DESC_COOKIE_LEN);
- v3_shift += 2+REND_DESC_COOKIE_LEN;
- }
- /* Once this held a timestamp. */
- set_uint32(tmp+v3_shift+1, 0);
- v3_shift += 4;
- } /* if version 2 only write version number */
- else if (entry->parsed->protocols & (1<<2)) {
- tmp[0] = 2; /* version 2 of the cell format */
- }
-
- /* write the remaining items into tmp */
- if (entry->parsed->protocols & (1<<3) || entry->parsed->protocols & (1<<2)) {
- /* version 2 format */
- extend_info_t *extend_info = rendcirc->build_state->chosen_exit;
- int klen;
- const tor_addr_port_t *orport =
- extend_info_get_orport(extend_info, AF_INET);
- IF_BUG_ONCE(! orport) {
- /* we should never put an IPv6 address here. */
- goto perm_err;
- }
- /* nul pads */
- set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&orport->addr));
- set_uint16(tmp+v3_shift+5, htons(orport->port));
- memcpy(tmp+v3_shift+7, extend_info->identity_digest, DIGEST_LEN);
- klen = crypto_pk_asn1_encode(extend_info->onion_key,
- tmp+v3_shift+7+DIGEST_LEN+2,
- sizeof(tmp)-(v3_shift+7+DIGEST_LEN+2));
- if (klen < 0) {
- log_warn(LD_BUG,"Internal error: can't encode public key.");
- status = -2;
- goto perm_err;
- }
- set_uint16(tmp+v3_shift+7+DIGEST_LEN, htons(klen));
- memcpy(tmp+v3_shift+7+DIGEST_LEN+2+klen, rendcirc->rend_data->rend_cookie,
- REND_COOKIE_LEN);
- dh_offset = v3_shift+7+DIGEST_LEN+2+klen+REND_COOKIE_LEN;
- } else {
- /* Version 0. */
-
- /* Some compilers are smart enough to work out that nickname can be more
- * than 19 characters, when it's a hexdigest. They warn that strncpy()
- * will truncate hexdigests without NUL-terminating them. But we only put
- * hexdigests in HSDir and general circuit exits. */
- if (BUG(strlen(rendcirc->build_state->chosen_exit->nickname)
- > MAX_NICKNAME_LEN)) {
- goto perm_err;
- }
- strlcpy(tmp, rendcirc->build_state->chosen_exit->nickname,
- sizeof(tmp));
- memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_data->rend_cookie,
- REND_COOKIE_LEN);
- dh_offset = MAX_NICKNAME_LEN+1+REND_COOKIE_LEN;
- }
-
- if (crypto_dh_get_public(cpath->rend_dh_handshake_state, tmp+dh_offset,
- DH1024_KEY_LEN)<0) {
- log_warn(LD_BUG, "Internal error: couldn't extract g^x.");
- status = -2;
- goto perm_err;
- }
-
- /*XXX maybe give crypto_pk_obsolete_public_hybrid_encrypt a max_len arg,
- * to avoid buffer overflows? */
- r = crypto_pk_obsolete_public_hybrid_encrypt(intro_key, payload+DIGEST_LEN,
- sizeof(payload)-DIGEST_LEN,
- tmp,
- (int)(dh_offset+DH1024_KEY_LEN),
- PK_PKCS1_OAEP_PADDING, 0);
- if (r<0) {
- log_warn(LD_BUG,"Internal error: hybrid pk encrypt failed.");
- status = -2;
- goto perm_err;
- }
-
- payload_len = DIGEST_LEN + r;
- tor_assert(payload_len <= RELAY_PAYLOAD_SIZE); /* we overran something */
-
- /* Copy the rendezvous cookie from rendcirc to introcirc, so that
- * when introcirc gets an ack, we can change the state of the right
- * rendezvous circuit. */
- memcpy(introcirc->rend_data->rend_cookie, rendcirc->rend_data->rend_cookie,
- REND_COOKIE_LEN);
-
- log_info(LD_REND, "Sending an INTRODUCE1 cell");
- if (relay_send_command_from_edge(0, TO_CIRCUIT(introcirc),
- RELAY_COMMAND_INTRODUCE1,
- payload, payload_len,
- introcirc->cpath->prev)<0) {
- /* introcirc is already marked for close. leave rendcirc alone. */
- log_warn(LD_BUG, "Couldn't send INTRODUCE1 cell");
- status = -2;
- goto cleanup;
- }
-
- /* Now, we wait for an ACK or NAK on this circuit. */
- circuit_change_purpose(TO_CIRCUIT(introcirc),
- CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
- /* Set timestamp_dirty, because circuit_expire_building expects it
- * to specify when a circuit entered the _C_INTRODUCE_ACK_WAIT
- * state. */
- introcirc->base_.timestamp_dirty = time(NULL);
-
- pathbias_count_use_attempt(introcirc);
-
- goto cleanup;
-
- perm_err:
- if (!introcirc->base_.marked_for_close)
- circuit_mark_for_close(TO_CIRCUIT(introcirc), END_CIRC_REASON_INTERNAL);
- circuit_mark_for_close(TO_CIRCUIT(rendcirc), END_CIRC_REASON_INTERNAL);
- cleanup:
- memwipe(payload, 0, sizeof(payload));
- memwipe(tmp, 0, sizeof(tmp));
-
- return status;
-}
-
-/** Called when a rendezvous circuit is open; sends a establish
- * rendezvous circuit as appropriate. */
-void
-rend_client_rendcirc_has_opened(origin_circuit_t *circ)
-{
- tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
-
- log_info(LD_REND,"rendcirc is open");
-
- /* generate a rendezvous cookie, store it in circ */
- if (rend_client_send_establish_rendezvous(circ) < 0) {
- return;
- }
-}
-
-/**
- * Called to close other intro circuits we launched in parallel.
- */
-static void
-rend_client_close_other_intros(const uint8_t *rend_pk_digest)
-{
- /* abort parallel intro circs, if any */
- SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, c) {
- if ((c->purpose == CIRCUIT_PURPOSE_C_INTRODUCING ||
- c->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) &&
- !c->marked_for_close && CIRCUIT_IS_ORIGIN(c)) {
- origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(c);
- if (oc->rend_data &&
- rend_circuit_pk_digest_eq(oc, rend_pk_digest)) {
- log_info(LD_REND|LD_CIRC, "Closing introduction circuit %d that we "
- "built in parallel (Purpose %d).", oc->global_identifier,
- c->purpose);
- circuit_mark_for_close(c, END_CIRC_REASON_IP_NOW_REDUNDANT);
- }
- }
- }
- SMARTLIST_FOREACH_END(c);
-}
-
-/** Called when get an ACK or a NAK for a REND_INTRODUCE1 cell.
- */
-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.
-
- tor_assert(circ->build_state);
- tor_assert(circ->build_state->chosen_exit);
- assert_circ_anonymity_ok(circ, options);
- tor_assert(circ->rend_data);
-
- if (request_len == 0) {
- /* It's an ACK; the introduction point relayed our introduction request. */
- /* Locate the rend circ which is waiting to hear about this ack,
- * and tell it.
- */
- 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 */
- 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
- * it to specify when a circuit entered the
- * _C_REND_READY_INTRO_ACKED state. */
- rendcirc->base_.timestamp_dirty = time(NULL);
- } else {
- log_info(LD_REND,"...Found no rend circ. Dropping on the floor.");
- }
- /* Save the rend data digest to a temporary object so that we don't access
- * it after we mark the circuit for close. */
- const uint8_t *rend_digest_tmp = NULL;
- size_t digest_len;
- uint8_t *cached_rend_digest = NULL;
- rend_digest_tmp = rend_data_get_pk_digest(circ->rend_data, &digest_len);
- cached_rend_digest = tor_malloc_zero(digest_len);
- memcpy(cached_rend_digest, rend_digest_tmp, digest_len);
-
- /* close the circuit: we won't need it anymore. */
- circuit_change_purpose(TO_CIRCUIT(circ),
- CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
- circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
-
- /* close any other intros launched in parallel */
- rend_client_close_other_intros(cached_rend_digest);
- tor_free(cached_rend_digest); /* free the temporary digest */
- } else {
- /* It's a NAK; the introduction point didn't relay our request. */
- circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_INTRODUCING);
- /* Remove this intro point from the set of viable introduction
- * points. If any remain, extend to a new one and try again.
- * If none remain, refetch the service descriptor.
- */
- log_info(LD_REND, "Got nack for %s from %s...",
- safe_str_client(rend_data_get_address(circ->rend_data)),
- safe_str_client(extend_info_describe(circ->build_state->chosen_exit)));
- if (rend_client_report_intro_point_failure(circ->build_state->chosen_exit,
- circ->rend_data,
- INTRO_POINT_FAILURE_GENERIC)>0) {
- /* There are introduction points left. Re-extend the circuit to
- * another intro point and try again. */
- int result = hs_client_reextend_intro_circuit(circ);
- /* XXXX If that call failed, should we close the rend circuit,
- * too? */
- return result;
- } else {
- /* Close circuit because no more intro points are usable thus not
- * useful anymore. Change it's purpose before so we don't report an
- * intro point failure again triggering an extra descriptor fetch. */
- circuit_change_purpose(TO_CIRCUIT(circ),
- CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
- circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
- }
- }
- return 0;
-}
-
-/** Determine the responsible hidden service directories for <b>desc_id</b>
- * and fetch the descriptor with that ID from one of them. Only
- * send a request to a hidden service directory that we have not yet tried
- * during this attempt to connect to this hidden service; on success, return 1,
- * in the case that no hidden service directory is left to ask for the
- * descriptor, return 0, and in case of a failure -1. */
-static int
-directory_get_from_hs_dir(const char *desc_id,
- const rend_data_t *rend_query,
- routerstatus_t *rs_hsdir)
-{
- routerstatus_t *hs_dir = rs_hsdir;
- char *hsdir_fp;
- char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
- char descriptor_cookie_base64[3*REND_DESC_COOKIE_LEN_BASE64];
- const rend_data_v2_t *rend_data;
- const int how_to_fetch = DIRIND_ANONYMOUS;
-
- tor_assert(desc_id);
- tor_assert(rend_query);
- rend_data = TO_REND_DATA_V2(rend_query);
-
- base32_encode(desc_id_base32, sizeof(desc_id_base32),
- desc_id, DIGEST_LEN);
-
- /* Automatically pick an hs dir if none given. */
- if (!rs_hsdir) {
- bool rate_limited = false;
-
- /* Determine responsible dirs. Even if we can't get all we want, work with
- * the ones we have. If it's empty, we'll notice in hs_pick_hsdir(). */
- smartlist_t *responsible_dirs = smartlist_new();
- hid_serv_get_responsible_directories(responsible_dirs, desc_id);
-
- hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32, &rate_limited);
- if (!hs_dir) {
- /* No suitable hs dir can be found, stop right now. */
- const char *query_response = (rate_limited) ? "QUERY_RATE_LIMITED" :
- "QUERY_NO_HSDIR";
- control_event_hsv2_descriptor_failed(rend_query, NULL, query_response);
- control_event_hs_descriptor_content(rend_data_get_address(rend_query),
- desc_id_base32, NULL, NULL);
- return 0;
- }
- }
-
- /* Add a copy of the HSDir identity digest to the query so we can track it
- * on the control port. */
- hsdir_fp = tor_memdup(hs_dir->identity_digest,
- sizeof(hs_dir->identity_digest));
- smartlist_add(rend_query->hsdirs_fp, hsdir_fp);
-
- /* Encode descriptor cookie for logging purposes. Also, if the cookie is
- * malformed, no fetch is triggered thus this needs to be done before the
- * fetch request. */
- if (rend_data->auth_type != REND_NO_AUTH) {
- if (base64_encode(descriptor_cookie_base64,
- sizeof(descriptor_cookie_base64),
- rend_data->descriptor_cookie,
- REND_DESC_COOKIE_LEN,
- 0)<0) {
- log_warn(LD_BUG, "Could not base64-encode descriptor cookie.");
- control_event_hsv2_descriptor_failed(rend_query, hsdir_fp, "BAD_DESC");
- control_event_hs_descriptor_content(rend_data_get_address(rend_query),
- desc_id_base32, hsdir_fp, NULL);
- return 0;
- }
- /* Remove == signs. */
- descriptor_cookie_base64[strlen(descriptor_cookie_base64)-2] = '\0';
- } else {
- strlcpy(descriptor_cookie_base64, "(none)",
- sizeof(descriptor_cookie_base64));
- }
-
- /* Send fetch request. (Pass query and possibly descriptor cookie so that
- * they can be written to the directory connection and be referred to when
- * the response arrives. */
- directory_request_t *req =
- directory_request_new(DIR_PURPOSE_FETCH_RENDDESC_V2);
- directory_request_set_routerstatus(req, hs_dir);
- directory_request_set_indirection(req, how_to_fetch);
- directory_request_set_resource(req, desc_id_base32);
- directory_request_set_rend_query(req, rend_query);
- directory_initiate_request(req);
- directory_request_free(req);
-
- log_info(LD_REND, "Sending fetch request for v2 descriptor for "
- "service '%s' with descriptor ID '%s', auth type %d, "
- "and descriptor cookie '%s' to hidden service "
- "directory %s",
- rend_data->onion_address, desc_id_base32,
- rend_data->auth_type,
- (rend_data->auth_type == REND_NO_AUTH ? "[none]" :
- escaped_safe_str_client(descriptor_cookie_base64)),
- routerstatus_describe(hs_dir));
- control_event_hs_descriptor_requested(rend_data->onion_address,
- rend_data->auth_type,
- hs_dir->identity_digest,
- desc_id_base32, NULL);
- return 1;
-}
-
-/** Remove tracked HSDir requests from our history for this hidden service
- * descriptor <b>desc_id</b> (of size DIGEST_LEN) */
-static void
-purge_v2_hidserv_req(const char *desc_id)
-{
- char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
-
- /* The hsdir request tracker stores v2 keys using the base32 encoded
- desc_id. Do it: */
- base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
- DIGEST_LEN);
- hs_purge_hid_serv_from_last_hid_serv_requests(desc_id_base32);
-}
-
-/** Fetch a v2 descriptor using the given descriptor id. If any hsdir(s) are
- * given, they will be used instead.
- *
- * On success, 1 is returned. If no hidden service is left to ask, return 0.
- * On error, -1 is returned. */
-static int
-fetch_v2_desc_by_descid(const char *desc_id,
- const rend_data_t *rend_query, smartlist_t *hsdirs)
-{
- int ret;
-
- tor_assert(rend_query);
-
- if (!hsdirs) {
- ret = directory_get_from_hs_dir(desc_id, rend_query, NULL);
- goto end; /* either success or failure, but we're done */
- }
-
- /* Using the given hsdir list, trigger a fetch on each of them. */
- SMARTLIST_FOREACH_BEGIN(hsdirs, routerstatus_t *, hs_dir) {
- /* This should always be a success. */
- ret = directory_get_from_hs_dir(desc_id, rend_query, hs_dir);
- tor_assert(ret);
- } SMARTLIST_FOREACH_END(hs_dir);
-
- /* Everything went well. */
- ret = 0;
-
- end:
- return ret;
-}
-
-/** Fetch a v2 descriptor using the onion address in the given query object.
- * This will compute the descriptor id for each replicas and fetch it on the
- * given hsdir(s) if any or the responsible ones that are chosen
- * automatically.
- *
- * On success, 1 is returned. If no hidden service is left to ask, return 0.
- * On error, -1 is returned. */
-static int
-fetch_v2_desc_by_addr(rend_data_t *rend_query, smartlist_t *hsdirs)
-{
- char descriptor_id[DIGEST_LEN];
- int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
- int i, tries_left, ret;
- rend_data_v2_t *rend_data = TO_REND_DATA_V2(rend_query);
-
- /* Randomly iterate over the replicas until a descriptor can be fetched
- * from one of the consecutive nodes, or no options are left. */
- for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
- replicas_left_to_try[i] = i;
- }
-
- tries_left = REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS;
- while (tries_left > 0) {
- int rand_val = crypto_rand_int(tries_left);
- int chosen_replica = replicas_left_to_try[rand_val];
- replicas_left_to_try[rand_val] = replicas_left_to_try[--tries_left];
-
- ret = rend_compute_v2_desc_id(descriptor_id,
- rend_data->onion_address,
- rend_data->auth_type == REND_STEALTH_AUTH ?
- rend_data->descriptor_cookie : NULL,
- time(NULL), chosen_replica);
- if (ret < 0) {
- /* Normally, on failure the descriptor_id is untouched but let's be
- * safe in general in case the function changes at some point. */
- goto end;
- }
-
- if (tor_memcmp(descriptor_id, rend_data->descriptor_id[chosen_replica],
- sizeof(descriptor_id)) != 0) {
- /* Not equal from what we currently have so purge the last hid serv
- * request cache and update the descriptor ID with the new value. */
- purge_v2_hidserv_req(rend_data->descriptor_id[chosen_replica]);
- memcpy(rend_data->descriptor_id[chosen_replica], descriptor_id,
- sizeof(rend_data->descriptor_id[chosen_replica]));
- }
-
- /* Trigger the fetch with the computed descriptor ID. */
- ret = fetch_v2_desc_by_descid(descriptor_id, rend_query, hsdirs);
- if (ret != 0) {
- /* Either on success or failure, as long as we tried a fetch we are
- * done here. */
- goto end;
- }
- }
-
- /* If we come here, there are no hidden service directories left. */
- log_info(LD_REND, "Could not pick one of the responsible hidden "
- "service directories to fetch descriptors, because "
- "we already tried them all unsuccessfully.");
- ret = 0;
-
- end:
- memwipe(descriptor_id, 0, sizeof(descriptor_id));
- return ret;
-}
-
-/** Fetch a v2 descriptor using the given query. If any hsdir are specified,
- * use them for the fetch.
- *
- * On success, 1 is returned. If no hidden service is left to ask, return 0.
- * On error, -1 is returned. */
-int
-rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs)
-{
- int ret;
- rend_data_v2_t *rend_data;
- const char *onion_address;
-
- tor_assert(query);
-
- /* Get the version 2 data structure of the query. */
- rend_data = TO_REND_DATA_V2(query);
- onion_address = rend_data_get_address(query);
-
- /* Depending on what's available in the rend data query object, we will
- * trigger a fetch by HS address or using a descriptor ID. */
-
- if (onion_address[0] != '\0') {
- ret = fetch_v2_desc_by_addr(query, hsdirs);
- } else if (!tor_digest_is_zero(rend_data->desc_id_fetch)) {
- ret = fetch_v2_desc_by_descid(rend_data->desc_id_fetch, query,
- hsdirs);
- } else {
- /* Query data is invalid. */
- ret = -1;
- goto error;
- }
-
- error:
- return ret;
-}
-
-/** Unless we already have a descriptor for <b>rend_query</b> with at least
- * one (possibly) working introduction point in it, start a connection to a
- * hidden service directory to fetch a v2 rendezvous service descriptor. */
-void
-rend_client_refetch_v2_renddesc(rend_data_t *rend_query)
-{
- rend_cache_entry_t *e = NULL;
- const char *onion_address = rend_data_get_address(rend_query);
-
- tor_assert(rend_query);
- /* Before fetching, check if we already have a usable descriptor here. */
- if (rend_cache_lookup_entry(onion_address, -1, &e) == 0 &&
- rend_client_any_intro_points_usable(e)) {
- log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
- "already have a usable descriptor here. Not fetching.");
- return;
- }
- /* Are we configured to fetch descriptors? */
- if (!get_options()->FetchHidServDescriptors) {
- log_warn(LD_REND, "We received an onion address for a v2 rendezvous "
- "service descriptor, but are not fetching service descriptors.");
- return;
- }
- log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
- safe_str_client(onion_address));
-
- rend_client_fetch_v2_desc(rend_query, NULL);
- /* We don't need to look the error code because either on failure or
- * success, the necessary steps to continue the HS connection will be
- * triggered once the descriptor arrives or if all fetch failed. */
- return;
-}
-
-/** Cancel all rendezvous descriptor fetches currently in progress.
- */
-void
-rend_client_cancel_descriptor_fetches(void)
-{
- smartlist_t *connection_array = get_connection_array();
-
- SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
- if (conn->type == CONN_TYPE_DIR &&
- conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
- /* It's a rendezvous descriptor fetch in progress -- cancel it
- * by marking the connection for close.
- *
- * Even if this connection has already reached EOF, this is
- * enough to make sure that if the descriptor hasn't been
- * processed yet, it won't be. See the end of
- * connection_handle_read; connection_reached_eof (indirectly)
- * processes whatever response the connection received. */
-
- const rend_data_t *rd = (TO_DIR_CONN(conn))->rend_data;
- if (!rd) {
- log_warn(LD_BUG | LD_REND,
- "Marking for close dir conn fetching rendezvous "
- "descriptor for unknown service!");
- } else {
- log_debug(LD_REND, "Marking for close dir conn fetching "
- "rendezvous descriptor for service %s",
- safe_str(rend_data_get_address(rd)));
- }
- connection_mark_for_close(conn);
- }
- } SMARTLIST_FOREACH_END(conn);
-}
-
-/** Mark <b>failed_intro</b> as a failed introduction point for the
- * hidden service specified by <b>rend_query</b>. If the HS now has no
- * usable intro points, or we do not have an HS descriptor for it,
- * then launch a new renddesc fetch.
- *
- * If <b>failure_type</b> is INTRO_POINT_FAILURE_GENERIC, remove the
- * intro point from (our parsed copy of) the HS descriptor.
- *
- * If <b>failure_type</b> is INTRO_POINT_FAILURE_TIMEOUT, mark the
- * intro point as 'timed out'; it will not be retried until the
- * current hidden service connection attempt has ended or it has
- * appeared in a newly fetched rendezvous descriptor.
- *
- * If <b>failure_type</b> is INTRO_POINT_FAILURE_UNREACHABLE,
- * increment the intro point's reachability-failure count; if it has
- * now failed MAX_INTRO_POINT_REACHABILITY_FAILURES or more times,
- * remove the intro point from (our parsed copy of) the HS descriptor.
- *
- * Return -1 if error, 0 if no usable intro points remain or service
- * unrecognized, 1 if recognized and some intro points remain.
- */
-int
-rend_client_report_intro_point_failure(extend_info_t *failed_intro,
- rend_data_t *rend_data,
- unsigned int failure_type)
-{
- int i, r;
- rend_cache_entry_t *ent;
- connection_t *conn;
- const char *onion_address = rend_data_get_address(rend_data);
-
- r = rend_cache_lookup_entry(onion_address, -1, &ent);
- if (r < 0) {
- /* Either invalid onion address or cache entry not found. */
- switch (-r) {
- case EINVAL:
- log_warn(LD_BUG, "Malformed service ID %s.",
- escaped_safe_str_client(onion_address));
- return -1;
- case ENOENT:
- log_info(LD_REND, "Unknown service %s. Re-fetching descriptor.",
- escaped_safe_str_client(onion_address));
- rend_client_refetch_v2_renddesc(rend_data);
- return 0;
- default:
- log_warn(LD_BUG, "Unknown cache lookup returned code: %d", r);
- return -1;
- }
- }
- /* The intro points are not checked here if they are usable or not because
- * this is called when an intro point circuit is closed thus there must be
- * at least one intro point that is usable and is about to be flagged. */
-
- for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
- rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
- if (tor_memeq(failed_intro->identity_digest,
- intro->extend_info->identity_digest, DIGEST_LEN)) {
- switch (failure_type) {
- default:
- log_warn(LD_BUG, "Unknown failure type %u. Removing intro point.",
- failure_type);
- tor_fragile_assert();
- FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL;
- case INTRO_POINT_FAILURE_GENERIC:
- rend_cache_intro_failure_note(failure_type,
- (uint8_t *)failed_intro->identity_digest,
- onion_address);
- rend_intro_point_free(intro);
- smartlist_del(ent->parsed->intro_nodes, i);
- break;
- case INTRO_POINT_FAILURE_TIMEOUT:
- intro->timed_out = 1;
- break;
- case INTRO_POINT_FAILURE_UNREACHABLE:
- ++(intro->unreachable_count);
- {
- int zap_intro_point =
- intro->unreachable_count >= MAX_INTRO_POINT_REACHABILITY_FAILURES;
- log_info(LD_REND, "Failed to reach this intro point %u times.%s",
- intro->unreachable_count,
- zap_intro_point ? " Removing from descriptor.": "");
- if (zap_intro_point) {
- rend_cache_intro_failure_note(
- failure_type,
- (uint8_t *) failed_intro->identity_digest, onion_address);
- rend_intro_point_free(intro);
- smartlist_del(ent->parsed->intro_nodes, i);
- }
- }
- break;
- }
- break;
- }
- }
-
- if (! rend_client_any_intro_points_usable(ent)) {
- log_info(LD_REND,
- "No more intro points remain for %s. Re-fetching descriptor.",
- escaped_safe_str_client(onion_address));
- rend_client_refetch_v2_renddesc(rend_data);
-
- /* move all pending streams back to renddesc_wait */
- /* NOTE: We can now do this faster, if we use pending_entry_connections */
- while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
- AP_CONN_STATE_CIRCUIT_WAIT,
- onion_address))) {
- connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
- }
-
- return 0;
- }
- log_info(LD_REND,"%d options left for %s.",
- smartlist_len(ent->parsed->intro_nodes),
- escaped_safe_str_client(onion_address));
- return 1;
-}
-
-/** The service sent us a rendezvous cell; join the circuits. */
-int
-rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
- size_t request_len)
-{
- if (request_len != DH1024_KEY_LEN+DIGEST_LEN) {
- log_warn(LD_PROTOCOL,"Incorrect length (%d) on RENDEZVOUS2 cell.",
- (int)request_len);
- goto err;
- }
-
- if (hs_circuit_setup_e2e_rend_circ_legacy_client(circ, request) < 0) {
- log_warn(LD_GENERAL, "Failed to setup circ");
- goto err;
- }
- return 0;
-
- err:
- circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
- return -1;
-}
-
-/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that are
- * waiting on <b>query</b>. If there's a working cache entry here with at
- * least one intro point, move them to the next state. */
-void
-rend_client_desc_trynow(const char *query)
-{
- entry_connection_t *conn;
- rend_cache_entry_t *entry;
- const rend_data_t *rend_data;
- time_t now = time(NULL);
-
- smartlist_t *conns = get_connection_array();
- SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
- if (base_conn->type != CONN_TYPE_AP ||
- base_conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
- base_conn->marked_for_close)
- continue;
- conn = TO_ENTRY_CONN(base_conn);
- rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data;
- if (!rend_data)
- continue;
- const char *onion_address = rend_data_get_address(rend_data);
- if (rend_cmp_service_ids(query, onion_address))
- continue;
- assert_connection_ok(base_conn, now);
- if (rend_cache_lookup_entry(onion_address, -1,
- &entry) == 0 &&
- rend_client_any_intro_points_usable(entry)) {
- /* either this fetch worked, or it failed but there was a
- * valid entry from before which we should reuse */
- log_info(LD_REND,"Rend desc is usable. Launching circuits.");
- base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-
- /* restart their timeout values, so they get a fair shake at
- * connecting to the hidden service. */
- base_conn->timestamp_created = now;
- base_conn->timestamp_last_read_allowed = now;
- base_conn->timestamp_last_write_allowed = now;
-
- connection_ap_mark_as_pending_circuit(conn);
- } else { /* 404, or fetch didn't get that far */
- log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
- "unavailable (try again later).",
- safe_str_client(query));
- connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
- rend_client_note_connection_attempt_ended(rend_data);
- }
- } SMARTLIST_FOREACH_END(base_conn);
-}
-
-/** Clear temporary state used only during an attempt to connect to the
- * hidden service with <b>rend_data</b>. Called when a connection attempt
- * has ended; it is possible for this to be called multiple times while
- * handling an ended connection attempt, and any future changes to this
- * function must ensure it remains idempotent. */
-void
-rend_client_note_connection_attempt_ended(const rend_data_t *rend_data)
-{
- unsigned int have_onion = 0;
- rend_cache_entry_t *cache_entry = NULL;
- const char *onion_address = rend_data_get_address(rend_data);
- rend_data_v2_t *rend_data_v2 = TO_REND_DATA_V2(rend_data);
-
- if (onion_address[0] != '\0') {
- /* Ignore return value; we find an entry, or we don't. */
- (void) rend_cache_lookup_entry(onion_address, -1, &cache_entry);
- have_onion = 1;
- }
-
- /* Clear the timed_out flag on all remaining intro points for this HS. */
- if (cache_entry != NULL) {
- SMARTLIST_FOREACH(cache_entry->parsed->intro_nodes,
- rend_intro_point_t *, ip,
- ip->timed_out = 0; );
- }
-
- /* Remove the HS's entries in last_hid_serv_requests. */
- if (have_onion) {
- unsigned int replica;
- for (replica = 0; replica < ARRAY_LENGTH(rend_data_v2->descriptor_id);
- replica++) {
- const char *desc_id = rend_data_v2->descriptor_id[replica];
- purge_v2_hidserv_req(desc_id);
- }
- log_info(LD_REND, "Connection attempt for %s has ended; "
- "cleaning up temporary state.",
- safe_str_client(onion_address));
- } else {
- /* We only have an ID for a fetch. Probably used by HSFETCH. */
- purge_v2_hidserv_req(rend_data_v2->desc_id_fetch);
- }
-}
-
-/** Return a newly allocated extend_info_t* for a randomly chosen introduction
- * point for the named hidden service. Return NULL if all introduction points
- * have been tried and failed.
- */
-extend_info_t *
-rend_client_get_random_intro(const rend_data_t *rend_query)
-{
- int ret;
- extend_info_t *result;
- rend_cache_entry_t *entry;
- const char *onion_address = rend_data_get_address(rend_query);
-
- ret = rend_cache_lookup_entry(onion_address, -1, &entry);
- if (ret < 0 || !rend_client_any_intro_points_usable(entry)) {
- log_warn(LD_REND,
- "Query '%s' didn't have valid rend desc in cache. Failing.",
- safe_str_client(onion_address));
- /* XXX: Should we refetch the descriptor here if the IPs are not usable
- * anymore ?. */
- return NULL;
- }
-
- /* See if we can get a node that complies with ExcludeNodes */
- if ((result = rend_client_get_random_intro_impl(entry, 1, 1)))
- return result;
- /* If not, and StrictNodes is not set, see if we can return any old node
- */
- if (!get_options()->StrictNodes)
- return rend_client_get_random_intro_impl(entry, 0, 1);
- return NULL;
-}
-
-/** As rend_client_get_random_intro, except assume that StrictNodes is set
- * iff <b>strict</b> is true. If <b>warnings</b> is false, don't complain
- * to the user when we're out of nodes, even if StrictNodes is true.
- */
-static extend_info_t *
-rend_client_get_random_intro_impl(const rend_cache_entry_t *entry,
- const int strict,
- const int warnings)
-{
- int i;
-
- rend_intro_point_t *intro;
- const or_options_t *options = get_options();
- smartlist_t *usable_nodes;
- int n_excluded = 0;
- char service_id[REND_SERVICE_ID_LEN_BASE32 + 1];
-
- /* We'll keep a separate list of the usable nodes. If this becomes empty,
- * no nodes are usable. */
- usable_nodes = smartlist_new();
- smartlist_add_all(usable_nodes, entry->parsed->intro_nodes);
-
- /* Get service ID so we can use it to query the failure cache. If we fail to
- * parse it, this cache entry is no good. */
- if (BUG(rend_get_service_id(entry->parsed->pk, service_id) < 0)) {
- smartlist_free(usable_nodes);
- return NULL;
- }
-
- /* Remove the intro points that have timed out during this HS
- * connection attempt from our list of usable nodes. */
- SMARTLIST_FOREACH_BEGIN(usable_nodes, const rend_intro_point_t *, ip) {
- bool failed_intro =
- rend_cache_intro_failure_exists(service_id,
- (const uint8_t *) ip->extend_info->identity_digest);
- if (ip->timed_out || failed_intro) {
- SMARTLIST_DEL_CURRENT(usable_nodes, ip);
- };
- } SMARTLIST_FOREACH_END(ip);
-
- again:
- if (smartlist_len(usable_nodes) == 0) {
- if (n_excluded && get_options()->StrictNodes && warnings) {
- /* We only want to warn if StrictNodes is really set. Otherwise
- * we're just about to retry anyways.
- */
- log_warn(LD_REND, "All introduction points for hidden service are "
- "at excluded relays, and StrictNodes is set. Skipping.");
- }
- smartlist_free(usable_nodes);
- return NULL;
- }
-
- i = crypto_rand_int(smartlist_len(usable_nodes));
- intro = smartlist_get(usable_nodes, i);
- if (BUG(!intro->extend_info)) {
- /* This should never happen, but it isn't fatal, just try another */
- smartlist_del(usable_nodes, i);
- goto again;
- }
- /* All version 2 HS descriptors come with a TAP onion key.
- * Clients used to try to get the TAP onion key from the consensus, but this
- * meant that hidden services could discover which consensus clients have. */
- if (!extend_info_supports_tap(intro->extend_info)) {
- log_info(LD_REND, "The HS descriptor is missing a TAP onion key for the "
- "intro-point relay '%s'; trying another.",
- safe_str_client(extend_info_describe(intro->extend_info)));
- smartlist_del(usable_nodes, i);
- goto again;
- }
- /* Check if we should refuse to talk to this router. */
- if (strict &&
- routerset_contains_extendinfo(options->ExcludeNodes,
- intro->extend_info)) {
- n_excluded++;
- smartlist_del(usable_nodes, i);
- goto again;
- }
-
- smartlist_free(usable_nodes);
- return extend_info_dup(intro->extend_info);
-}
-
-/** Return true iff any introduction points still listed in <b>entry</b> are
- * usable. */
-int
-rend_client_any_intro_points_usable(const rend_cache_entry_t *entry)
-{
- extend_info_t *extend_info =
- rend_client_get_random_intro_impl(entry, get_options()->StrictNodes, 0);
-
- int rv = (extend_info != NULL);
-
- extend_info_free(extend_info);
- return rv;
-}
-
-/** Client-side authorizations for hidden services; map of onion address to
- * rend_service_authorization_t*. */
-static strmap_t *auth_hid_servs = NULL;
-
-/** Look up the client-side authorization for the hidden service with
- * <b>onion_address</b>. Return NULL if no authorization is available for
- * that address. */
-rend_service_authorization_t*
-rend_client_lookup_service_authorization(const char *onion_address)
-{
- tor_assert(onion_address);
- if (!auth_hid_servs) return NULL;
- return strmap_get(auth_hid_servs, onion_address);
-}
-
-#define rend_service_authorization_free(val) \
- FREE_AND_NULL(rend_service_authorization_t, \
- rend_service_authorization_free_, (val))
-
-/** Helper: Free storage held by rend_service_authorization_t. */
-static void
-rend_service_authorization_free_(rend_service_authorization_t *auth)
-{
- tor_free(auth);
-}
-
-/** Helper for strmap_free. */
-static void
-rend_service_authorization_free_void(void *service_auth)
-{
- rend_service_authorization_free_(service_auth);
-}
-
-/** Release all the storage held in auth_hid_servs.
- */
-void
-rend_service_authorization_free_all(void)
-{
- if (!auth_hid_servs) {
- return;
- }
- strmap_free(auth_hid_servs, rend_service_authorization_free_void);
- auth_hid_servs = NULL;
-}
-
-/** Parse <b>config_line</b> as a client-side authorization for a hidden
- * service and add it to the local map of hidden service authorizations.
- * Return 0 for success and -1 for failure. */
-int
-rend_parse_service_authorization(const or_options_t *options,
- int validate_only)
-{
- config_line_t *line;
- int res = -1;
- strmap_t *parsed = strmap_new();
- smartlist_t *sl = smartlist_new();
- rend_service_authorization_t *auth = NULL;
- char *err_msg = NULL;
-
- for (line = options->HidServAuth; line; line = line->next) {
- char *onion_address, *descriptor_cookie;
- auth = NULL;
- SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
- smartlist_clear(sl);
- smartlist_split_string(sl, line->value, " ",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
- if (smartlist_len(sl) < 2) {
- log_warn(LD_CONFIG, "Configuration line does not consist of "
- "\"onion-address authorization-cookie [service-name]\": "
- "'%s'", line->value);
- goto err;
- }
- auth = tor_malloc_zero(sizeof(rend_service_authorization_t));
- /* Parse onion address. */
- onion_address = smartlist_get(sl, 0);
- if (strlen(onion_address) != REND_SERVICE_ADDRESS_LEN ||
- strcmpend(onion_address, ".onion")) {
- log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
- onion_address);
- goto err;
- }
- strlcpy(auth->onion_address, onion_address, REND_SERVICE_ID_LEN_BASE32+1);
- if (!rend_valid_v2_service_id(auth->onion_address)) {
- log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
- onion_address);
- goto err;
- }
- /* Parse descriptor cookie. */
- descriptor_cookie = smartlist_get(sl, 1);
- if (rend_auth_decode_cookie(descriptor_cookie, auth->descriptor_cookie,
- &auth->auth_type, &err_msg) < 0) {
- tor_assert(err_msg);
- log_warn(LD_CONFIG, "%s", err_msg);
- tor_free(err_msg);
- goto err;
- }
- if (strmap_get(parsed, auth->onion_address)) {
- log_warn(LD_CONFIG, "Duplicate authorization for the same hidden "
- "service.");
- goto err;
- }
- strmap_set(parsed, auth->onion_address, auth);
- auth = NULL;
- }
- res = 0;
- goto done;
- err:
- res = -1;
- done:
- rend_service_authorization_free(auth);
- SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
- smartlist_free(sl);
- if (!validate_only && res == 0) {
- rend_service_authorization_free_all();
- auth_hid_servs = parsed;
- } else {
- strmap_free(parsed, rend_service_authorization_free_void);
- }
- return res;
-}
-
-/** The given circuit is being freed. Take appropriate action if it is of
- * interest to the client subsystem. */
-void
-rend_client_circuit_cleanup_on_free(const circuit_t *circ)
-{
- int reason, orig_reason;
- bool has_timed_out, ip_is_redundant;
- const origin_circuit_t *ocirc = NULL;
-
- tor_assert(circ);
- tor_assert(CIRCUIT_IS_ORIGIN(circ));
-
- reason = circ->marked_for_close_reason;
- orig_reason = circ->marked_for_close_orig_reason;
- ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
- tor_assert(ocirc->rend_data);
-
- has_timed_out = (reason == END_CIRC_REASON_TIMEOUT);
- ip_is_redundant = (orig_reason == END_CIRC_REASON_IP_NOW_REDUNDANT);
-
- switch (circ->purpose) {
- case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
- {
- if (ip_is_redundant) {
- break;
- }
- tor_assert(circ->state == CIRCUIT_STATE_OPEN);
- tor_assert(ocirc->build_state->chosen_exit);
- /* Treat this like getting a nack from it */
- log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s",
- safe_str_client(rend_data_get_address(ocirc->rend_data)),
- safe_str_client(build_state_get_exit_nickname(ocirc->build_state)),
- has_timed_out ? "Recording timeout." : "Removing from descriptor.");
- rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
- ocirc->rend_data,
- has_timed_out ?
- INTRO_POINT_FAILURE_TIMEOUT :
- INTRO_POINT_FAILURE_GENERIC);
- break;
- }
- case CIRCUIT_PURPOSE_C_INTRODUCING:
- {
- /* Ignore if we were introducing and it timed out, we didn't pick an exit
- * point yet (IP) or the reason indicate that it was a redundant IP. */
- if (has_timed_out || !ocirc->build_state->chosen_exit || ip_is_redundant) {
- break;
- }
- log_info(LD_REND, "Failed intro circ %s to %s "
- "(building circuit to intro point). "
- "Marking intro point as possibly unreachable.",
- safe_str_client(rend_data_get_address(ocirc->rend_data)),
- safe_str_client(build_state_get_exit_nickname(
- ocirc->build_state)));
- rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
- ocirc->rend_data,
- INTRO_POINT_FAILURE_UNREACHABLE);
- break;
- }
- default:
- break;
- }
-}
diff --git a/src/feature/rend/rendclient.h b/src/feature/rend/rendclient.h
deleted file mode 100644
index b7aa212487..0000000000
--- a/src/feature/rend/rendclient.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 2001 Matej Pfajfar.
- * Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2020, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file rendclient.h
- * \brief Header file for rendclient.c.
- **/
-
-#ifndef TOR_RENDCLIENT_H
-#define TOR_RENDCLIENT_H
-
-#include "feature/hs/hs_circuit.h"
-#include "feature/rend/rendcache.h"
-
-void rend_client_purge_state(void);
-
-void rend_client_introcirc_has_opened(origin_circuit_t *circ);
-void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
-int rend_client_introduction_acked(origin_circuit_t *circ,
- const uint8_t *request,
- size_t request_len);
-void rend_client_refetch_v2_renddesc(rend_data_t *rend_query);
-int rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs);
-void rend_client_cancel_descriptor_fetches(void);
-
-int rend_client_report_intro_point_failure(extend_info_t *failed_intro,
- rend_data_t *rend_data,
- unsigned int failure_type);
-
-int rend_client_receive_rendezvous(origin_circuit_t *circ,
- const uint8_t *request,
- size_t request_len);
-void rend_client_desc_trynow(const char *query);
-
-void rend_client_note_connection_attempt_ended(const rend_data_t *rend_data);
-
-extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
-int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry);
-
-int rend_client_send_introduction(origin_circuit_t *introcirc,
- origin_circuit_t *rendcirc);
-int rend_parse_service_authorization(const or_options_t *options,
- int validate_only);
-rend_service_authorization_t *rend_client_lookup_service_authorization(
- const char *onion_address);
-void rend_service_authorization_free_all(void);
-
-void rend_client_circuit_cleanup_on_free(const circuit_t *circ);
-
-#endif /* !defined(TOR_RENDCLIENT_H) */
-
diff --git a/src/feature/rend/rendcommon.c b/src/feature/rend/rendcommon.c
index f00dfee68a..275ee52968 100644
--- a/src/feature/rend/rendcommon.c
+++ b/src/feature/rend/rendcommon.c
@@ -23,7 +23,7 @@
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_intropoint.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/rend/rendclient.h"
+#include "feature/rend/rendcache.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendmid.h"
#include "feature/rend/rendparse.h"
diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c
index add25579b3..2be68eadbe 100644
--- a/src/feature/rend/rendservice.c
+++ b/src/feature/rend/rendservice.c
@@ -34,7 +34,6 @@
#include "feature/nodelist/node_select.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendparse.h"
#include "feature/rend/rendservice.h"
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 73c8ca0549..5bca3e04fc 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -41,7 +41,6 @@
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"
-#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"
#include "feature/relay/relay_find_addr.h"
#include "feature/relay/router.h"
diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c
index 6a8603cbf8..11840b2c4f 100644
--- a/src/test/test_entryconn.c
+++ b/src/test/test_entryconn.c
@@ -728,46 +728,6 @@ test_entryconn_rewrite_mapaddress_automap_onion4(void *arg)
test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1);
}
-/** Test that rewrite functions can handle v2 addresses */
-static void
-test_entryconn_rewrite_onion_v2(void *arg)
-{
- int retval;
- entry_connection_t *conn = arg;
-
- (void) arg;
-
- rend_cache_init();
-
- /* Make a SOCKS request */
- conn->socks_request->command = SOCKS_COMMAND_CONNECT;
- strlcpy(conn->socks_request->address,
- "pqeed46efnwmfuid.onion",
- sizeof(conn->socks_request->address));
-
- /* Make an onion connection using the SOCKS request */
- conn->entry_cfg.onion_traffic = 1;
- ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_SOCKS_WAIT;
- tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data);
-
- /* Handle SOCKS and rewrite! */
- retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
- tt_int_op(retval, OP_EQ, 0);
-
- /* Check connection state after rewrite */
- tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT);
- /* check that the address got rewritten */
- tt_str_op(conn->socks_request->address, OP_EQ,
- "pqeed46efnwmfuid");
- /* check that HS information got attached to the connection */
- tt_assert(ENTRY_TO_EDGE_CONN(conn)->rend_data);
- tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident);
-
- done:
- rend_cache_free_all();
- /* 'conn' is cleaned by handler */
-}
-
/** Test that rewrite functions can handle v3 onion addresses */
static void
test_entryconn_rewrite_onion_v3(void *arg)
@@ -830,7 +790,6 @@ struct testcase_t entryconn_tests[] = {
REWRITE(rewrite_mapaddress_automap_onion2),
REWRITE(rewrite_mapaddress_automap_onion3),
REWRITE(rewrite_mapaddress_automap_onion4),
- REWRITE(rewrite_onion_v2),
REWRITE(rewrite_onion_v3),
END_OF_TESTCASES
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index 5032a82b9c..916b7e4a04 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -787,11 +787,8 @@ test_parse_extended_hostname(void *arg)
hostname_type_t type;
char address1[] = "fooaddress.onion";
- char address2[] = "aaaaaaaaaaaaaaaa.onion";
char address3[] = "fooaddress.exit";
char address4[] = "www.torproject.org";
- char address5[] = "foo.abcdefghijklmnop.onion";
- char address6[] = "foo.bar.abcdefghijklmnop.onion";
char address7[] = ".abcdefghijklmnop.onion";
char address8[] =
"www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion";
@@ -803,24 +800,12 @@ test_parse_extended_hostname(void *arg)
tt_assert(!parse_extended_hostname(address1, &type));
tt_int_op(type, OP_EQ, BAD_HOSTNAME);
- tt_assert(parse_extended_hostname(address2, &type));
- tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
- tt_str_op(address2, OP_EQ, "aaaaaaaaaaaaaaaa");
-
tt_assert(parse_extended_hostname(address3, &type));
tt_int_op(type, OP_EQ, EXIT_HOSTNAME);
tt_assert(parse_extended_hostname(address4, &type));
tt_int_op(type, OP_EQ, NORMAL_HOSTNAME);
- tt_assert(parse_extended_hostname(address5, &type));
- tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
- tt_str_op(address5, OP_EQ, "abcdefghijklmnop");
-
- tt_assert(parse_extended_hostname(address6, &type));
- tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
- tt_str_op(address6, OP_EQ, "abcdefghijklmnop");
-
tt_assert(!parse_extended_hostname(address7, &type));
tt_int_op(type, OP_EQ, BAD_HOSTNAME);
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 714ee4767f..653b647dfe 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -2389,14 +2389,6 @@ test_options_validate__rend(void *ignored)
"Failed to configure rendezvous options. See logs for details.");
tor_free(msg);
- free_options_test_data(tdata);
- tdata = get_options_test_data("HidServAuth failed\n");
- ret = options_validate(NULL, tdata->opt, &msg);
- tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ, "Failed to configure client authorization for hidden "
- "services. See logs for details.");
- tor_free(msg);
-
done:
policies_free_all();
teardown_capture_of_logs();