Prepare for #40373: Re-introduce parsing for v2 onion addresses.

Welcome back ONION_V2_HOSTNAME! :)
This commit is contained in:
George Kadianakis 2021-05-05 11:05:09 +03:00
parent cf6e72b702
commit f230beadf4
3 changed files with 38 additions and 1 deletions

View File

@ -1612,6 +1612,23 @@ consider_plaintext_ports(entry_connection_t *conn, uint16_t port)
return 0; return 0;
} }
/** Return true iff <b>query</b> is a syntactically valid service ID (as
* generated by rend_get_service_id). */
static int
rend_valid_v2_service_id(const char *query)
{
/** Length of 'y' portion of 'y.onion' URL. */
#define REND_SERVICE_ID_LEN_BASE32 16
if (strlen(query) != REND_SERVICE_ID_LEN_BASE32)
return 0;
if (strspn(query, BASE32_CHARS) != REND_SERVICE_ID_LEN_BASE32)
return 0;
return 1;
}
/** Parse the given hostname in address. Returns true if the parsing was /** Parse the given hostname in address. Returns true if the parsing was
* successful and type_out contains the type of the hostname. Else, false is * successful and type_out contains the type of the hostname. Else, false is
* returned which means it was not recognized and type_out is set to * returned which means it was not recognized and type_out is set to
@ -1675,6 +1692,14 @@ parse_extended_hostname(char *address, hostname_type_t *type_out)
if (q != address) { if (q != address) {
memmove(address, q, strlen(q) + 1 /* also get \0 */); memmove(address, q, strlen(q) + 1 /* also get \0 */);
} }
/* v2 onion address check. */
if (strlen(query) == REND_SERVICE_ID_LEN_BASE32) {
*type_out = ONION_V2_HOSTNAME;
if (rend_valid_v2_service_id(query)) {
goto success;
}
goto failed;
}
/* v3 onion address check. */ /* v3 onion address check. */
if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) { if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) {
@ -1694,7 +1719,8 @@ parse_extended_hostname(char *address, hostname_type_t *type_out)
failed: failed:
/* otherwise, return to previous state and return 0 */ /* otherwise, return to previous state and return 0 */
*s = '.'; *s = '.';
const bool is_onion = (*type_out == ONION_V3_HOSTNAME); const bool is_onion = (*type_out == ONION_V2_HOSTNAME) ||
(*type_out == ONION_V3_HOSTNAME);
log_warn(LD_APP, "Invalid %shostname %s; rejecting", log_warn(LD_APP, "Invalid %shostname %s; rejecting",
is_onion ? "onion " : "", is_onion ? "onion " : "",
safe_str_client(address)); safe_str_client(address));

View File

@ -80,6 +80,7 @@ typedef enum hostname_type_t {
BAD_HOSTNAME, BAD_HOSTNAME,
EXIT_HOSTNAME, EXIT_HOSTNAME,
NORMAL_HOSTNAME, NORMAL_HOSTNAME,
ONION_V2_HOSTNAME,
ONION_V3_HOSTNAME, ONION_V3_HOSTNAME,
} hostname_type_t; } hostname_type_t;

View File

@ -789,6 +789,8 @@ test_parse_extended_hostname(void *arg)
char address1[] = "fooaddress.onion"; char address1[] = "fooaddress.onion";
char address3[] = "fooaddress.exit"; char address3[] = "fooaddress.exit";
char address4[] = "www.torproject.org"; char address4[] = "www.torproject.org";
char address5[] = "foo.abcdefghijklmnop.onion";
char address6[] = "foo.bar.abcdefghijklmnop.onion";
char address7[] = ".abcdefghijklmnop.onion"; char address7[] = ".abcdefghijklmnop.onion";
char address8[] = char address8[] =
"www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion"; "www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion";
@ -806,6 +808,14 @@ test_parse_extended_hostname(void *arg)
tt_assert(parse_extended_hostname(address4, &type)); tt_assert(parse_extended_hostname(address4, &type));
tt_int_op(type, OP_EQ, NORMAL_HOSTNAME); tt_int_op(type, OP_EQ, NORMAL_HOSTNAME);
tt_assert(parse_extended_hostname(address5, &type));
tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
tt_str_op(address5, OP_EQ, "abcdefghijklmnop");
tt_assert(parse_extended_hostname(address6, &type));
tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
tt_str_op(address6, OP_EQ, "abcdefghijklmnop");
tt_assert(!parse_extended_hostname(address7, &type)); tt_assert(!parse_extended_hostname(address7, &type));
tt_int_op(type, OP_EQ, BAD_HOSTNAME); tt_int_op(type, OP_EQ, BAD_HOSTNAME);