mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Add missing descriptor ID to HS_DESC control event
For FAILED and RECEIVED action of the HS_DESC event, we now sends back the descriptor ID at the end like specified in the control-spec section 4.1.25. Fixes #15881 Signed-off-by: David Goulet <dgoulet@ev0ke.net>
This commit is contained in:
parent
95a9920461
commit
c1ffeadff4
3
changes/bug15881
Normal file
3
changes/bug15881
Normal file
@ -0,0 +1,3 @@
|
||||
o Controller fixes:
|
||||
- Add the descriptor ID in each HS_DESC control event. It was missing
|
||||
but specified in control-spec.txt. Fixes ticket 15881.
|
@ -5904,6 +5904,44 @@ control_event_hs_descriptor_requested(const rend_data_t *rend_query,
|
||||
desc_id_base32);
|
||||
}
|
||||
|
||||
/** For an HS descriptor query <b>rend_data</b>, using the
|
||||
* <b>onion_address</b> and HSDir fingerprint <b>hsdir_fp</b>, find out
|
||||
* which descriptor ID in the query is the right one.
|
||||
*
|
||||
* Return a pointer of the binary descriptor ID found in the query's object
|
||||
* or NULL if not found. */
|
||||
static const char *
|
||||
get_desc_id_from_query(const rend_data_t *rend_data, const char *hsdir_fp)
|
||||
{
|
||||
int replica;
|
||||
const char *desc_id = NULL;
|
||||
|
||||
/* Possible if the fetch was done using a descriptor ID. This means that
|
||||
* the HSFETCH command was used. */
|
||||
if (!tor_digest_is_zero(rend_data->desc_id_fetch)) {
|
||||
desc_id = rend_data->desc_id_fetch;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* OK, we have an onion address so now let's find which descriptor ID
|
||||
* is the one associated with the HSDir fingerprint. */
|
||||
for (replica = 0; replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS;
|
||||
replica++) {
|
||||
const char *digest = rend_data->descriptor_id[replica];
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(rend_data->hsdirs_fp, char *, fingerprint) {
|
||||
if (tor_memcmp(fingerprint, hsdir_fp, DIGEST_LEN) == 0) {
|
||||
/* Found it! This descriptor ID is the right one. */
|
||||
desc_id = digest;
|
||||
goto end;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(fingerprint);
|
||||
}
|
||||
|
||||
end:
|
||||
return desc_id;
|
||||
}
|
||||
|
||||
/** send HS_DESC upload event.
|
||||
*
|
||||
* <b>service_id</b> is the descriptor onion address.
|
||||
@ -5940,30 +5978,45 @@ control_event_hs_descriptor_upload(const char *service_id,
|
||||
void
|
||||
control_event_hs_descriptor_receive_end(const char *action,
|
||||
const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason)
|
||||
{
|
||||
char *desc_id_field = NULL;
|
||||
char *reason_field = NULL;
|
||||
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
||||
const char *desc_id = NULL;
|
||||
|
||||
if (!action || !id_digest || !onion_address) {
|
||||
log_warn(LD_BUG, "Called with action==%p, id_digest==%p "
|
||||
"onion_address==%p", action, id_digest, onion_address);
|
||||
if (!action || !id_digest || !rend_data || !onion_address) {
|
||||
log_warn(LD_BUG, "Called with action==%p, id_digest==%p, "
|
||||
"rend_data==%p, onion_address==%p", action, id_digest,
|
||||
rend_data, onion_address);
|
||||
return;
|
||||
}
|
||||
|
||||
desc_id = get_desc_id_from_query(rend_data, id_digest);
|
||||
if (desc_id != NULL) {
|
||||
/* Set the descriptor ID digest to base32 so we can send it. */
|
||||
base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
|
||||
DIGEST_LEN);
|
||||
/* Extra whitespace is needed before the value. */
|
||||
tor_asprintf(&desc_id_field, " %s", desc_id_base32);
|
||||
}
|
||||
|
||||
if (reason) {
|
||||
tor_asprintf(&reason_field, " REASON=%s", reason);
|
||||
}
|
||||
|
||||
send_control_event(EVENT_HS_DESC, ALL_FORMATS,
|
||||
"650 HS_DESC %s %s %s %s%s\r\n",
|
||||
"650 HS_DESC %s %s %s %s%s%s\r\n",
|
||||
action,
|
||||
rend_hsaddress_str_or_unknown(onion_address),
|
||||
rend_auth_type_to_string(auth_type),
|
||||
rend_auth_type_to_string(rend_data->auth_type),
|
||||
node_describe_longname_by_id(id_digest),
|
||||
desc_id_field ? desc_id_field : "",
|
||||
reason_field ? reason_field : "");
|
||||
|
||||
tor_free(desc_id_field);
|
||||
tor_free(reason_field);
|
||||
}
|
||||
|
||||
@ -6007,15 +6060,16 @@ control_event_hs_descriptor_upload_end(const char *action,
|
||||
*/
|
||||
void
|
||||
control_event_hs_descriptor_received(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest)
|
||||
{
|
||||
if (!id_digest) {
|
||||
log_warn(LD_BUG, "Called with id_digest==%p", id_digest);
|
||||
if (!rend_data || !id_digest || !onion_address) {
|
||||
log_warn(LD_BUG, "Called with rend_data==%p, id_digest==%p, "
|
||||
"onion_address==%p", rend_data, id_digest, onion_address);
|
||||
return;
|
||||
}
|
||||
control_event_hs_descriptor_receive_end("RECEIVED", onion_address,
|
||||
auth_type, id_digest, NULL);
|
||||
rend_data, id_digest, NULL);
|
||||
}
|
||||
|
||||
/** send HS_DESC UPLOADED event
|
||||
@ -6039,17 +6093,18 @@ control_event_hs_descriptor_uploaded(const char *id_digest)
|
||||
* field.
|
||||
*/
|
||||
void
|
||||
control_event_hs_descriptor_failed(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
control_event_hs_descriptor_failed(const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason)
|
||||
{
|
||||
if (!id_digest) {
|
||||
log_warn(LD_BUG, "Called with id_digest==%p", id_digest);
|
||||
if (!rend_data || !id_digest) {
|
||||
log_warn(LD_BUG, "Called with rend_data==%p, id_digest==%p",
|
||||
rend_data, id_digest);
|
||||
return;
|
||||
}
|
||||
control_event_hs_descriptor_receive_end("FAILED", onion_address, auth_type,
|
||||
id_digest, reason);
|
||||
control_event_hs_descriptor_receive_end("FAILED",
|
||||
rend_data->onion_address,
|
||||
rend_data, id_digest, reason);
|
||||
}
|
||||
|
||||
/** send HS_DESC_CONTENT event after completion of a successful fetch from
|
||||
|
@ -111,18 +111,17 @@ void control_event_hs_descriptor_upload(const char *service_id,
|
||||
const char *hs_dir);
|
||||
void control_event_hs_descriptor_receive_end(const char *action,
|
||||
const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_upload_end(const char *action,
|
||||
const char *hs_dir,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_received(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest);
|
||||
void control_event_hs_descriptor_uploaded(const char *hs_dir);
|
||||
void control_event_hs_descriptor_failed(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
void control_event_hs_descriptor_failed(const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_upload_failed(const char *hs_dir,
|
||||
|
@ -2099,8 +2099,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
|
||||
#define SEND_HS_DESC_FAILED_EVENT(reason) ( \
|
||||
control_event_hs_descriptor_failed(conn->rend_data->onion_address, \
|
||||
conn->rend_data->auth_type, \
|
||||
control_event_hs_descriptor_failed(conn->rend_data, \
|
||||
conn->identity_digest, \
|
||||
reason) )
|
||||
#define SEND_HS_DESC_FAILED_CONTENT() ( \
|
||||
@ -2141,7 +2140,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
log_info(LD_REND, "Successfully fetched v2 rendezvous "
|
||||
"descriptor.");
|
||||
control_event_hs_descriptor_received(service_id,
|
||||
conn->rend_data->auth_type,
|
||||
conn->rend_data,
|
||||
conn->identity_digest);
|
||||
control_event_hs_descriptor_content(service_id,
|
||||
conn->requested_resource,
|
||||
|
@ -814,6 +814,10 @@ typedef struct rend_data_t {
|
||||
|
||||
/** Rendezvous cookie used by both, client and service. */
|
||||
char rend_cookie[REND_COOKIE_LEN];
|
||||
|
||||
/** List of HSDir fingerprints on which this request has been sent to.
|
||||
* This contains binary identity digest of the directory. */
|
||||
smartlist_t *hsdirs_fp;
|
||||
} rend_data_t;
|
||||
|
||||
/** Time interval for tracking replays of DH public keys received in
|
||||
|
@ -686,6 +686,7 @@ 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];
|
||||
#ifdef ENABLE_TOR2WEB_MODE
|
||||
@ -709,6 +710,12 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query,
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
@ -1400,8 +1400,14 @@ rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
|
||||
rend_data_t *
|
||||
rend_data_dup(const rend_data_t *data)
|
||||
{
|
||||
rend_data_t *data_dup;
|
||||
tor_assert(data);
|
||||
return tor_memdup(data, sizeof(rend_data_t));
|
||||
data_dup = tor_memdup(data, sizeof(rend_data_t));
|
||||
data_dup->hsdirs_fp = smartlist_new();
|
||||
SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp,
|
||||
smartlist_add(data_dup->hsdirs_fp,
|
||||
tor_memdup(fp, DIGEST_LEN)));
|
||||
return data_dup;
|
||||
}
|
||||
|
||||
/** Compute descriptor ID for each replicas and save them. A valid onion
|
||||
@ -1495,6 +1501,7 @@ rend_data_client_create(const char *onion_address, const char *desc_id,
|
||||
}
|
||||
|
||||
rend_data->auth_type = auth_type;
|
||||
rend_data->hsdirs_fp = smartlist_new();
|
||||
|
||||
return rend_data;
|
||||
|
||||
|
@ -16,6 +16,12 @@
|
||||
static INLINE void
|
||||
rend_data_free(rend_data_t *data)
|
||||
{
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
/* Cleanup the HSDir identity digest. */
|
||||
SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d));
|
||||
smartlist_free(data->hsdirs_fp);
|
||||
tor_free(data);
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ test_hs_desc_event(void *arg)
|
||||
/* test received event */
|
||||
rend_query.auth_type = 1;
|
||||
control_event_hs_descriptor_received(rend_query.onion_address,
|
||||
rend_query.auth_type, HSDIR_EXIST_ID);
|
||||
&rend_query, HSDIR_EXIST_ID);
|
||||
expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
|
||||
STR_HSDIR_EXIST_LONGNAME"\r\n";
|
||||
tt_assert(received_msg);
|
||||
@ -169,8 +169,8 @@ test_hs_desc_event(void *arg)
|
||||
|
||||
/* test failed event */
|
||||
rend_query.auth_type = 2;
|
||||
control_event_hs_descriptor_failed(rend_query.onion_address,
|
||||
rend_query.auth_type, HSDIR_NONE_EXIST_ID,
|
||||
control_event_hs_descriptor_failed(&rend_query,
|
||||
HSDIR_NONE_EXIST_ID,
|
||||
"QUERY_REJECTED");
|
||||
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
|
||||
STR_HSDIR_NONE_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
|
||||
@ -180,8 +180,8 @@ test_hs_desc_event(void *arg)
|
||||
|
||||
/* test invalid auth type */
|
||||
rend_query.auth_type = 999;
|
||||
control_event_hs_descriptor_failed(rend_query.onion_address,
|
||||
rend_query.auth_type, HSDIR_EXIST_ID,
|
||||
control_event_hs_descriptor_failed(&rend_query,
|
||||
HSDIR_EXIST_ID,
|
||||
"QUERY_REJECTED");
|
||||
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
|
||||
STR_HSDIR_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
|
||||
|
Loading…
Reference in New Issue
Block a user