[tor-commits] [stem/master] Having ExitPolicyRules report /0 as a wildcard

atagar at torproject.org atagar at torproject.org
Mon Mar 25 03:54:22 UTC 2013


commit b05bf7a7eeb9807bf003518b39677f8c6abc39c8
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Mar 24 19:40:23 2013 -0700

    Having ExitPolicyRules report /0 as a wildcard
    
    ExitPolicyRules can apply to both IPv4 and IPv6. Because of this I treated * as
    a wildcard, but *not* /0 (since 0.0.0.0/0, though it applies to all IPv4
    addresses, doesn't cover IPv6). However, in most cases (everywhere except the
    torrc?) Tor's exit policies are limited to IPv4. As such, /0 should usually be
    treated as a wildcard. Change suggested by Aaron Johnson.
---
 stem/exit_policy.py           |   25 +++++++++++++++++++++----
 test/unit/exit_policy/rule.py |   16 ++++++++++++++--
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 2b0d6d4..c7219b2 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -131,6 +131,12 @@ def get_config_policy(rules):
     else:
       result.append(ExitPolicyRule(rule))
 
+  # torrc policies can apply to IPv4 or IPv6, so we need to make sure /0
+  # addresses aren't treated as being a full wildcard
+
+  for rule in result:
+    rule._submask_wildcard = False
+
   return ExitPolicy(*result)
 
 
@@ -510,16 +516,27 @@ class ExitPolicyRule(object):
 
     self._str_representation = None
 
+    # If true then a submask of /0 is treated by is_address_wildcard() as being
+    # a wildcard.
+
+    self._submask_wildcard = True
+
   def is_address_wildcard(self):
     """
-    **True** if we'll match against any address, **False** otherwise. Note that
-    this may be different from matching against a /0 because policies can
-    contain both IPv4 and IPv6 addresses (so 0.0.0.0/0 won't match against an
-    IPv6 address).
+    **True** if we'll match against any address, **False** otherwise.
+
+    Note that if this policy can apply to both IPv4 and IPv6 then this is
+    different from being for a /0 (since, for instance, 0.0.0.0/0 wouldn't
+    match against an IPv6 address). That said, /0 addresses are highly unusual
+    and most things citing exit policies are IPv4 specific anyway, making this
+    moot.
 
     :returns: **bool** for if our address matching is a wildcard
     """
 
+    if self._submask_wildcard and self.get_masked_bits() == 0:
+      return True
+
     return self._address_type == _address_type_to_int(AddressType.WILDCARD)
 
   def is_port_wildcard(self):
diff --git a/test/unit/exit_policy/rule.py b/test/unit/exit_policy/rule.py
index 0fe369b..09c0e23 100644
--- a/test/unit/exit_policy/rule.py
+++ b/test/unit/exit_policy/rule.py
@@ -69,10 +69,11 @@ class TestExitPolicyRule(unittest.TestCase):
       "accept 192.168.0.1:*": (False, True),
       "accept 192.168.0.1:80": (False, False),
 
-      "reject 127.0.0.1/0:*": (False, True),
+      "reject 127.0.0.1/0:*": (True, True),
+      "reject 127.0.0.1/0.0.0.0:*": (True, True),
       "reject 127.0.0.1/16:*": (False, True),
       "reject 127.0.0.1/32:*": (False, True),
-      "reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80": (False, False),
+      "reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80": (True, False),
       "reject [0000:0000:0000:0000:0000:0000:0000:0000]/64:80": (False, False),
       "reject [0000:0000:0000:0000:0000:0000:0000:0000]/128:80": (False, False),
 
@@ -89,6 +90,16 @@ class TestExitPolicyRule(unittest.TestCase):
       self.assertEquals(is_address_wildcard, rule.is_address_wildcard())
       self.assertEquals(is_port_wildcard, rule.is_port_wildcard())
 
+    # check that when appropriate a /0 is reported as *not* being a wildcard
+
+    rule = ExitPolicyRule("reject 127.0.0.1/0:*")
+    rule._submask_wildcard = False
+    self.assertEquals(False, rule.is_address_wildcard())
+
+    rule = ExitPolicyRule("reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80")
+    rule._submask_wildcard = False
+    self.assertEquals(False, rule.is_address_wildcard())
+
   def test_invalid_wildcard(self):
     test_inputs = (
       "reject */16:*",
@@ -237,6 +248,7 @@ class TestExitPolicyRule(unittest.TestCase):
 
     for rule_arg, matches in test_inputs.items():
       rule = ExitPolicyRule(rule_arg)
+      rule._submask_wildcard = False
 
       for match_args, expected_result in matches.items():
         self.assertEquals(expected_result, rule.is_match(*match_args))





More information about the tor-commits mailing list