[tor-commits] [tor/master] Always allow OR connections to bridges on private addresses

nickm at torproject.org nickm at torproject.org
Thu Mar 24 14:14:10 UTC 2016


commit f2153f9716876b87bfcc53ff13b86b878edaae86
Author: teor (Tim Wilson-Brown) <teor2345 at gmail.com>
Date:   Wed Mar 23 13:37:35 2016 +1100

    Always allow OR connections to bridges on private addresses
    
    Regardless of the setting of ExtendAllowPrivateAddresses.
    
    This fixes a bug with pluggable transports that ignore the
    (potentially private) address in their bridge line.
    
    Fixes bug 18517; bugfix on 23b088907f in tor-0.2.8.1-alpha.
---
 changes/bug18517      |  6 ++++++
 doc/tor.1.txt         | 19 ++++++++++++-------
 src/or/circuitbuild.c | 11 +++++++++--
 src/or/entrynodes.c   | 24 +++++++++++++++++++++++-
 src/or/entrynodes.h   |  3 +++
 5 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/changes/bug18517 b/changes/bug18517
new file mode 100644
index 0000000..b82b5a4
--- /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 a71b04f..413af96 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)
@@ -1974,10 +1977,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 237b61a..a5a933e 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 3287fcd..8dbfeae 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 <b>digest</b>, or a
- * bridge with no known digest whose address matches <b>addr</b>:<b>/port</b>,
+ * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>,
  * return that bridge.  Else return NULL. If <b>digest</b> 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 <b>digest</b>, or a
+ * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>,
+ * return 1.  Else return 0. If <b>digest</b> 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
+ * <b>ei->identity_digest</b>, or a bridge with no known digest whose address
+ * matches <b>ei->addr</b>:<b>ei->port</b>, return 1.  Else return 0.
+ * If <b>ei->onion_key</b> 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 <b>ri</b>. */
 static bridge_info_t *
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 59147d1..247c809 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,





More information about the tor-commits mailing list