[tor-commits] [stem/master] Expand *4 and *6 exit poicy wildcards

atagar at torproject.org atagar at torproject.org
Fri Mar 4 17:36:15 UTC 2016


commit 200dd8ad376257ee9e1ee4713254d6f4ba1c9f17
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Mar 4 09:30:29 2016 -0800

    Expand *4 and *6 exit poicy wildcards
    
    Like accept6 and reject6, we have a couple new wildcards to specify all IPv4 or
    IPv6 addresses. This is akin to being a '/0' so simply translating 'em into
    that. :P
---
 docs/change_log.rst           |  1 +
 stem/exit_policy.py           | 34 ++++++++++++++--------------------
 test/unit/exit_policy/rule.py | 28 +++++++++++++++++++++++++---
 3 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index 8a92788..b01602a 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -48,6 +48,7 @@ The following are only available within Stem's `git repository
   * Added `stem.manual <api/manual.html>`_, which provides information available about Tor from `its manual <https://www.torproject.org/docs/tor-manual.html.en>`_ (:trac:`8251`)
   * :func:`~stem.connection.connect` and :func:`~stem.control.Controller.from_port` now connect to both port 9051 (relay's default) and 9151 (Tor Browser's default) (:trac:`16075`)
   * :class:`~stem.exit_policy.ExitPolicy` support for *accept6* and *reject6* rules (:trac:`16103`)
+  * :class:`~stem.exit_policy.ExitPolicy` support for *\*4* and *\*6* wildcards (:trac:`16103`)
   * Added `support for NETWORK_LIVENESS events <api/response.html#stem.response.events.NetworkLivenessEvent>`_ (:spec:`44aac63`)
   * Added :func:`~stem.control.Controller.is_set` to the :class:`~stem.control.Controller`
   * Added :func:`~stem.control.Controller.is_user_traffic_allowed` to the :class:`~stem.control.Controller`
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 587ef14..f71a638 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -153,12 +153,6 @@ def get_config_policy(rules, ip_address = None):
     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)
 
 
@@ -635,6 +629,9 @@ class ExitPolicyRule(object):
   .. versionchanged:: 1.5.0
      Support for 'accept6/reject6' entries and our **is_ipv6_only** attribute.
 
+  .. versionchanged:: 1.5.0
+     Support for '\*4' and '\*6' wildcards.
+
   :var bool is_accept: indicates if exiting is allowed or disallowed
   :var bool is_ipv6_only: indicates if this is an accept6 or reject6 rule, only
     matching ipv6 addresses
@@ -695,11 +692,6 @@ class ExitPolicyRule(object):
     self._apply_addrspec(rule, addrspec)
     self._apply_portspec(rule, portspec)
 
-    # If true then a submask of /0 is treated by is_address_wildcard() as being
-    # a wildcard.
-
-    self._submask_wildcard = True
-
     # Flags to indicate if this rule seems to be expanded from the 'private'
     # keyword or tor's default policy suffix.
 
@@ -708,20 +700,14 @@ class ExitPolicyRule(object):
 
   def is_address_wildcard(self):
     """
-    **True** if we'll match against any address, **False** otherwise.
+    **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.
+    Note that this is different than \*4, \*6, or '/0' address which are
+    wildcards for only either IPv4 or IPv6.
 
     :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):
@@ -960,6 +946,14 @@ class ExitPolicyRule(object):
     # Parses the addrspec...
     # addrspec ::= "*" | ip4spec | ip6spec
 
+    # Expand IPv4 and IPv6 specific wildcards into /0 entries so we have one
+    # fewer bizarre special case headaches to deal with.
+
+    if addrspec == '*4':
+      addrspec = '0.0.0.0/0'
+    elif addrspec == '*6':
+      addrspec = '[0000:0000:0000:0000:0000:0000:0000:0000]/0'
+
     if '/' in addrspec:
       self.address, addr_extra = addrspec.split('/', 1)
     else:
diff --git a/test/unit/exit_policy/rule.py b/test/unit/exit_policy/rule.py
index 780f7cb..59dc5d2 100644
--- a/test/unit/exit_policy/rule.py
+++ b/test/unit/exit_policy/rule.py
@@ -44,6 +44,7 @@ class TestExitPolicyRule(unittest.TestCase):
       'reject *:*',
       'accept6 *:*',
       'reject6 *:*',
+
       'accept *:80',
       'accept *:80-443',
       'accept 127.0.0.1:80',
@@ -64,6 +65,11 @@ class TestExitPolicyRule(unittest.TestCase):
       'accept 192.168.0.1/255.255.255.0:80': 'accept 192.168.0.1/24:80',
       'accept [::]/32:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/32:*',
       'accept [::]/128:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]:*',
+
+      'accept *4:*': 'accept 0.0.0.0/0:*',
+      'accept *6:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/0:*',
+      'accept6 *4:*': 'accept6 0.0.0.0/0:*',
+      'accept6 *6:*': 'accept6 [0000:0000:0000:0000:0000:0000:0000:0000]/0:*',
     }
 
     for rule_arg, expected_str in test_inputs.items():
@@ -77,11 +83,16 @@ 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:*': (True, True),
-      'reject 127.0.0.1/0.0.0.0:*': (True, True),
+      'reject *4:*': (False, True),
+      'reject *6:*': (False, True),
+      'reject6 *4:*': (False, True),
+      'reject6 *6:*': (False, True),
+
+      'reject 127.0.0.1/0:*': (False, True),
+      'reject 127.0.0.1/0.0.0.0:*': (False, 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': (True, False),
+      'reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:80': (False, 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),
 
@@ -256,6 +267,14 @@ class TestExitPolicyRule(unittest.TestCase):
         (None, None, False): False,
         (None, None, True): True,
       },
+      'reject *4:*': {
+        ('192.168.0.1', 80): True,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): False,
+      },
+      'reject *6:*': {
+        ('192.168.0.1', 80): False,
+        ('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 80): True,
+      },
     }
 
     for rule_arg, matches in test_inputs.items():
@@ -368,6 +387,9 @@ class TestExitPolicyRule(unittest.TestCase):
     self.assertFalse(rule.is_match('FE80:0000:0000:0000:0202:B3FF:FE1E:8329'))
     self.assertFalse(rule.is_match())
 
+    rule = ExitPolicyRule('accept6 *4:*')
+    self.assertTrue(rule._skip_rule)
+
     # wildcards match all ipv6 but *not* ipv4
 
     rule = ExitPolicyRule('accept6 *:*')





More information about the tor-commits mailing list