From f230beadf469e300c783791847a346c593033dd0 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 5 May 2021 11:05:09 +0300 Subject: Prepare for #40373: Re-introduce parsing for v2 onion addresses. Welcome back ONION_V2_HOSTNAME! :) --- src/core/or/connection_edge.c | 28 +++++++++++++++++++++++++++- src/core/or/connection_edge.h | 1 + src/test/test_hs_common.c | 10 ++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index b89f3336dc..8e13161348 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -1612,6 +1612,23 @@ consider_plaintext_ports(entry_connection_t *conn, uint16_t port) return 0; } +/** Return true iff query 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 * 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 @@ -1675,6 +1692,14 @@ parse_extended_hostname(char *address, hostname_type_t *type_out) if (q != address) { 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. */ if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) { @@ -1694,7 +1719,8 @@ parse_extended_hostname(char *address, hostname_type_t *type_out) failed: /* otherwise, return to previous state and return 0 */ *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", is_onion ? "onion " : "", safe_str_client(address)); diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h index 966a9391d8..72869f348b 100644 --- a/src/core/or/connection_edge.h +++ b/src/core/or/connection_edge.h @@ -80,6 +80,7 @@ typedef enum hostname_type_t { BAD_HOSTNAME, EXIT_HOSTNAME, NORMAL_HOSTNAME, + ONION_V2_HOSTNAME, ONION_V3_HOSTNAME, } hostname_type_t; diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index 08e0b9b703..7cb6a36f8e 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -789,6 +789,8 @@ test_parse_extended_hostname(void *arg) char address1[] = "fooaddress.onion"; char address3[] = "fooaddress.exit"; char address4[] = "www.torproject.org"; + char address5[] = "foo.abcdefghijklmnop.onion"; + char address6[] = "foo.bar.abcdefghijklmnop.onion"; char address7[] = ".abcdefghijklmnop.onion"; char address8[] = "www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion"; @@ -806,6 +808,14 @@ test_parse_extended_hostname(void *arg) tt_assert(parse_extended_hostname(address4, &type)); 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_int_op(type, OP_EQ, BAD_HOSTNAME); -- cgit v1.2.3-54-g00ecf From 5e836eb80c31b97f87b152351b6a7a932aeffaed Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 5 May 2021 11:10:28 +0300 Subject: Add warning when trying to connect to deprecated v2 onions. --- changes/ticket40373 | 3 +++ src/core/or/connection_edge.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 changes/ticket40373 diff --git a/changes/ticket40373 b/changes/ticket40373 new file mode 100644 index 0000000000..3b2edd0652 --- /dev/null +++ b/changes/ticket40373 @@ -0,0 +1,3 @@ + o Minor features (onion services): + - Add warning message when connecting to deprecated v2 onions. + Closes ticket 40373. \ No newline at end of file diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 8e13161348..a307249967 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -2242,7 +2242,7 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, } /* Now, we handle everything that isn't a .onion address. */ - if (addresstype != ONION_V3_HOSTNAME) { + if (addresstype != ONION_V3_HOSTNAME && addresstype != ONION_V2_HOSTNAME) { /* Not a hidden-service request. It's either a hostname or an IP, * possibly with a .exit that we stripped off. We're going to check * if we're allowed to connect/resolve there, and then launch the @@ -2527,6 +2527,19 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, return 0; } else { /* If we get here, it's a request for a .onion address! */ + + /* We don't support v2 onions anymore. Log a warning and bail. */ + if (addresstype == ONION_V2_HOSTNAME) { + log_warn(LD_PROTOCOL, "Tried to connect to a v2 onion address, but this " + "version of Tor no longer supports them. Please encourage the " + "site operator to upgrade. For more information see " + "https://blog.torproject.org/v2-deprecation-timeline."); + control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s", + escaped(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); + return -1; + } + tor_assert(addresstype == ONION_V3_HOSTNAME); tor_assert(!automap); return connection_ap_handle_onion(conn, socks, circ); -- cgit v1.2.3-54-g00ecf