mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
prop224: Decouple the HS part of connection_ap_handshake_rewrite_and_attach().
We will need to edit this function, and it's already pretty huge. Let's make it a bit smaller. This commit moves code, fixes a 80 char line and add two lines at the start to make it compile. Trivial change. Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
bce18a7642
commit
5d89ea1e6c
@ -1392,6 +1392,124 @@ connection_ap_handshake_rewrite(entry_connection_t *conn,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
connection_ap_handle_onion(entry_connection_t *conn,
|
||||
socks_request_t *socks,
|
||||
origin_circuit_t *circ)
|
||||
{
|
||||
time_t now = approx_time();
|
||||
connection_t *base_conn = ENTRY_TO_CONN(conn);
|
||||
|
||||
/* If .onion address requests are disabled, refuse the request */
|
||||
if (!conn->entry_cfg.onion_traffic) {
|
||||
log_warn(LD_APP, "Onion address %s requested from a port with .onion "
|
||||
"disabled", safe_str_client(socks->address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether it's RESOLVE or RESOLVE_PTR. We don't handle those
|
||||
* for hidden service addresses. */
|
||||
if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) {
|
||||
/* if it's a resolve request, fail it right now, rather than
|
||||
* building all the circuits and then realizing it won't work. */
|
||||
log_warn(LD_APP,
|
||||
"Resolve requests to hidden services not allowed. Failing.");
|
||||
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,
|
||||
0,NULL,-1,TIME_MAX);
|
||||
connection_mark_unattached_ap(conn,
|
||||
END_STREAM_REASON_SOCKSPROTOCOL |
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we were passed a circuit, then we need to fail. .onion addresses
|
||||
* only work when we launch our own circuits for now. */
|
||||
if (circ) {
|
||||
log_warn(LD_CONTROL, "Attachstream to a circuit is not "
|
||||
"supported for .onion addresses currently. Failing.");
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
const char *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));
|
||||
|
||||
/* 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:
|
||||
/* We should already have rejected this address! */
|
||||
log_warn(LD_BUG,"Invalid service name '%s'",
|
||||
safe_str_client(onion_address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
case ENOENT:
|
||||
/* We didn't have this; we should look it up. */
|
||||
refetch_desc = 1;
|
||||
break;
|
||||
default:
|
||||
log_warn(LD_BUG, "Unknown cache lookup error %d",
|
||||
rend_cache_lookup_result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Help predict that we'll want to do hidden service circuits in the
|
||||
* future. We're not sure if it will need a stable circuit yet, but
|
||||
* we know we'll need *something*. */
|
||||
rep_hist_note_used_internal(now, 0, 1);
|
||||
|
||||
/* 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)) {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have the descriptor! So launch a connection to the HS. */
|
||||
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
log_info(LD_REND, "Descriptor is here. Great.");
|
||||
|
||||
/* We'll try to attach it at the next event loop, or whenever
|
||||
* we call connection_ap_attach_pending() */
|
||||
connection_ap_mark_as_pending_circuit(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Connection <b>conn</b> just finished its socks handshake, or the
|
||||
* controller asked us to take care of it. If <b>circ</b> is defined,
|
||||
* then that's where we'll want to attach it. Otherwise we have to
|
||||
@ -1837,115 +1955,9 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
||||
} else {
|
||||
/* If we get here, it's a request for a .onion address! */
|
||||
tor_assert(!automap);
|
||||
|
||||
/* If .onion address requests are disabled, refuse the request */
|
||||
if (!conn->entry_cfg.onion_traffic) {
|
||||
log_warn(LD_APP, "Onion address %s requested from a port with .onion "
|
||||
"disabled", safe_str_client(socks->address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
|
||||
if (connection_ap_handle_onion(conn, socks, circ) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether it's RESOLVE or RESOLVE_PTR. We don't handle those
|
||||
* for hidden service addresses. */
|
||||
if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) {
|
||||
/* if it's a resolve request, fail it right now, rather than
|
||||
* building all the circuits and then realizing it won't work. */
|
||||
log_warn(LD_APP,
|
||||
"Resolve requests to hidden services not allowed. Failing.");
|
||||
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,
|
||||
0,NULL,-1,TIME_MAX);
|
||||
connection_mark_unattached_ap(conn,
|
||||
END_STREAM_REASON_SOCKSPROTOCOL |
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we were passed a circuit, then we need to fail. .onion addresses
|
||||
* only work when we launch our own circuits for now. */
|
||||
if (circ) {
|
||||
log_warn(LD_CONTROL, "Attachstream to a circuit is not "
|
||||
"supported for .onion addresses currently. Failing.");
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
const char *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));
|
||||
|
||||
/* 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:
|
||||
/* We should already have rejected this address! */
|
||||
log_warn(LD_BUG,"Invalid service name '%s'",
|
||||
safe_str_client(onion_address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
case ENOENT:
|
||||
/* We didn't have this; we should look it up. */
|
||||
refetch_desc = 1;
|
||||
break;
|
||||
default:
|
||||
log_warn(LD_BUG, "Unknown cache lookup error %d",
|
||||
rend_cache_lookup_result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Help predict that we'll want to do hidden service circuits in the
|
||||
* future. We're not sure if it will need a stable circuit yet, but
|
||||
* we know we'll need *something*. */
|
||||
rep_hist_note_used_internal(now, 0, 1);
|
||||
|
||||
/* 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)) {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have the descriptor! So launch a connection to the HS. */
|
||||
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
log_info(LD_REND, "Descriptor is here. Great.");
|
||||
|
||||
/* We'll try to attach it at the next event loop, or whenever
|
||||
* we call connection_ap_attach_pending() */
|
||||
connection_ap_mark_as_pending_circuit(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0; /* unreached but keeps the compiler happy */
|
||||
|
Loading…
Reference in New Issue
Block a user