summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2021-05-07 09:05:16 -0400
committerDavid Goulet <dgoulet@torproject.org>2021-05-07 09:05:16 -0400
commita42e58a284f2b1d8f975175c97eb044b57ce5905 (patch)
treeba33d20f7c66fb1ba5ee01d6cb78ab1f47835788
parentb1b4c05fb32b1f5a5306a16e9b61b7a4912c9209 (diff)
parent5e836eb80c31b97f87b152351b6a7a932aeffaed (diff)
downloadtor-a42e58a284f2b1d8f975175c97eb044b57ce5905.tar.gz
tor-a42e58a284f2b1d8f975175c97eb044b57ce5905.zip
Merge branch 'tor-gitlab/mr/375' into maint-0.4.6
-rw-r--r--changes/ticket403733
-rw-r--r--src/core/or/connection_edge.c43
-rw-r--r--src/core/or/connection_edge.h1
-rw-r--r--src/test/test_hs_common.c10
4 files changed, 55 insertions, 2 deletions
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 b89f3336dc..a307249967 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 <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
* 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));
@@ -2216,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
@@ -2501,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);
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);