mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Correct the behavior of .exit with ExcludeNodes, StrictNodes, etc.
ExcludeExitNodes foo now means that foo.exit doesn't work. If StrictNodes is set, then ExcludeNodes foo also overrides foo.exit. foo.exit , however, still works even if foo is not listed in ExitNodes.
This commit is contained in:
+38
-18
@@ -1497,9 +1497,13 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
||||
hostname_type_t addresstype;
|
||||
or_options_t *options = get_options();
|
||||
struct in_addr addr_tmp;
|
||||
/* We set this to true if this is an address we should automatically
|
||||
* remap to a local address in VirtualAddrNetwork */
|
||||
int automap = 0;
|
||||
char orig_address[MAX_SOCKS_ADDR_LEN];
|
||||
time_t map_expires = TIME_MAX;
|
||||
/* This will be set to true iff the address starts out as a non-.exit
|
||||
address, and we remap it to one because of an entry in the addressmap. */
|
||||
int remapped_to_exit = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
@@ -1610,18 +1614,24 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
||||
/* foo.exit -- modify conn->chosen_exit_node to specify the exit
|
||||
* node, and conn->address to hold only the address portion. */
|
||||
char *s = strrchr(socks->address,'.');
|
||||
|
||||
/* If StrictNodes is not set, then .exit overrides ExcludeNodes. */
|
||||
routerset_t *excludeset = options->StrictNodes ?
|
||||
options->_ExcludeExitNodesUnion : options->ExcludeExitNodes;
|
||||
/*XXX023 make this a node_t. */
|
||||
routerinfo_t *router;
|
||||
|
||||
tor_assert(!automap);
|
||||
if (s) {
|
||||
/* The address was of the form "(stuff).(name).exit */
|
||||
if (s[1] != '\0') {
|
||||
/* XXX022-1090 we should look this up as a relay and see if it's
|
||||
* in our excluded set, and refuse it here if so. But first,
|
||||
* figure out what's up with this 'remapped_to_exit' business
|
||||
* and whether that needs careful treatment. -RD */
|
||||
conn->chosen_exit_name = tor_strdup(s+1);
|
||||
router = router_get_by_nickname(conn->chosen_exit_name, 1);
|
||||
if (remapped_to_exit) /* 5 tries before it expires the addressmap */
|
||||
conn->chosen_exit_retries = TRACKHOSTEXITS_RETRIES;
|
||||
*s = 0;
|
||||
} else {
|
||||
/* Oops, the address was (stuff)..exit. That's not okay. */
|
||||
log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",
|
||||
safe_str_client(socks->address));
|
||||
control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
|
||||
@@ -1630,23 +1640,33 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
routerinfo_t *r;
|
||||
/* It looks like they just asked for "foo.exit". */
|
||||
conn->chosen_exit_name = tor_strdup(socks->address);
|
||||
r = router_get_by_nickname(conn->chosen_exit_name, 1);
|
||||
*socks->address = 0;
|
||||
if (r && (!options->_ExcludeExitNodesUnion ||
|
||||
!routerset_contains_router(options->_ExcludeExitNodesUnion,
|
||||
r))) {
|
||||
strlcpy(socks->address, r->address, sizeof(socks->address));
|
||||
} else {
|
||||
log_warn(LD_APP,
|
||||
"%s relay in exit address '%s.exit'. Refusing.",
|
||||
r ? "Excluded" : "Unrecognized",
|
||||
safe_str_client(socks->address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
router = router_get_by_nickname(conn->chosen_exit_name, 1);
|
||||
if (router) {
|
||||
*socks->address = 0;
|
||||
strlcpy(socks->address, router->address, sizeof(socks->address));
|
||||
}
|
||||
}
|
||||
/* Now make sure that the chosen exit exists... */
|
||||
if (!router) {
|
||||
log_warn(LD_APP,
|
||||
"Unrecognized relay in exit address '%s.exit'. Refusing.",
|
||||
safe_str_client(socks->address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
}
|
||||
/* ...and make sure that it isn't excluded. */
|
||||
if (routerset_contains_router(excludeset, router)) {
|
||||
log_warn(LD_APP,
|
||||
"Excluded relay in exit address '%s.exit'. Refusing.",
|
||||
safe_str_client(socks->address));
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
}
|
||||
/* XXXX022-1090 Should we also allow foo.bar.exit if ExitNodes is set and
|
||||
Bar is not listed in it? I say yes, but our revised manpage branch
|
||||
implies no. */
|
||||
}
|
||||
|
||||
if (addresstype != ONION_HOSTNAME) {
|
||||
|
||||
Reference in New Issue
Block a user