diff options
Diffstat (limited to 'src/feature/hs')
-rw-r--r-- | src/feature/hs/hs_cache.c | 81 | ||||
-rw-r--r-- | src/feature/hs/hs_cache.h | 20 | ||||
-rw-r--r-- | src/feature/hs/hs_cell.c | 78 | ||||
-rw-r--r-- | src/feature/hs/hs_circuit.c | 157 | ||||
-rw-r--r-- | src/feature/hs/hs_client.c | 7 | ||||
-rw-r--r-- | src/feature/hs/hs_common.c | 261 | ||||
-rw-r--r-- | src/feature/hs/hs_common.h | 23 | ||||
-rw-r--r-- | src/feature/hs/hs_config.c | 55 | ||||
-rw-r--r-- | src/feature/hs/hs_descriptor.c | 1 | ||||
-rw-r--r-- | src/feature/hs/hs_service.c | 97 | ||||
-rw-r--r-- | src/feature/hs/hs_service.h | 5 |
11 files changed, 154 insertions, 631 deletions
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index 765323df0d..ac43e78767 100644 --- a/src/feature/hs/hs_cache.c +++ b/src/feature/hs/hs_cache.c @@ -19,13 +19,15 @@ #include "feature/hs/hs_descriptor.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" -#include "feature/rend/rendcache.h" #include "feature/stats/rephist.h" #include "feature/hs/hs_cache.h" #include "feature/nodelist/networkstatus_st.h" +/* Total counter of the cache size. */ +static size_t hs_cache_total_allocation = 0; + static int cached_client_descriptor_has_expired(time_t now, const hs_cache_client_descriptor_t *cached_desc); @@ -164,7 +166,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc) * remove the entry we currently have from our cache so we can then * store the new one. */ remove_v3_desc_as_dir(cache_entry); - rend_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry)); + hs_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry)); cache_dir_desc_free(cache_entry); } /* Store the descriptor we just got. We are sure here that either we @@ -174,7 +176,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc) /* Update our total cache size with this entry for the OOM. This uses the * old HS protocol cache subsystem for which we are tied with. */ - rend_cache_increment_allocation(cache_get_dir_entry_size(desc)); + hs_cache_increment_allocation(cache_get_dir_entry_size(desc)); /* Update HSv3 statistics */ if (get_options()->HiddenServiceStatistics) { @@ -259,7 +261,7 @@ cache_clean_v3_as_dir(time_t now, time_t global_cutoff) /* Entry is not in the cache anymore, destroy it. */ cache_dir_desc_free(entry); /* Update our cache entry allocation size for the OOM. */ - rend_cache_decrement_allocation(entry_size); + hs_cache_decrement_allocation(entry_size); /* Logging. */ { char key_b64[BASE64_DIGEST256_LEN + 1]; @@ -336,12 +338,6 @@ hs_cache_lookup_as_dir(uint32_t version, const char *query, void hs_cache_clean_as_dir(time_t now) { - time_t cutoff; - - /* Start with v2 cache cleaning. */ - cutoff = now - rend_cache_max_entry_lifetime(); - rend_cache_clean_v2_descs_as_dir(cutoff); - /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function * to compute the cutoff by itself using the lifetime value. */ cache_clean_v3_as_dir(now, 0); @@ -387,7 +383,7 @@ remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc) tor_assert(desc); digest256map_remove(hs_cache_v3_client, desc->key.pubkey); /* Update cache size with this entry for the OOM handler. */ - rend_cache_decrement_allocation(cache_get_client_entry_size(desc)); + hs_cache_decrement_allocation(cache_get_client_entry_size(desc)); } /** Store a given descriptor in our cache. */ @@ -397,7 +393,7 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *desc) tor_assert(desc); digest256map_set(hs_cache_v3_client, desc->key.pubkey, desc); /* Update cache size with this entry for the OOM handler. */ - rend_cache_increment_allocation(cache_get_client_entry_size(desc)); + hs_cache_increment_allocation(cache_get_client_entry_size(desc)); } /** Query our cache and return the entry or NULL if not found or if expired. */ @@ -796,7 +792,7 @@ cache_clean_v3_as_client(time_t now) cache_client_desc_free(entry); /* Update our OOM. We didn't use the remove() function because we are in * a loop so we have to explicitly decrement. */ - rend_cache_decrement_allocation(entry_size); + hs_cache_decrement_allocation(entry_size); /* Logging. */ { char key_b64[BASE64_DIGEST256_LEN + 1]; @@ -934,8 +930,6 @@ hs_cache_remove_as_client(const ed25519_public_key_t *key) void hs_cache_clean_as_client(time_t now) { - /* Start with v2 cache cleaning. */ - rend_cache_clean(now, REND_CACHE_TYPE_CLIENT); /* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function * to compute the cutoff by itself using the lifetime value. */ cache_clean_v3_as_client(now); @@ -952,7 +946,7 @@ hs_cache_purge_as_client(void) cache_client_desc_free(entry); /* Update our OOM. We didn't use the remove() function because we are in * a loop so we have to explicitly decrement. */ - rend_cache_decrement_allocation(entry_size); + hs_cache_decrement_allocation(entry_size); } DIGEST256MAP_FOREACH_END; log_info(LD_REND, "Hidden service client descriptor cache purged."); @@ -1074,19 +1068,16 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes) /* The algorithm is as follow. K is the oldest expected descriptor age. * - * 1) Deallocate all entries from v2 cache that are older than K hours. - * 1.1) If the amount of remove bytes has been reached, stop. - * 2) Deallocate all entries from v3 cache that are older than K hours + * 1) Deallocate all entries from v3 cache that are older than K hours * 2.1) If the amount of remove bytes has been reached, stop. - * 3) Set K = K - RendPostPeriod and repeat process until K is < 0. + * 2) Set K = K - RendPostPeriod and repeat process until K is < 0. * * This ends up being O(Kn). */ /* Set K to the oldest expected age in seconds which is the maximum - * lifetime of a cache entry. We'll use the v2 lifetime because it's much - * bigger than the v3 thus leading to cleaning older descriptors. */ - k = rend_cache_max_entry_lifetime(); + * lifetime of a cache entry. */ + k = hs_cache_max_entry_lifetime(); do { time_t cutoff; @@ -1099,9 +1090,6 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes) /* Compute a cutoff value with K and the current time. */ cutoff = now - k; - /* Start by cleaning the v2 cache with that cutoff. */ - bytes_removed += rend_cache_clean_v2_descs_as_dir(cutoff); - if (bytes_removed < min_remove_bytes) { /* We haven't remove enough bytes so clean v3 cache. */ bytes_removed += cache_clean_v3_as_dir(now, cutoff); @@ -1150,4 +1138,45 @@ hs_cache_free_all(void) digest256map_free(hs_cache_client_intro_state, cache_client_intro_state_free_void); hs_cache_client_intro_state = NULL; + hs_cache_total_allocation = 0; +} + +/* Return total size of the cache. */ +size_t +hs_cache_get_total_allocation(void) +{ + return hs_cache_total_allocation; +} + +/** Decrement the total bytes attributed to the rendezvous cache by n. */ +void +hs_cache_decrement_allocation(size_t n) +{ + static int have_underflowed = 0; + + if (hs_cache_total_allocation >= n) { + hs_cache_total_allocation -= n; + } else { + hs_cache_total_allocation = 0; + if (! have_underflowed) { + have_underflowed = 1; + log_warn(LD_BUG, "Underflow in hs_cache_decrement_allocation"); + } + } +} + +/** Increase the total bytes attributed to the rendezvous cache by n. */ +void +hs_cache_increment_allocation(size_t n) +{ + static int have_overflowed = 0; + if (hs_cache_total_allocation <= SIZE_MAX - n) { + hs_cache_total_allocation += n; + } else { + hs_cache_total_allocation = SIZE_MAX; + if (! have_overflowed) { + have_overflowed = 1; + log_warn(LD_BUG, "Overflow in hs_cache_increment_allocation"); + } + } } diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h index bb3c77f224..e8165569db 100644 --- a/src/feature/hs/hs_cache.h +++ b/src/feature/hs/hs_cache.h @@ -21,6 +21,14 @@ struct ed25519_public_key_t; /** This is the maximum time an introduction point state object can stay in the * client cache in seconds (2 mins or 120 seconds). */ #define HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE (2 * 60) +/** How old do we let hidden service descriptors get before discarding + * them as too old? */ +#define HS_CACHE_MAX_AGE (2*24*60*60) +/** How wrong do we assume our clock may be when checking whether hidden + * services are too old or too new? */ +#define HS_CACHE_MAX_SKEW (24*60*60) +/** How old do we keep an intro point failure entry in the failure cache? */ +#define HS_CACHE_FAILURE_MAX_AGE (5*60) /** Introduction point state. */ typedef struct hs_cache_intro_state_t { @@ -57,7 +65,6 @@ typedef struct hs_cache_dir_descriptor_t { /** Descriptor plaintext information. Obviously, we can't decrypt the * encrypted part of the descriptor. */ hs_desc_plaintext_data_t *plaintext_data; - /** Encoded descriptor which is basically in text form. It's a NUL terminated * string thus safe to strlen(). */ char *encoded_desc; @@ -65,6 +72,13 @@ typedef struct hs_cache_dir_descriptor_t { /* Public API */ +/* Return maximum lifetime in seconds of a cache entry. */ +static inline time_t +hs_cache_max_entry_lifetime(void) +{ + return HS_CACHE_MAX_AGE + HS_CACHE_MAX_SKEW; +} + void hs_cache_init(void); void hs_cache_free_all(void); void hs_cache_clean_as_dir(time_t now); @@ -102,6 +116,10 @@ void hs_cache_client_intro_state_purge(void); bool hs_cache_client_new_auth_parse(const ed25519_public_key_t *service_pk); +size_t hs_cache_get_total_allocation(void); +void hs_cache_decrement_allocation(size_t n); +void hs_cache_increment_allocation(size_t n); + #ifdef HS_CACHE_PRIVATE #include "lib/crypt_ops/crypto_ed25519.h" diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c index 8bdaa4922a..01dd39e231 100644 --- a/src/feature/hs/hs_cell.c +++ b/src/feature/hs/hs_cell.c @@ -9,7 +9,6 @@ #include "core/or/or.h" #include "app/config/config.h" #include "lib/crypt_ops/crypto_util.h" -#include "feature/rend/rendservice.h" #include "feature/hs_common/replaycache.h" #include "feature/hs/hs_cell.h" @@ -194,37 +193,10 @@ parse_introduce2_encrypted(const uint8_t *decrypted_data, return NULL; } -/** Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA - * encryption key. The encoded cell is put in cell_out that MUST at least be - * of the size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on - * success else a negative value and cell_out is untouched. */ -static ssize_t -build_legacy_establish_intro(const char *circ_nonce, crypto_pk_t *enc_key, - uint8_t *cell_out) -{ - ssize_t cell_len; - - tor_assert(circ_nonce); - tor_assert(enc_key); - tor_assert(cell_out); - - memwipe(cell_out, 0, RELAY_PAYLOAD_SIZE); - - cell_len = rend_service_encode_establish_intro_cell((char*)cell_out, - RELAY_PAYLOAD_SIZE, - enc_key, circ_nonce); - return cell_len; -} - /** Parse an INTRODUCE2 cell from payload of size payload_len for the given * service and circuit which are used only for logging purposes. The resulting * parsed cell is put in cell_ptr_out. * - * This function only parses prop224 INTRODUCE2 cells even when the intro point - * is a legacy intro point. That's because intro points don't actually care - * about the contents of the introduce cell. Legacy INTRODUCE cells are only - * used by the legacy system now. - * * Return 0 on success else a negative value and cell_ptr_out is untouched. */ static int parse_introduce2_cell(const hs_service_t *service, @@ -457,28 +429,6 @@ introduce1_set_auth_key(trn_cell_introduce1_t *cell, data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell)); } -/** Set the legacy ID field in the INTRODUCE1 cell from the given data. */ -static void -introduce1_set_legacy_id(trn_cell_introduce1_t *cell, - const hs_cell_introduce1_data_t *data) -{ - tor_assert(cell); - tor_assert(data); - - if (data->is_legacy) { - uint8_t digest[DIGEST_LEN]; - if (BUG(crypto_pk_get_digest(data->legacy_key, (char *) digest) < 0)) { - return; - } - memcpy(trn_cell_introduce1_getarray_legacy_key_id(cell), - digest, trn_cell_introduce1_getlen_legacy_key_id(cell)); - } else { - /* We have to zeroed the LEGACY_KEY_ID field. */ - memset(trn_cell_introduce1_getarray_legacy_key_id(cell), 0, - trn_cell_introduce1_getlen_legacy_key_id(cell)); - } -} - /** Build and add to the given DoS cell extension the given parameter type and * value. */ static void @@ -608,8 +558,7 @@ build_establish_intro_extensions(const hs_service_config_t *service_config, /** Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point * object. The encoded cell is put in cell_out that MUST at least be of the * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else - * a negative value and cell_out is untouched. This function also supports - * legacy cell creation. */ + * a negative value and cell_out is untouched. */ ssize_t hs_cell_build_establish_intro(const char *circ_nonce, const hs_service_config_t *service_config, @@ -625,16 +574,6 @@ hs_cell_build_establish_intro(const char *circ_nonce, tor_assert(service_config); tor_assert(ip); - /* Quickly handle the legacy IP. */ - if (ip->base.is_only_legacy) { - tor_assert(ip->legacy_key); - cell_len = build_legacy_establish_intro(circ_nonce, ip->legacy_key, - cell_out); - tor_assert(cell_len <= RELAY_PAYLOAD_SIZE); - /* Success or not we are done here. */ - goto done; - } - /* Build the extensions, if any. */ extensions = build_establish_intro_extensions(service_config, ip); @@ -1022,9 +961,6 @@ hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, trn_cell_extension_set_num(ext, 0); trn_cell_introduce1_set_extensions(cell, ext); - /* Set the legacy ID field. */ - introduce1_set_legacy_id(cell, data); - /* Set the authentication key. */ introduce1_set_auth_key(cell, data); @@ -1067,18 +1003,6 @@ hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len) tor_assert(payload); - /* If it is a legacy IP, rend-spec.txt specifies that a ACK is 0 byte and a - * NACK is 1 byte. We can't use the legacy function for this so we have to - * do a special case. */ - if (payload_len <= 1) { - if (payload_len == 0) { - ret = TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS; - } else { - ret = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID; - } - goto end; - } - if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) { log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it."); goto end; diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index b246ab423c..548e1cbe2a 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -28,7 +28,6 @@ #include "feature/hs/hs_service.h" #include "feature/nodelist/describe.h" #include "feature/nodelist/nodelist.h" -#include "feature/rend/rendservice.h" #include "feature/stats/rephist.h" #include "lib/crypt_ops/crypto_dh.h" #include "lib/crypt_ops/crypto_rand.h" @@ -105,57 +104,6 @@ create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len, return cpath; } -/** We are a v2 legacy HS client: Create and return a crypt path for the hidden - * service on the other side of the rendezvous circuit <b>circ</b>. Initialize - * the crypt path crypto using the body of the RENDEZVOUS1 cell at - * <b>rend_cell_body</b> (which must be at least DH1024_KEY_LEN+DIGEST_LEN - * bytes). - */ -static crypt_path_t * -create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body) -{ - crypt_path_t *hop = NULL; - char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN]; - - /* first DH1024_KEY_LEN bytes are g^y from the service. Finish the dh - * handshake...*/ - tor_assert(circ->build_state); - tor_assert(circ->build_state->pending_final_cpath); - hop = circ->build_state->pending_final_cpath; - - tor_assert(hop->rend_dh_handshake_state); - if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state, - (char*)rend_cell_body, DH1024_KEY_LEN, - keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) { - log_warn(LD_GENERAL, "Couldn't complete DH handshake."); - goto err; - } - /* ... and set up cpath. */ - if (cpath_init_circuit_crypto(hop, - keys+DIGEST_LEN, sizeof(keys)-DIGEST_LEN, - 0, 0) < 0) - goto err; - - /* Check whether the digest is right... */ - if (tor_memneq(keys, rend_cell_body+DH1024_KEY_LEN, DIGEST_LEN)) { - log_warn(LD_PROTOCOL, "Incorrect digest of key material."); - goto err; - } - - /* clean up the crypto stuff we just made */ - crypto_dh_free(hop->rend_dh_handshake_state); - hop->rend_dh_handshake_state = NULL; - - goto done; - - err: - hop = NULL; - - done: - memwipe(keys, 0, sizeof(keys)); - return hop; -} - /** Append the final <b>hop</b> to the cpath of the rend <b>circ</b>, and mark * <b>circ</b> ready for use to transfer HS relay cells. */ static void @@ -184,13 +132,6 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop, /* Append the hop to the cpath of this circuit */ cpath_extend_linked_list(&circ->cpath, hop); - /* In legacy code, 'pending_final_cpath' points to the final hop we just - * appended to the cpath. We set the original pointer to NULL so that we - * don't double free it. */ - if (circ->build_state) { - circ->build_state->pending_final_cpath = NULL; - } - /* Finally, mark circuit as ready to be used for client streams */ if (!is_service_side) { circuit_try_attaching_streams(circ); @@ -198,7 +139,7 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop, } /** For a given circuit and a service introduction point object, register the - * intro circuit to the circuitmap. This supports legacy intro point. */ + * intro circuit to the circuitmap. */ static void register_intro_circ(const hs_service_intro_point_t *ip, origin_circuit_t *circ) @@ -206,13 +147,8 @@ register_intro_circ(const hs_service_intro_point_t *ip, tor_assert(ip); tor_assert(circ); - if (ip->base.is_only_legacy) { - hs_circuitmap_register_intro_circ_v2_service_side(circ, - ip->legacy_key_digest); - } else { - hs_circuitmap_register_intro_circ_v3_service_side(circ, - &ip->auth_key_kp.pubkey); - } + hs_circuitmap_register_intro_circ_v3_service_side(circ, + &ip->auth_key_kp.pubkey); } /** Return the number of opened introduction circuit for the given circuit that @@ -605,10 +541,6 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip, /* Populate the introduce1 data object. */ memset(intro1_data, 0, sizeof(hs_cell_introduce1_data_t)); - if (ip->legacy.key != NULL) { - intro1_data->is_legacy = 1; - intro1_data->legacy_key = ip->legacy.key; - } intro1_data->auth_pk = &ip->auth_key_cert->signed_key; intro1_data->enc_pk = &ip->enc_key; intro1_data->subcredential = subcredential; @@ -635,8 +567,8 @@ cleanup_on_close_client_circ(circuit_t *circ) if (circuit_is_hs_v3(circ)) { hs_client_circuit_cleanup_on_close(circ); } - /* It is possible the circuit has an HS purpose but no identifier (rend_data - * or hs_ident). Thus possible that this passes through. */ + /* It is possible the circuit has an HS purpose but no identifier (hs_ident). + * Thus possible that this passes through. */ } /** Helper: cleanup function for client circuit. This is for every HS version. @@ -649,8 +581,8 @@ cleanup_on_free_client_circ(circuit_t *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 - * or hs_ident). Thus possible that this passes through. */ + /* It is possible the circuit has an HS purpose but no identifier (hs_ident). + * Thus possible that this passes through. */ } /* ========== */ @@ -664,12 +596,7 @@ hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip) { tor_assert(ip); - if (ip->base.is_only_legacy) { - return hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest); - } else { - return hs_circuitmap_get_intro_circ_v3_service_side( - &ip->auth_key_kp.pubkey); - } + return hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey); } /** Return an introduction point established circuit matching the given intro @@ -682,12 +609,7 @@ hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip) tor_assert(ip); - if (ip->base.is_only_legacy) { - circ = hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest); - } else { - circ = hs_circuitmap_get_intro_circ_v3_service_side( - &ip->auth_key_kp.pubkey); - } + circ = hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey); /* Only return circuit if it is established. */ return (circ && TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_INTRO) ? @@ -695,8 +617,7 @@ hs_circ_service_get_established_intro_circ(const hs_service_intro_point_t *ip) } /** Called when we fail building a rendezvous circuit at some point other than - * the last hop: launches a new circuit to the same rendezvous point. This - * supports legacy service. + * the last hop: launches a new circuit to the same rendezvous point. * * We currently relaunch connections to rendezvous points if: * - A rendezvous circuit timed out before connecting to RP. @@ -726,8 +647,6 @@ hs_circ_retry_service_rendezvous_point(origin_circuit_t *circ) /* Legacy services don't have a hidden service ident. */ if (circ->hs_ident) { retry_service_rendezvous_point(circ); - } else { - rend_service_relaunch_rendezvous(circ); } done: @@ -762,9 +681,7 @@ hs_circ_launch_intro_point(hs_service_t *service, goto end; } /* We only use a one-hop path on the first attempt. If the first attempt - * fails, we use a 3-hop path for reachability / reliability. - * (Unlike v2, retries is incremented by the caller before it calls this - * function.) */ + * fails, we use a 3-hop path for reachability / reliability. */ if (direct_conn && ip->circuit_retries == 1) { circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL; } @@ -952,10 +869,8 @@ hs_circ_handle_intro_established(const hs_service_t *service, } /* Try to parse the payload into a cell making sure we do actually have a - * valid cell. For a legacy node, it's an empty payload so as long as we - * have the cell, we are good. */ - if (!ip->base.is_only_legacy && - hs_cell_parse_intro_established(payload, payload_len) < 0) { + * valid cell. */ + if (hs_cell_parse_intro_established(payload, payload_len) < 0) { log_warn(LD_REND, "Unable to parse the INTRO_ESTABLISHED cell on " "circuit %u for service %s", TO_CIRCUIT(circ)->n_circ_id, @@ -1112,31 +1027,6 @@ hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, return 0; } -/** We are a v2 legacy HS client and we just received a RENDEZVOUS1 cell - * <b>rend_cell_body</b> on <b>circ</b>. Finish up the DH key exchange and then - * extend the crypt path of <b>circ</b> so that the hidden service is on the - * other side. */ -int -hs_circuit_setup_e2e_rend_circ_legacy_client(origin_circuit_t *circ, - const uint8_t *rend_cell_body) -{ - - if (BUG(!circuit_purpose_is_correct_for_rend( - TO_CIRCUIT(circ)->purpose, 0))) { - return -1; - } - - crypt_path_t *hop = create_rend_cpath_legacy(circ, rend_cell_body); - if (!hop) { - log_warn(LD_GENERAL, "Couldn't get v2 cpath."); - return -1; - } - - finalize_rend_circuit(circ, hop, 0); - - return 0; -} - /** Given the introduction circuit intro_circ, the rendezvous circuit * rend_circ, a descriptor intro point object ip and the service's * subcredential, send an INTRODUCE1 cell on intro_circ. @@ -1381,31 +1271,20 @@ hs_circ_is_rend_sent_in_intro1(const origin_circuit_t *circ) * confirmed rendezsvous circuit but without an introduction ACK. */ tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_REND_READY); - /* The v2 and v3 circuit are handled differently: - * - * v2: A circ's pending_final_cpath field is non-NULL iff it is a rend circ - * and we have tried to send an INTRODUCE1 cell specifying it. Thus, if the - * pending_final_cpath field *is* NULL, then we want to not spare it. - * - * v3: When the INTRODUCE1 cell is sent, the introduction encryption public + /* When the INTRODUCE1 cell is sent, the introduction encryption public * key is copied in the rendezvous circuit hs identifier. If it is a valid * key, we know that this circuit is waiting the ACK on the introduction * circuit. We want to _not_ spare the circuit if the key was never set. */ - if (circ->rend_data) { - /* v2. */ - if (circ->build_state && circ->build_state->pending_final_cpath != NULL) { - return true; - } - } else if (circ->hs_ident) { + if (circ->hs_ident) { /* v3. */ if (curve25519_public_key_is_ok(&circ->hs_ident->intro_enc_pk)) { return true; } } else { - /* A circuit with an HS purpose without an hs_ident or rend_data in theory - * can not happen. In case, scream loudly and return false to the caller - * that the rendezvous was not sent in the INTRO1 cell. */ + /* A circuit with an HS purpose without an hs_ident in theory can not + * happen. In case, scream loudly and return false to the caller that the + * rendezvous was not sent in the INTRO1 cell. */ tor_assert_nonfatal_unreached(); } diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index 28bbe72459..f1c17f4f90 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -1950,11 +1950,6 @@ hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn) { tor_assert(connection_edge_is_rendezvous_stream(conn)); - if (BUG(conn->rend_data && conn->hs_ident)) { - log_warn(LD_BUG, "Stream had both rend_data and hs_ident..." - "Prioritizing hs_ident"); - } - if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */ note_connection_attempt_succeeded(conn->hs_ident); return; @@ -2094,8 +2089,6 @@ hs_client_circuit_has_opened(origin_circuit_t *circ) { tor_assert(circ); - /* Handle both version. v2 uses rend_data and v3 uses the hs circuit - * identifier hs_ident. Can't be both. */ switch (TO_CIRCUIT(circ)->purpose) { case CIRCUIT_PURPOSE_C_INTRODUCING: if (circ->hs_ident) { diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index 55cc4d5518..ae4a9cd970 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -33,7 +33,6 @@ #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" #include "feature/rend/rendcommon.h" -#include "feature/rend/rendservice.h" #include "feature/relay/routermode.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" @@ -337,258 +336,6 @@ hs_get_start_time_of_next_time_period(time_t now) return (time_t)(start_of_next_tp_in_mins * 60 + time_period_rotation_offset); } -/** Create a new rend_data_t for a specific given <b>version</b>. - * Return a pointer to the newly allocated data structure. */ -static rend_data_t * -rend_data_alloc(uint32_t version) -{ - rend_data_t *rend_data = NULL; - - switch (version) { - case HS_VERSION_TWO: - { - rend_data_v2_t *v2 = tor_malloc_zero(sizeof(*v2)); - v2->base_.version = HS_VERSION_TWO; - v2->base_.hsdirs_fp = smartlist_new(); - rend_data = &v2->base_; - break; - } - default: - tor_assert(0); - break; - } - - return rend_data; -} - -/** Free all storage associated with <b>data</b> */ -void -rend_data_free_(rend_data_t *data) -{ - if (!data) { - return; - } - /* By using our allocation function, this should always be set. */ - tor_assert(data->hsdirs_fp); - /* Cleanup the HSDir identity digest. */ - SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d)); - smartlist_free(data->hsdirs_fp); - /* Depending on the version, cleanup. */ - switch (data->version) { - case HS_VERSION_TWO: - { - rend_data_v2_t *v2_data = TO_REND_DATA_V2(data); - tor_free(v2_data); - break; - } - default: - tor_assert(0); - } -} - -/** Allocate and return a deep copy of <b>data</b>. */ -rend_data_t * -rend_data_dup(const rend_data_t *data) -{ - rend_data_t *data_dup = NULL; - smartlist_t *hsdirs_fp = smartlist_new(); - - tor_assert(data); - tor_assert(data->hsdirs_fp); - - SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp, - smartlist_add(hsdirs_fp, tor_memdup(fp, DIGEST_LEN))); - - switch (data->version) { - case HS_VERSION_TWO: - { - rend_data_v2_t *v2_data = tor_memdup(TO_REND_DATA_V2(data), - sizeof(*v2_data)); - data_dup = &v2_data->base_; - data_dup->hsdirs_fp = hsdirs_fp; - break; - } - default: - tor_assert(0); - break; - } - - return data_dup; -} - -/** Compute the descriptor ID for each HS descriptor replica and save them. A - * valid onion address must be present in the <b>rend_data</b>. - * - * Return 0 on success else -1. */ -static int -compute_desc_id(rend_data_t *rend_data) -{ - int ret = 0; - unsigned replica; - time_t now = time(NULL); - - tor_assert(rend_data); - - switch (rend_data->version) { - case HS_VERSION_TWO: - { - rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data); - /* Compute descriptor ID for each replicas. */ - for (replica = 0; replica < ARRAY_LENGTH(v2_data->descriptor_id); - replica++) { - ret = rend_compute_v2_desc_id(v2_data->descriptor_id[replica], - v2_data->onion_address, - v2_data->descriptor_cookie, - now, replica); - if (ret < 0) { - goto end; - } - } - break; - } - default: - tor_assert(0); - } - - end: - return ret; -} - -/** Allocate and initialize a rend_data_t object for a service using the - * provided arguments. All arguments are optional (can be NULL), except from - * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of - * the service private key. The <b>cookie</b> is the rendezvous cookie and - * <b>auth_type</b> is which authentiation this service is configured with. - * - * Return a valid rend_data_t pointer. This only returns a version 2 object of - * rend_data_t. */ -rend_data_t * -rend_data_service_create(const char *onion_address, const char *pk_digest, - const uint8_t *cookie, rend_auth_type_t auth_type) -{ - /* Create a rend_data_t object for version 2. */ - rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO); - rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data); - - /* We need at least one else the call is wrong. */ - tor_assert(onion_address != NULL); - - if (pk_digest) { - memcpy(v2->rend_pk_digest, pk_digest, sizeof(v2->rend_pk_digest)); - } - if (cookie) { - memcpy(rend_data->rend_cookie, cookie, sizeof(rend_data->rend_cookie)); - } - - strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address)); - v2->auth_type = auth_type; - - return rend_data; -} - -/** Allocate and initialize a rend_data_t object for a client request using the - * given arguments. Either an onion address or a descriptor ID is needed. Both - * can be given but in this case only the onion address will be used to make - * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and - * <b>auth_type</b> is which authentiation the service is configured with. - * - * Return a valid rend_data_t pointer or NULL on error meaning the - * descriptor IDs couldn't be computed from the given data. */ -rend_data_t * -rend_data_client_create(const char *onion_address, const char *desc_id, - const char *cookie, rend_auth_type_t auth_type) -{ - /* Create a rend_data_t object for version 2. */ - rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO); - rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data); - - /* We need at least one else the call is wrong. */ - tor_assert(onion_address != NULL || desc_id != NULL); - - if (cookie) { - memcpy(v2->descriptor_cookie, cookie, sizeof(v2->descriptor_cookie)); - } - if (desc_id) { - memcpy(v2->desc_id_fetch, desc_id, sizeof(v2->desc_id_fetch)); - } - if (onion_address) { - strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address)); - if (compute_desc_id(rend_data) < 0) { - goto error; - } - } - - v2->auth_type = auth_type; - - return rend_data; - - error: - rend_data_free(rend_data); - return NULL; -} - -/** Return the onion address from the rend data. Depending on the version, - * the size of the address can vary but it's always NUL terminated. */ -const char * -rend_data_get_address(const rend_data_t *rend_data) -{ - tor_assert(rend_data); - - switch (rend_data->version) { - case HS_VERSION_TWO: - return TO_REND_DATA_V2(rend_data)->onion_address; - default: - /* We should always have a supported version. */ - tor_assert_unreached(); - } -} - -/** Return the descriptor ID for a specific replica number from the rend - * data. The returned data is a binary digest and depending on the version its - * size can vary. The size of the descriptor ID is put in <b>len_out</b> if - * non NULL. */ -const char * -rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica, - size_t *len_out) -{ - tor_assert(rend_data); - - switch (rend_data->version) { - case HS_VERSION_TWO: - tor_assert(replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS); - if (len_out) { - *len_out = DIGEST_LEN; - } - return TO_REND_DATA_V2(rend_data)->descriptor_id[replica]; - default: - /* We should always have a supported version. */ - tor_assert_unreached(); - } -} - -/** Return the public key digest using the given <b>rend_data</b>. The size of - * the digest is put in <b>len_out</b> (if set) which can differ depending on - * the version. */ -const uint8_t * -rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out) -{ - tor_assert(rend_data); - - switch (rend_data->version) { - case HS_VERSION_TWO: - { - const rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data); - if (len_out) { - *len_out = sizeof(v2_data->rend_pk_digest); - } - return (const uint8_t *) v2_data->rend_pk_digest; - } - default: - /* We should always have a supported version. */ - tor_assert_unreached(); - } -} - /** Using the given time period number, compute the disaster shared random * value and put it in srv_out. It MUST be at least DIGEST256_LEN bytes. */ static void @@ -1981,9 +1728,7 @@ hs_dec_rdv_stream_counter(origin_circuit_t *circ) { tor_assert(circ); - if (circ->rend_data) { - circ->rend_data->nr_streams--; - } else if (circ->hs_ident) { + if (circ->hs_ident) { circ->hs_ident->num_rdv_streams--; } else { /* Should not be called if this circuit is not for hidden service. */ @@ -1998,9 +1743,7 @@ hs_inc_rdv_stream_counter(origin_circuit_t *circ) { tor_assert(circ); - if (circ->rend_data) { - circ->rend_data->nr_streams++; - } else if (circ->hs_ident) { + if (circ->hs_ident) { circ->hs_ident->num_rdv_streams++; } else { /* Should not be called if this circuit is not for hidden service. */ diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h index 894b0e4844..5ddc6fd2d8 100644 --- a/src/feature/hs/hs_common.h +++ b/src/feature/hs/hs_common.h @@ -19,13 +19,10 @@ struct ed25519_keypair_t; /* Trunnel */ #include "trunnel/ed25519_cert.h" -/** Protocol version 2. Use this instead of hardcoding "2" in the code base, - * this adds a clearer semantic to the value when used. */ -#define HS_VERSION_TWO 2 /** Version 3 of the protocol (prop224). */ #define HS_VERSION_THREE 3 /** Earliest version we support. */ -#define HS_VERSION_MIN HS_VERSION_TWO +#define HS_VERSION_MIN HS_VERSION_THREE /** Latest version we support. */ #define HS_VERSION_MAX HS_VERSION_THREE @@ -194,24 +191,6 @@ void hs_build_blinded_keypair(const struct ed25519_keypair_t *kp, struct ed25519_keypair_t *kp_out); int hs_service_requires_uptime_circ(const smartlist_t *ports); -void rend_data_free_(rend_data_t *data); -#define rend_data_free(data) \ - FREE_AND_NULL(rend_data_t, rend_data_free_, (data)) -rend_data_t *rend_data_dup(const rend_data_t *data); -rend_data_t *rend_data_client_create(const char *onion_address, - const char *desc_id, - const char *cookie, - rend_auth_type_t auth_type); -rend_data_t *rend_data_service_create(const char *onion_address, - const char *pk_digest, - const uint8_t *cookie, - rend_auth_type_t auth_type); -const char *rend_data_get_address(const rend_data_t *rend_data); -const char *rend_data_get_desc_id(const rend_data_t *rend_data, - uint8_t replica, size_t *len_out); -const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data, - size_t *len_out); - routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32); struct hs_subcredential_t; diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c index b100acfcd4..e2e1756f21 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/rendservice.h" #include "lib/encoding/confline.h" #include "lib/conf/confdecl.h" #include "lib/confmgt/confmgt.h" @@ -101,23 +100,6 @@ stage_services(smartlist_t *service_list) { tor_assert(service_list); - /* This is v2 specific. Trigger service pruning which will make sure the - * just configured services end up in the main global list. It should only - * be done in non validation mode because v2 subsystem handles service - * object differently. */ - rend_service_prune_list(); - - /* Cleanup v2 service from the list, we don't need those object anymore - * because we validated them all against the others and we want to stage - * only >= v3 service. And remember, v2 has a different object type which is - * shadow copied from an hs_service_t type. */ - SMARTLIST_FOREACH_BEGIN(service_list, hs_service_t *, s) { - if (s->config.version == HS_VERSION_TWO) { - SMARTLIST_DEL_CURRENT(service_list, s); - hs_service_free(s); - } - } SMARTLIST_FOREACH_END(s); - /* This is >= v3 specific. Using the newly configured service list, stage * them into our global state. Every object ownership is lost after. */ hs_service_stage_services(service_list); @@ -145,8 +127,7 @@ service_is_duplicate_in_list(const smartlist_t *service_list, /* XXX: Validate if we have any service that has the given service dir path. * This has two problems: * - * a) It's O(n^2), but the same comment from the bottom of - * rend_config_services() should apply. + * a) It's O(n^2) * * b) We only compare directory paths as strings, so we can't * detect two distinct paths that specify the same directory @@ -269,15 +250,6 @@ config_has_invalid_options(const config_line_t *line_, NULL /* End marker. */ }; - const char *opts_exclude_v2[] = { - "HiddenServiceExportCircuitID", - "HiddenServiceEnableIntroDoSDefense", - "HiddenServiceEnableIntroDoSRatePerSec", - "HiddenServiceEnableIntroDoSBurstPerSec", - "HiddenServiceOnionBalanceInstance", - NULL /* End marker. */ - }; - /* Defining the size explicitly allows us to take advantage of the compiler * which warns us if we ever bump the max version but forget to grow this * array. The plus one is because we have a version 0 :). */ @@ -286,7 +258,7 @@ config_has_invalid_options(const config_line_t *line_, } exclude_lists[HS_VERSION_MAX + 1] = { { NULL }, /* v0. */ { NULL }, /* v1. */ - { opts_exclude_v2 }, /* v2 */ + { NULL }, /* v2. */ { opts_exclude_v3 }, /* v3. */ }; @@ -310,16 +282,6 @@ config_has_invalid_options(const config_line_t *line_, "version %" PRIu32 " of service in %s", opt, service->config.version, service->config.directory_path); - - if (!strcasecmp(line->key, "HiddenServiceAuthorizeClient")) { - /* Special case this v2 option so that we can offer alternatives. - * If more such special cases appear, it would be good to - * generalize the exception mechanism here. */ - log_warn(LD_CONFIG, "For v3 onion service client authorization, " - "please read the 'CLIENT AUTHORIZATION' section in the " - "manual."); - } - ret = 1; /* Continue the loop so we can find all possible options. */ continue; @@ -521,7 +483,7 @@ config_generic_service(const hs_opts_t *hs_opts, /* Check if we are configured in non anonymous mode meaning every service * becomes a single onion service. */ - if (rend_service_non_anonymous_mode_enabled(options)) { + if (hs_service_non_anonymous_mode_enabled(options)) { config->is_single_onion = 1; } @@ -594,8 +556,7 @@ config_service(config_line_t *line, const or_options_t *options, service->config.version = config_learn_service_version(service); } - /* We make sure that this set of options for a service are valid that is for - * instance an option only for v2 is not used for v3. */ + /* We make sure that this set of options for a service are valid. */ if (config_has_invalid_options(line->next, service)) { goto err; } @@ -604,9 +565,6 @@ config_service(config_line_t *line, const or_options_t *options, * start just after the service directory line so once we hit another * directory line, the function knows that it has to stop parsing. */ switch (service->config.version) { - case HS_VERSION_TWO: - ret = rend_config_service(hs_opts, options, &service->config); - break; case HS_VERSION_THREE: ret = config_service_v3(hs_opts, &service->config); break; @@ -687,11 +645,6 @@ hs_config_service_all(const or_options_t *options, int validate_only) * services. We don't need those objects anymore. */ SMARTLIST_FOREACH(new_service_list, hs_service_t *, s, hs_service_free(s)); - /* For the v2 subsystem, the configuration function adds the service - * object to the staging list and it is transferred in the main list - * through the prunning process. In validation mode, we thus have to purge - * the staging list so it's not kept in memory as valid service. */ - rend_service_free_staging_list(); } /* Success. Note that the service list has no ownership of its content. */ diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c index 0656224e48..0faa91f871 100644 --- a/src/feature/hs/hs_descriptor.c +++ b/src/feature/hs/hs_descriptor.c @@ -64,7 +64,6 @@ #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/dirparse/parsecommon.h" -#include "feature/rend/rendcache.h" #include "feature/hs/hs_cache.h" #include "feature/hs/hs_config.h" #include "feature/nodelist/torcert.h" /* tor_cert_encode_ed22519() */ diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index b33013ba1f..79734a67d5 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -29,7 +29,6 @@ #include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" #include "feature/nodelist/nodelist.h" -#include "feature/rend/rendservice.h" #include "lib/crypt_ops/crypto_ope.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" @@ -2666,8 +2665,6 @@ run_housekeeping_event(time_t now) static void run_build_descriptor_event(time_t now) { - /* For v2 services, this step happens in the upload event. */ - /* Run v3+ events. */ /* We start by rotating the descriptors only if needed. */ rotate_all_descriptors(now); @@ -2840,11 +2837,6 @@ run_build_circuit_event(time_t now) return; } - /* Run v2 check. */ - if (rend_num_services() > 0) { - rend_consider_services_intro_points(now); - } - /* Run v3+ check. */ FOR_EACH_SERVICE_BEGIN(service) { /* For introduction circuit, we need to make sure we don't stress too much @@ -3280,13 +3272,6 @@ refresh_service_descriptor(const hs_service_t *service, STATIC void run_upload_descriptor_event(time_t now) { - /* v2 services use the same function for descriptor creation and upload so - * we do everything here because the intro circuits were checked before. */ - if (rend_num_services() > 0) { - rend_consider_services_upload(now); - rend_consider_descriptor_republication(); - } - /* Run v3+ check. */ FOR_EACH_SERVICE_BEGIN(service) { FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { @@ -3615,6 +3600,54 @@ service_encode_descriptor(const hs_service_t *service, /* Public API */ /* ========== */ +/* Are HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode consistent? + */ +static int +hs_service_non_anonymous_mode_consistent(const or_options_t *options) +{ + /* !! is used to make these options boolean */ + return (!! options->HiddenServiceSingleHopMode == + !! options->HiddenServiceNonAnonymousMode); +} + +/* Do the options allow onion services to make direct (non-anonymous) + * connections to introduction or rendezvous points? + * Must only be called after options_validate_single_onion() has successfully + * checked onion service option consistency. + * Returns true if tor is in HiddenServiceSingleHopMode. */ +int +hs_service_allow_non_anonymous_connection(const or_options_t *options) +{ + tor_assert(hs_service_non_anonymous_mode_consistent(options)); + return options->HiddenServiceSingleHopMode ? 1 : 0; +} + +/* Do the options allow us to reveal the exact startup time of the onion + * service? + * Single Onion Services prioritise availability over hiding their + * startup time, as their IP address is publicly discoverable anyway. + * Must only be called after options_validate_single_onion() has successfully + * checked onion service option consistency. + * Returns true if tor is in non-anonymous hidden service mode. */ +int +hs_service_reveal_startup_time(const or_options_t *options) +{ + tor_assert(hs_service_non_anonymous_mode_consistent(options)); + return hs_service_non_anonymous_mode_enabled(options); +} + +/* Is non-anonymous mode enabled using the HiddenServiceNonAnonymousMode + * config option? + * Must only be called after options_validate_single_onion() has successfully + * checked onion service option consistency. + */ +int +hs_service_non_anonymous_mode_enabled(const or_options_t *options) +{ + tor_assert(hs_service_non_anonymous_mode_consistent(options)); + return options->HiddenServiceNonAnonymousMode ? 1 : 0; +} + /** Called when a circuit was just cleaned up. This is done right before the * circuit is marked for close. */ void @@ -3641,7 +3674,7 @@ hs_service_circuit_cleanup_on_close(const circuit_t *circ) } } -/** This is called every time the service map (v2 or v3) changes that is if an +/** This is called every time the service map changes that is if an * element is added or removed. */ void hs_service_map_has_changed(void) @@ -3992,9 +4025,6 @@ hs_service_lists_fnames_for_sandbox(smartlist_t *file_list, tor_assert(file_list); tor_assert(dir_list); - /* Add files and dirs for legacy services. */ - rend_services_add_filenames_to_lists(file_list, dir_list); - /* Add files and dirs for v3+. */ FOR_EACH_SERVICE_BEGIN(service) { /* Skip ephemeral service, they don't touch the disk. */ @@ -4046,9 +4076,6 @@ hs_service_receive_introduce2(origin_circuit_t *circ, const uint8_t *payload, if (circ->hs_ident) { ret = service_handle_introduce2(circ, payload, payload_len); hs_stats_note_introduce2_cell(1); - } else { - ret = rend_service_receive_introduction(circ, payload, payload_len); - hs_stats_note_introduce2_cell(0); } done: @@ -4075,12 +4102,8 @@ hs_service_receive_intro_established(origin_circuit_t *circ, goto err; } - /* Handle both version. v2 uses rend_data and v3 uses the hs circuit - * identifier hs_ident. Can't be both. */ if (circ->hs_ident) { ret = service_handle_intro_established(circ, payload, payload_len); - } else { - ret = rend_service_intro_established(circ, payload, payload_len); } if (ret < 0) { @@ -4099,21 +4122,15 @@ hs_service_circuit_has_opened(origin_circuit_t *circ) { tor_assert(circ); - /* Handle both version. v2 uses rend_data and v3 uses the hs circuit - * identifier hs_ident. Can't be both. */ switch (TO_CIRCUIT(circ)->purpose) { case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: if (circ->hs_ident) { service_intro_circ_has_opened(circ); - } else { - rend_service_intro_has_opened(circ); } break; case CIRCUIT_PURPOSE_S_CONNECT_REND: if (circ->hs_ident) { service_rendezvous_circ_has_opened(circ); - } else { - rend_service_rendezvous_has_opened(circ); } break; default: @@ -4141,11 +4158,6 @@ hs_service_get_version_from_key(const hs_service_t *service) version = HS_VERSION_THREE; goto end; } - /* Version 2 check. */ - if (rend_service_key_on_disk(directory_path)) { - version = HS_VERSION_TWO; - goto end; - } end: return version; @@ -4156,13 +4168,6 @@ hs_service_get_version_from_key(const hs_service_t *service) int hs_service_load_all_keys(void) { - /* Load v2 service keys if we have v2. */ - if (rend_num_services() != 0) { - if (rend_service_load_all_keys(NULL) < 0) { - goto err; - } - } - /* Load or/and generate them for v3+. */ SMARTLIST_FOREACH_BEGIN(hs_service_staging_list, hs_service_t *, service) { /* Ignore ephemeral service, they already have their keys set. */ @@ -4362,9 +4367,6 @@ hs_service_init(void) tor_assert(!hs_service_map); tor_assert(!hs_service_staging_list); - /* v2 specific. */ - rend_service_init(); - hs_service_map = tor_malloc_zero(sizeof(struct hs_service_ht)); HT_INIT(hs_service_ht, hs_service_map); @@ -4375,7 +4377,6 @@ hs_service_init(void) void hs_service_free_all(void) { - rend_service_free_all(); service_free_all(); hs_config_free_all(); } diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h index 54d646d3e4..be01ce3cfb 100644 --- a/src/feature/hs/hs_service.h +++ b/src/feature/hs/hs_service.h @@ -398,6 +398,11 @@ service_authorized_client_free_(hs_service_authorized_client_t *client); FREE_AND_NULL(hs_service_authorized_client_t, \ service_authorized_client_free_, (c)) +/* Config options. */ +int hs_service_allow_non_anonymous_connection(const or_options_t *options); +int hs_service_non_anonymous_mode_enabled(const or_options_t *options); +int hs_service_reveal_startup_time(const or_options_t *options); + #ifdef HS_SERVICE_PRIVATE #ifdef TOR_UNIT_TESTS |