]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Implement proposal 204: ignore subdomains in hidden service addresses
authorJérémy Bobbio <lunar@debian.org>
Fri, 6 Jul 2012 13:31:47 +0000 (15:31 +0200)
committerNick Mathewson <nickm@torproject.org>
Thu, 17 Jan 2013 04:29:59 +0000 (23:29 -0500)
The implementation is pretty straightforward: parse_extended_hostname() is
modified to drop any leading components from an address like
'foo.aaaaaaaaaaaaaaaa.onion'.

changes/proposal204 [new file with mode: 0644]
src/or/connection_edge.c
src/test/test.c

diff --git a/changes/proposal204 b/changes/proposal204
new file mode 100644 (file)
index 0000000..4c1854b
--- /dev/null
@@ -0,0 +1,5 @@
+  o Minor features:
+    - Ignore sub-domain components of a .onion address. This makes HTTP "virtual"
+      hosting possible: http://foo.aaaaaaaaaaaaaaaa.onion/ and
+      http//bar.aaaaaaaaaaaaaaaa.onion/ can be two different websites hosted at
+      the same location. Implements proposal 204.
index a68a5cf42b811a8882f9ecdc49e12e34acddfa3b..870ded98c962ba7d39bed8a73421e809c892c646 100644 (file)
@@ -2813,6 +2813,9 @@ connection_ap_can_use_exit(const entry_connection_t *conn, const node_t *exit)
 /** If address is of the form "y.onion" with a well-formed handle y:
  *     Put a NUL after y, lower-case it, and return ONION_HOSTNAME.
  *
+ *  If address is of the form "x.y.onion" with a well-formed handle x:
+ *     Drop "x.", put a NUL after y, lower-case it, and return ONION_HOSTNAME.
+ *
  * If address is of the form "y.onion" with a badly-formed handle y:
  *     Return BAD_HOSTNAME and log a message.
  *
@@ -2826,6 +2829,7 @@ hostname_type_t
 parse_extended_hostname(char *address)
 {
     char *s;
+    char *q;
     char query[REND_SERVICE_ID_LEN_BASE32+1];
 
     s = strrchr(address,'.');
@@ -2840,9 +2844,18 @@ parse_extended_hostname(char *address)
 
     /* so it is .onion */
     *s = 0; /* NUL-terminate it */
-    if (strlcpy(query, address, REND_SERVICE_ID_LEN_BASE32+1) >=
+    /* locate a 'sub-domain' component, in order to remove it */
+    q = strrchr(address, '.');
+    if (q == address) {
+      goto failed; /* reject sub-domain, as DNS does */
+    }
+    q = (NULL == q) ? address : q + 1;
+    if (strlcpy(query, q, REND_SERVICE_ID_LEN_BASE32+1) >=
         REND_SERVICE_ID_LEN_BASE32+1)
       goto failed;
+    if (q != address) {
+      memmove(address, q, strlen(q) + 1 /* also get \0 */);
+    }
     if (rend_valid_service_id(query)) {
       return ONION_HOSTNAME; /* success */
     }
index c219d984a85b9d7c98abfa1d37164d43e2b58238..e3e989b0c18b009bb33e59a4fee2e80c18577fbd 100644 (file)
@@ -1412,11 +1412,20 @@ test_rend_fns(void)
   char address2[] = "aaaaaaaaaaaaaaaa.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";
 
   test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
   test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
+  test_streq(address2, "aaaaaaaaaaaaaaaa");
   test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
   test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
+  test_assert(ONION_HOSTNAME == parse_extended_hostname(address5));
+  test_streq(address5, "abcdefghijklmnop");
+  test_assert(ONION_HOSTNAME == parse_extended_hostname(address6));
+  test_streq(address6, "abcdefghijklmnop");
+  test_assert(BAD_HOSTNAME == parse_extended_hostname(address7));
 
   pk1 = pk_generate(0);
   pk2 = pk_generate(1);