Browse Source

Merge commit 'arma/dotexit'

Nick Mathewson 15 years ago
parent
commit
4311b9a6d1
5 changed files with 32 additions and 11 deletions
  1. 7 0
      doc/tor.1.in
  2. 1 0
      src/or/config.c
  3. 12 6
      src/or/connection_edge.c
  4. 8 1
      src/or/or.h
  5. 4 4
      src/or/test.c

+ 7 - 0
doc/tor.1.in

@@ -692,6 +692,13 @@ resolved.  This helps trap accidental attempts to resolve URLs and so on.
 (Default: 0)
 .LP
 .TP
+\fBAllowDotExit \fR\fB0\fR|\fB1\fR\fP
+If enabled, we convert "www.google.com.foo.exit" addresses on the
+SocksPort/TransPort/NatdPort into "www.google.com" addresses that exit
+from the node "foo". Disabled by default since attacking websites and
+exit relays can use it to manipulate your path selection. (Default: 0)
+.LP
+.TP
 \fBFastFirstHopPK \fR\fB0\fR|\fB1\fR\fP
 When this option is disabled, Tor uses the public key step for the first
 hop of creating circuits. Skipping it is generally safe since we have

+ 1 - 0
src/or/config.c

@@ -134,6 +134,7 @@ static config_var_t _option_vars[] = {
   V(AccountingMax,               MEMUNIT,  "0 bytes"),
   V(AccountingStart,             STRING,   NULL),
   V(Address,                     STRING,   NULL),
+  V(AllowDotExit,                BOOL,     "0"),
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
   V(AllowSingleHopCircuits,      BOOL,     "0"),

+ 12 - 6
src/or/connection_edge.c

@@ -1483,7 +1483,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
   /* Parse the address provided by SOCKS.  Modify it in-place if it
    * specifies a hidden-service (.onion) or particular exit node (.exit).
    */
-  addresstype = parse_extended_hostname(socks->address);
+  addresstype = parse_extended_hostname(socks->address,
+                         remapped_to_exit || options->AllowDotExit);
 
   if (addresstype == BAD_HOSTNAME) {
     log_warn(LD_APP, "Invalid onion hostname %s; rejecting",
@@ -1496,7 +1497,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
 
   if (addresstype == EXIT_HOSTNAME) {
     /* foo.exit -- modify conn->chosen_exit_node to specify the exit
-     * node, and conn->address to hold only the address portion.*/
+     * node, and conn->address to hold only the address portion. */
     char *s = strrchr(socks->address,'.');
     tor_assert(!automap);
     if (s) {
@@ -2902,14 +2903,14 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_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 "y.exit":
+ * If address is of the form "y.exit" and <b>allowdotexit</b> is true:
  *     Put a NUL after y and return EXIT_HOSTNAME.
  *
  * Otherwise:
  *     Return NORMAL_HOSTNAME and change nothing.
  */
 hostname_type_t
-parse_extended_hostname(char *address)
+parse_extended_hostname(char *address, int allowdotexit)
 {
     char *s;
     char query[REND_SERVICE_ID_LEN_BASE32+1];
@@ -2918,8 +2919,13 @@ parse_extended_hostname(char *address)
     if (!s)
       return NORMAL_HOSTNAME; /* no dot, thus normal */
     if (!strcmp(s+1,"exit")) {
-      *s = 0; /* NUL-terminate it */
-      return EXIT_HOSTNAME; /* .exit */
+      if (allowdotexit) {
+        *s = 0; /* NUL-terminate it */
+        return EXIT_HOSTNAME; /* .exit */
+      } /* else */
+      log_warn(LD_APP, "The \".exit\" notation is disabled in Tor due to "
+               "security risks. Set AllowDotExit in your torrc to enable it.");
+      /* FFFF send a controller event too to notify Vidalia users */
     }
     if (strcmp(s+1,"onion"))
       return NORMAL_HOSTNAME; /* neither .exit nor .onion, thus normal */

+ 8 - 1
src/or/or.h

@@ -2508,6 +2508,13 @@ typedef struct {
    * exit allows it, we use it. */
   int AllowSingleHopCircuits;
 
+  /** If true, we convert "www.google.com.foo.exit" addresses on the
+   * socks/trans/natd ports into "www.google.com" addresses that
+   * exit from the node "foo". Disabled by default since attacking
+   * websites and exit relays can use it to manipulate your path
+   * selection. */
+  int AllowDotExit;
+
   /** If true, the user wants us to collect statistics on clients
    * requesting network statuses from us as directory. */
   int DirReqStatistics;
@@ -3133,7 +3140,7 @@ int hostname_is_noconnect_address(const char *address);
 typedef enum hostname_type_t {
   NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME, BAD_HOSTNAME
 } hostname_type_t;
-hostname_type_t parse_extended_hostname(char *address);
+hostname_type_t parse_extended_hostname(char *address, int allowdotexit);
 
 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
 int get_pf_socket(void);

+ 4 - 4
src/or/test.c

@@ -4489,10 +4489,10 @@ test_rend_fns(void)
   char address3[] = "fooaddress.exit";
   char address4[] = "www.torproject.org";
 
-  test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
-  test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
-  test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
-  test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
+  test_assert(BAD_HOSTNAME == parse_extended_hostname(address1, 1));
+  test_assert(ONION_HOSTNAME == parse_extended_hostname(address2, 1));
+  test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3, 1));
+  test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4, 1));
 
   pk1 = pk_generate(0);
   pk2 = pk_generate(1);