From e1d8e611c8fa1a3a1d3c2beb72c416c71f9cdf15 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 7 Nov 2017 15:42:38 -0500 Subject: [PATCH] control: Implement GETINFO hs/client/desc/id/ for HSv3 Part of #20699 Signed-off-by: David Goulet --- src/or/control.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 0d462b2d7d..193a65facc 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -58,6 +58,7 @@ #include "entrynodes.h" #include "geoip.h" #include "hibernate.h" +#include "hs_cache.h" #include "hs_common.h" #include "main.h" #include "microdesc.h" @@ -2014,20 +2015,46 @@ getinfo_helper_dir(control_connection_t *control_conn, SMARTLIST_FOREACH(sl, char *, c, tor_free(c)); smartlist_free(sl); } else if (!strcmpstart(question, "hs/client/desc/id/")) { - rend_cache_entry_t *e = NULL; + hostname_type_t addr_type; question += strlen("hs/client/desc/id/"); - if (strlen(question) != REND_SERVICE_ID_LEN_BASE32) { + if (rend_valid_v2_service_id(question)) { + addr_type = ONION_V2_HOSTNAME; + } else if (hs_address_is_valid(question)) { + addr_type = ONION_V3_HOSTNAME; + } else { *errmsg = "Invalid address"; return -1; } - if (!rend_cache_lookup_entry(question, -1, &e)) { - /* Descriptor found in cache */ - *answer = tor_strdup(e->desc); + if (addr_type == ONION_V2_HOSTNAME) { + rend_cache_entry_t *e = NULL; + if (!rend_cache_lookup_entry(question, -1, &e)) { + /* Descriptor found in cache */ + *answer = tor_strdup(e->desc); + } else { + *errmsg = "Not found in cache"; + return -1; + } } else { - *errmsg = "Not found in cache"; - return -1; + ed25519_public_key_t service_pk; + const char *desc; + + /* The check before this if/else makes sure of this. */ + tor_assert(addr_type == ONION_V3_HOSTNAME); + + if (hs_parse_address(question, &service_pk, NULL, NULL) < 0) { + *errmsg = "Invalid v3 address"; + return -1; + } + + desc = hs_cache_lookup_encoded_as_client(&service_pk); + if (desc) { + *answer = tor_strdup(desc); + } else { + *errmsg = "Not found in cache"; + return -1; + } } } else if (!strcmpstart(question, "hs/service/desc/id/")) { rend_cache_entry_t *e = NULL;