(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
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"),
/* 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",
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) {
/** 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];
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 */
* 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;
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);
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);