commit 6f5f38a0bc60d3be9b6cf02e29b9065869cf6af8 Author: David Goulet dgoulet@ev0ke.net Date: Tue Apr 21 14:04:39 2015 -0400
Add function to validate HS descriptor ID
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/or/control.c | 2 +- src/or/directory.c | 2 +- src/or/rendcommon.c | 18 ++++++++++++++++++ src/or/rendcommon.h | 1 + src/or/routerparse.c | 3 +-- 5 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/or/control.c b/src/or/control.c index b4d671b..3135324 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3284,7 +3284,7 @@ handle_control_hsfetch(control_connection_t *conn, uint32_t len, if (rend_valid_service_id(arg1)) { hsaddress = arg1; } else if (strcmpstart(arg1, v2_str) == 0 && - strlen(arg1 + v2_str_len) == REND_DESC_ID_V2_LEN_BASE32 && + rend_valid_descriptor_id(arg1 + v2_str_len) && base32_decode(digest, sizeof(digest), arg1 + v2_str_len, REND_DESC_ID_V2_LEN_BASE32) == 0) { /* We have a well formed version 2 descriptor ID. Keep the decoded value diff --git a/src/or/directory.c b/src/or/directory.c index 37a46fc..bad1f62 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3094,7 +3094,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, /* Handle v2 rendezvous descriptor fetch request. */ const char *descp; const char *query = url + strlen("/tor/rendezvous2/"); - if (strlen(query) == REND_DESC_ID_V2_LEN_BASE32) { + if (rend_valid_descriptor_id(query)) { log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'", safe_str(escaped(query))); switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) { diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 95d16f1..4982745 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -919,6 +919,24 @@ rend_valid_service_id(const char *query) return 1; }
+/** Return true iff <b>query</b> is a syntactically valid descriptor ID. + * (as generated by rend_get_descriptor_id_bytes). */ +int +rend_valid_descriptor_id(const char *query) +{ + if (strlen(query) != REND_DESC_ID_V2_LEN_BASE32) { + goto invalid; + } + if (strspn(query, BASE32_CHARS) != REND_DESC_ID_V2_LEN_BASE32) { + goto invalid; + } + + return 1; + +invalid: + return 0; +} + /** Lookup in the client cache the given service ID <b>query</b> for * <b>version</b>. * diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index f4f2051..b86cdb7 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -37,6 +37,7 @@ void rend_cache_clean_v2_descs_as_dir(time_t now, size_t min_to_remove); void rend_cache_purge(void); void rend_cache_free_all(void); int rend_valid_service_id(const char *query); +int rend_valid_descriptor_id(const char *query); int rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **entry_out); int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index fd3971c..14d5f75 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -4572,8 +4572,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, tok = find_by_keyword(tokens, R_RENDEZVOUS_SERVICE_DESCRIPTOR); tor_assert(tok == smartlist_get(tokens, 0)); tor_assert(tok->n_args == 1); - if (strlen(tok->args[0]) != REND_DESC_ID_V2_LEN_BASE32 || - strspn(tok->args[0], BASE32_CHARS) != REND_DESC_ID_V2_LEN_BASE32) { + if (!rend_valid_descriptor_id(tok->args[0])) { log_warn(LD_REND, "Invalid descriptor ID: '%s'", tok->args[0]); goto err; }