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:
George Kadianakis 2017-06-01 13:24:28 +03:00
parent bce18a7642
commit 5d89ea1e6c

View File

@ -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 /** 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, * 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 * 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 { } else {
/* If we get here, it's a request for a .onion address! */ /* If we get here, it's a request for a .onion address! */
tor_assert(!automap); tor_assert(!automap);
if (connection_ap_handle_onion(conn, socks, circ) < 0) {
/* 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; 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 */ return 0; /* unreached but keeps the compiler happy */