diff --git a/changes/bug18517 b/changes/bug18517 new file mode 100644 index 0000000000..b82b5a4b0d --- /dev/null +++ b/changes/bug18517 @@ -0,0 +1,6 @@ + o Major bugfixes (bridges, pluggable transports): + - Modify the check for OR connections to private addresses. + Allow bridges on private addresses, including pluggable transports + that ignore the (potentially private) address in the bridge line. + Fixes bug 18517; bugfix on 23b088907f in tor-0.2.8.1-alpha. + Reported by "gk", patch by "teor". diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 389b9fac45..84cfb28173 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -747,9 +747,12 @@ The following options are useful only for clients (that is, if fingerprint to look up the bridge descriptor at the bridge authority, if it's provided and if UpdateBridgesFromAuthority is set too. + + - If "transport" is provided, and matches to a ClientTransportPlugin - line, we use that pluggable transports proxy to transfer data to - the bridge. + If "transport" is provided, it must match a ClientTransportPlugin line. We + then use that pluggable transport's proxy to transfer data to the bridge, + rather than connecting to the bridge directly. Some transports use a + transport-specific method to work out the remote address to connect to. + These transports typically ignore the "IP:ORPort" specified in the bridge + line. [[LearnCircuitBuildTimeout]] **LearnCircuitBuildTimeout** **0**|**1**:: If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1) @@ -1975,10 +1978,12 @@ is non-zero): (Default: 1) [[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**:: - When this option is enabled, Tor will connect to localhost, RFC1918 - addresses, and so on. In particular, Tor will make direct connections, and - Tor routers allow EXTEND requests, to these private addresses. This can - create security issues; you should probably leave it off. + When this option is enabled, Tor will connect to relays on localhost, + RFC1918 addresses, and so on. In particular, Tor will make direct OR + connections, and Tor routers allow EXTEND requests, to these private + addresses. (Tor will always allow connections to bridges, proxies, and + pluggable transports configured on private addresses.) Enabling this + option can create security issues; you should probably leave it off. (Default: 0) [[MaxMemInQueues]] **MaxMemInQueues** __N__ **bytes**|**KB**|**MB**|**GB**:: diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 237b61ab18..a5a933e6b0 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -495,14 +495,21 @@ circuit_handle_first_hop(origin_circuit_t *circ) int err_reason = 0; const char *msg = NULL; int should_launch = 0; + const or_options_t *options = get_options(); firsthop = onion_next_hop_in_cpath(circ->cpath); tor_assert(firsthop); tor_assert(firsthop->extend_info); - /* XX/teor - does tor ever need build a circuit directly to itself? */ + /* Some bridges are on private addresses. Others pass a dummy private + * address to the pluggable transport, which ignores it. + * Deny the connection if: + * - the address is internal, and + * - we're not connecting to a configured bridge, and + * - we're not configured to allow extends to private addresses. */ if (tor_addr_is_internal(&firsthop->extend_info->addr, 0) && - !get_options()->ExtendAllowPrivateAddresses) { + !extend_info_is_a_configured_bridge(firsthop->extend_info) && + !options->ExtendAllowPrivateAddresses) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Client asked me to connect directly to a private address"); return -END_CIRC_REASON_TORPROTOCOL; diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 3287fcd584..8dbfeaecea 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1795,7 +1795,7 @@ get_configured_bridge_by_orports_digest(const char *digest, } /** If we have a bridge configured whose digest matches digest, or a - * bridge with no known digest whose address matches addr:/port, + * bridge with no known digest whose address matches addr:port, * return that bridge. Else return NULL. If digest is NULL, check for * address/port matches only. */ static bridge_info_t * @@ -1818,6 +1818,28 @@ get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr, return NULL; } +/** If we have a bridge configured whose digest matches digest, or a + * bridge with no known digest whose address matches addr:port, + * return 1. Else return 0. If digest is NULL, check for + * address/port matches only. */ +int addr_is_a_configured_bridge(const tor_addr_t *addr, + uint16_t port, + const char *digest) +{ + tor_assert(addr); + return get_configured_bridge_by_addr_port_digest(addr, port, digest) ? 1 : 0; +} + +/** If we have a bridge configured whose digest matches + * ei->identity_digest, or a bridge with no known digest whose address + * matches ei->addr:ei->port, return 1. Else return 0. + * If ei->onion_key is NULL, check for address/port matches only. */ +int extend_info_is_a_configured_bridge(const extend_info_t *ei) +{ + const char *digest = ei->onion_key ? ei->identity_digest : NULL; + return addr_is_a_configured_bridge(&ei->addr, ei->port, digest); +} + /** Wrapper around get_configured_bridge_by_addr_port_digest() to look * it up via router descriptor ri. */ static bridge_info_t * diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index 59147d19b5..247c80940e 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -127,6 +127,9 @@ int getinfo_helper_entry_guards(control_connection_t *conn, void mark_bridge_list(void); void sweep_bridge_list(void); +int addr_is_a_configured_bridge(const tor_addr_t *addr, uint16_t port, + const char *digest); +int extend_info_is_a_configured_bridge(const extend_info_t *ei); int routerinfo_is_a_configured_bridge(const routerinfo_t *ri); int node_is_a_configured_bridge(const node_t *node); void learned_router_identity(const tor_addr_t *addr, uint16_t port,