aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/tor.1.in7
-rw-r--r--src/or/config.c1
-rw-r--r--src/or/connection_edge.c18
-rw-r--r--src/or/or.h9
-rw-r--r--src/or/test.c8
5 files changed, 32 insertions, 11 deletions
diff --git a/doc/tor.1.in b/doc/tor.1.in
index b6e22310f2..fa383ccba6 100644
--- a/doc/tor.1.in
+++ b/doc/tor.1.in
@@ -690,6 +690,13 @@ resolved. This helps trap accidental attempts to resolve URLs and so on.
(Default: 0)
.LP
.TP
+\fBAllowDotOnion \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
diff --git a/src/or/config.c b/src/or/config.c
index 1e559070ef..951f6fab5b 100644
--- a/src/or/config.c
+++ b/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"),
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 7a3d0a55be..79496f7a9b 100644
--- a/src/or/connection_edge.c
+++ b/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 */
diff --git a/src/or/or.h b/src/or/or.h
index 4f215d6448..253e89af85 100644
--- a/src/or/or.h
+++ b/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);
diff --git a/src/or/test.c b/src/or/test.c
index 3103eed828..dffb0a5ade 100644
--- a/src/or/test.c
+++ b/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);