mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
prop224: Connect to v3 services in connection_ap_handle_onion().
Recognize and handle v3 addresses. Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
c754864cfd
commit
776e796d96
@ -76,6 +76,8 @@
|
||||
#include "dirserv.h"
|
||||
#include "hibernate.h"
|
||||
#include "hs_common.h"
|
||||
#include "hs_cache.h"
|
||||
#include "hs_client.h"
|
||||
#include "hs_circuit.h"
|
||||
#include "main.h"
|
||||
#include "nodelist.h"
|
||||
@ -1392,10 +1394,13 @@ connection_ap_handshake_rewrite(entry_connection_t *conn,
|
||||
}
|
||||
}
|
||||
|
||||
/** We just received a SOCKS request in <b>conn</b> to an onion address of type
|
||||
* <b>addresstype</b>. Start connecting to the onion service. */
|
||||
static int
|
||||
connection_ap_handle_onion(entry_connection_t *conn,
|
||||
socks_request_t *socks,
|
||||
origin_circuit_t *circ)
|
||||
origin_circuit_t *circ,
|
||||
hostname_type_t addresstype)
|
||||
{
|
||||
time_t now = approx_time();
|
||||
connection_t *base_conn = ENTRY_TO_CONN(conn);
|
||||
@ -1432,6 +1437,14 @@ connection_ap_handle_onion(entry_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Interface: Regardless of HS version after the block below we should have
|
||||
set onion_address, rend_cache_lookup_result, and descriptor_is_usable. */
|
||||
const char *onion_address = NULL;
|
||||
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 =
|
||||
@ -1454,16 +1467,51 @@ connection_ap_handle_onion(entry_connection_t *conn,
|
||||
if (rend_data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
const char *onion_address = rend_data_get_address(rend_data);
|
||||
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);
|
||||
const hs_descriptor_t *cached_desc = NULL;
|
||||
int retval;
|
||||
/* Create HS conn identifier with HS pubkey */
|
||||
hs_ident_edge_conn_t *hs_conn_ident =
|
||||
tor_malloc_zero(sizeof(hs_ident_edge_conn_t));
|
||||
|
||||
retval = hs_parse_address(socks->address, &hs_conn_ident->identity_pk,
|
||||
NULL, NULL);
|
||||
if (retval < 0) {
|
||||
log_warn(LD_GENERAL, "failed to parse hs address");
|
||||
tor_free(hs_conn_ident);
|
||||
return -1;
|
||||
}
|
||||
ENTRY_TO_EDGE_CONN(conn)->hs_ident = hs_conn_ident;
|
||||
|
||||
onion_address = socks->address;
|
||||
|
||||
/* Check the v3 desc cache */
|
||||
cached_desc = hs_cache_lookup_as_client(&hs_conn_ident->identity_pk);
|
||||
if (cached_desc) {
|
||||
rend_cache_lookup_result = 0;
|
||||
descriptor_is_usable = hs_client_any_intro_points_usable(cached_desc);
|
||||
log_info(LD_GENERAL, "Found %s descriptor in cache for %s. %s.",
|
||||
(descriptor_is_usable) ? "usable" : "unusable",
|
||||
safe_str_client(onion_address),
|
||||
(descriptor_is_usable) ? "Not fetching." : "Refecting.");
|
||||
} else {
|
||||
rend_cache_lookup_result = -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lookup the given onion address. If invalid, stop right now.
|
||||
* Otherwise, we might have it in the cache or not. */
|
||||
unsigned int refetch_desc = 0;
|
||||
rend_cache_entry_t *entry = NULL;
|
||||
const int rend_cache_lookup_result =
|
||||
rend_cache_lookup_entry(onion_address, -1, &entry);
|
||||
if (rend_cache_lookup_result < 0) {
|
||||
switch (-rend_cache_lookup_result) {
|
||||
case EINVAL:
|
||||
@ -1474,6 +1522,8 @@ connection_ap_handle_onion(entry_connection_t *conn,
|
||||
return -1;
|
||||
case ENOENT:
|
||||
/* We didn't have this; we should look it up. */
|
||||
log_info(LD_REND, "No descriptor found in our cache for %s. Fetching.",
|
||||
safe_str_client(onion_address));
|
||||
refetch_desc = 1;
|
||||
break;
|
||||
default:
|
||||
@ -1491,12 +1541,18 @@ connection_ap_handle_onion(entry_connection_t *conn,
|
||||
/* Now we have a descriptor but is it usable or not? If not, refetch.
|
||||
* Also, a fetch could have been requested if the onion address was not
|
||||
* found in the cache previously. */
|
||||
if (refetch_desc || !rend_client_any_intro_points_usable(entry)) {
|
||||
if (refetch_desc || !descriptor_is_usable) {
|
||||
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;
|
||||
log_info(LD_REND, "Unknown descriptor %s. Fetching.",
|
||||
safe_str_client(onion_address));
|
||||
rend_client_refetch_v2_renddesc(rend_data);
|
||||
if (addresstype == ONION_V2_HOSTNAME) {
|
||||
tor_assert(edge_conn->rend_data);
|
||||
rend_client_refetch_v2_renddesc(edge_conn->rend_data);
|
||||
} else {
|
||||
tor_assert(addresstype == ONION_V3_HOSTNAME);
|
||||
tor_assert(edge_conn->hs_ident);
|
||||
hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1676,7 +1732,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) {
|
||||
if (addresstype != ONION_V2_HOSTNAME && 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
|
||||
@ -1954,8 +2010,10 @@ 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(!automap);
|
||||
if (connection_ap_handle_onion(conn, socks, circ) < 0) {
|
||||
if (connection_ap_handle_onion(conn, socks, circ, addresstype) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user