[or-cvs] Warn when exit policy implicitly allows local addresses.

Nick Mathewson nickm at seul.org
Thu Jan 20 18:39:51 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria.mit.edu:/tmp/cvs-serv29801/src/or

Modified Files:
	config.c or.h routerlist.c 
Log Message:
Warn when exit policy implicitly allows local addresses.

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.303
retrieving revision 1.304
diff -u -d -r1.303 -r1.304
--- config.c	18 Jan 2005 19:34:22 -0000	1.303
+++ config.c	20 Jan 2005 18:39:48 -0000	1.304
@@ -1480,6 +1480,7 @@
     log_fn(LOG_WARN, "Error in Exit Policy entry.");
     result = -1;
   }
+  exit_policy_implicitly_allows_local_networks(addr_policy, 1);
   if (config_parse_addr_policy(options->DirPolicy, &addr_policy)) {
     log_fn(LOG_WARN, "Error in DirPolicy entry.");
     result = -1;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.527
retrieving revision 1.528
diff -u -d -r1.527 -r1.528
--- or.h	19 Jan 2005 23:15:59 -0000	1.527
+++ or.h	20 Jan 2005 18:39:48 -0000	1.528
@@ -1615,6 +1615,8 @@
 int router_nickname_is_in_list(routerinfo_t *router, const char *list);
 routerinfo_t *routerlist_find_my_routerinfo(void);
 int router_nickname_matches(routerinfo_t *router, const char *nickname);
+int exit_policy_implicitly_allows_local_networks(addr_policy_t *policy,
+                                                 int warn);
 
 /** How many seconds a router must be up before we'll use it for
  * reliability-critical node positions.

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.206
retrieving revision 1.207
diff -u -d -r1.206 -r1.207
--- routerlist.c	13 Jan 2005 20:22:38 -0000	1.206
+++ routerlist.c	20 Jan 2005 18:39:48 -0000	1.207
@@ -1021,6 +1021,90 @@
   return 1; /* all will reject. */
 }
 
+/**
+ * If <b>policy</b> implicitly allows connections to any port in the
+ * IP set <b>addr</b>/<b>mask</b>, then set *<b>policy_out</b> to the
+ * part of the policy that allows it, and return 1.  Else return 0.
+ *
+ * A policy allows an IP:Port combination <em>implicitly</em> if
+ * it is included in a *: pattern, or in a fallback pattern.
+ */
+static int
+policy_includes_addr_mask_implicitly(addr_policy_t *policy,
+                                     uint32_t addr, uint32_t mask,
+                                     addr_policy_t **policy_out)
+{
+  uint32_t addr2;
+  tor_assert(policy_out);
+  addr &= mask;
+  addr2 = addr | ~mask;
+  for (; policy; policy=policy->next) {
+    /* Does this policy cover all of the address range we're looking at? */
+    /* Boolean logic time: range X is contained in range Y if, for
+     * each bit B, all possible values of B in X are values of B in Y.
+     * In "addr", we have every fixed bit set to its value, and every
+     * free bit set to 0.  In "addr2", we have every fixed bit set to
+     * its value, and every free bit set to 1.  So if addr and addr2 are
+     * both in the policy, the range is covered by the policy.
+     */
+    if ((policy->addr & policy->msk) == (addr & policy->msk) &&
+        (policy->addr & policy->msk) == (addr2 & policy->msk) &&
+        (policy->prt_min <= 1 && policy->prt_max == 65535)) {
+      return 0;
+    }
+    /* Does this policy cover some of the address range we're looking at? */
+    /* Boolean logic time: range X and range Y intersect if there is
+     * some z such that z & Xmask == Xaddr and z & Ymask == Yaddr.
+     * This is FALSE iff there is some bit b where Xmask == yMask == 1
+     * and Xaddr != Yaddr.  So if X intersects with Y iff at every
+     * place where Xmask&Ymask==1, Xaddr == Yaddr, or equivalently,
+     * Xaddr&Xmask&Ymask == Yaddr&Xmask&Ymask.
+     */
+    if ((policy->addr & policy->msk & mask) == (addr & policy->msk) &&
+        policy->policy_type == ADDR_POLICY_ACCEPT) {
+      *policy_out = policy;
+      return 1;
+    }
+  }
+  *policy_out = NULL;
+  return 1;
+}
+
+/** If <b>policy</b> implicitly allows connections to any port on
+ * 127.*, 192.168.*, etc, then warn (if <b>warn</b> is set) and return
+ * true.  Else return false.
+ **/
+int
+exit_policy_implicitly_allows_local_networks(addr_policy_t *policy,
+                                             int warn)
+{
+  addr_policy_t *p;
+  int r=0,i;
+  static struct {
+    uint32_t addr; uint32_t mask; const char *network;
+  } private_networks[] = {
+    { 0x7f000000, 0xff000000, "localhost (127.x)" },
+    { 0x0a000000, 0xff000000, "addresses in private network 10.x" },
+    { 0xa9fe0000, 0xffff0000, "addresses in private network 169.254.x" },
+    { 0xac100000, 0xfff00000, "addresses in private network 172.16.x" },
+    { 0xc0a80000, 0xffff0000, "addresses in private network 192.168.x" },
+    { 0,0,NULL},
+  };
+  for (i=0; private_networks[i].addr; ++i) {
+    p = NULL;
+      if (policy_includes_addr_mask_implicitly(
+              policy, private_networks[i].addr, private_networks[i].mask, &p)) {
+        if (warn)
+          log_fn(LOG_WARN, "Exit policy %s implicitly accepts %s",
+                 policy?policy->string:"(default)",
+                 private_networks[i].network);
+        r = 1;
+      }
+  }
+
+  return r;
+}
+
 /** Return true iff <b>router</b> does not permit exit streams.
  */
 int router_exit_policy_rejects_all(routerinfo_t *router) {



More information about the tor-commits mailing list