
commit 7fceffac0f988670f4fd6b5eb061b2ebeee9e560 Author: Damian Johnson <atagar@torproject.org> Date: Sat Mar 5 12:06:25 2016 -0800 Normalize accept6/reject6 into normal exit policy rules On reflection accept6/reject6 is just syntatic sugar (and pretty worthless syntatic sugar at that). Normalizing these rules into normal exit policies. --- docs/change_log.rst | 3 +-- stem/exit_policy.py | 28 ++++++++-------------------- test/unit/exit_policy/rule.py | 18 ++++++++++-------- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/docs/change_log.rst b/docs/change_log.rst index b01602a..4f688aa 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -47,8 +47,7 @@ The following are only available within Stem's `git repository * Dramatic, `300x performance improvement <https://github.com/DonnchaC/stem/pull/1>`_ for reading from the control port with python 3 * 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`) + * :class:`~stem.exit_policy.ExitPolicy` support for *accept6/reject6* and *\*4/6* wildcards (:trac:`16053`) * 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 f71a638..003107e 100644 --- a/stem/exit_policy.py +++ b/stem/exit_policy.py @@ -627,14 +627,9 @@ class ExitPolicyRule(object): This should be treated as an immutable 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. + Support for 'accept6/reject6' entries and '\*4/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 :var str address: address that this rule is for @@ -651,7 +646,7 @@ class ExitPolicyRule(object): # exitpattern ::= addrspec ":" portspec self.is_accept = rule.startswith('accept') - self.is_ipv6_only = rule.startswith('accept6') or rule.startswith('reject6') + is_ipv6_only = rule.startswith('accept6') or rule.startswith('reject6') if rule.startswith('accept6') or rule.startswith('reject6'): exitpattern = rule[7:] @@ -689,7 +684,7 @@ class ExitPolicyRule(object): self._skip_rule = False addrspec, portspec = exitpattern.rsplit(':', 1) - self._apply_addrspec(rule, addrspec) + self._apply_addrspec(rule, addrspec, is_ipv6_only) self._apply_portspec(rule, portspec) # Flags to indicate if this rule seems to be expanded from the 'private' @@ -741,9 +736,6 @@ class ExitPolicyRule(object): # validate our input and check if the argument doesn't match our address type if address is not None: - if self.is_ipv6_only and stem.util.connection.is_valid_ipv4_address(address): - return False # accept6/reject6 don't match ipv4 - address_type = self.get_address_type() if stem.util.connection.is_valid_ipv4_address(address): @@ -874,10 +866,7 @@ class ExitPolicyRule(object): to re-create this rule. """ - if self.is_ipv6_only: - label = 'accept6 ' if self.is_accept else 'reject6 ' - else: - label = 'accept ' if self.is_accept else 'reject ' + label = 'accept ' if self.is_accept else 'reject ' if self.is_address_wildcard(): label += '*:' @@ -915,7 +904,7 @@ class ExitPolicyRule(object): if self._hash is None: my_hash = 0 - for attr in ('is_accept', 'is_ipv6_only', 'address', 'min_port', 'max_port'): + for attr in ('is_accept', 'address', 'min_port', 'max_port'): my_hash *= 1024 attr_value = getattr(self, attr) @@ -942,7 +931,7 @@ class ExitPolicyRule(object): return int(stem.util.connection._get_address_binary(self.address), 2) & self._get_mask_bin() - def _apply_addrspec(self, rule, addrspec): + def _apply_addrspec(self, rule, addrspec, is_ipv6_only): # Parses the addrspec... # addrspec ::= "*" | ip4spec | ip6spec @@ -951,7 +940,7 @@ class ExitPolicyRule(object): if addrspec == '*4': addrspec = '0.0.0.0/0' - elif addrspec == '*6': + elif addrspec == '*6' or (addrspec == '*' and is_ipv6_only): addrspec = '[0000:0000:0000:0000:0000:0000:0000:0000]/0' if '/' in addrspec: @@ -968,7 +957,7 @@ class ExitPolicyRule(object): # ip4mask ::= an IPv4 mask in dotted-quad format # num_ip4_bits ::= an integer between 0 and 32 - if self.is_ipv6_only: + if is_ipv6_only: self._skip_rule = True self._address_type = _address_type_to_int(AddressType.IPv4) @@ -1074,7 +1063,6 @@ class MicroExitPolicyRule(ExitPolicyRule): def __init__(self, is_accept, min_port, max_port): self.is_accept = is_accept - self.is_ipv6_only = False self.address = None # wildcard address self.min_port = min_port self.max_port = max_port diff --git a/test/unit/exit_policy/rule.py b/test/unit/exit_policy/rule.py index 59dc5d2..908e72b 100644 --- a/test/unit/exit_policy/rule.py +++ b/test/unit/exit_policy/rule.py @@ -42,8 +42,6 @@ class TestExitPolicyRule(unittest.TestCase): test_inputs = ( 'accept *:*', 'reject *:*', - 'accept6 *:*', - 'reject6 *:*', 'accept *:80', 'accept *:80-443', @@ -66,10 +64,15 @@ class TestExitPolicyRule(unittest.TestCase): 'accept [::]/32:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/32:*', 'accept [::]/128:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]:*', + 'accept6 *:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/0:*', + 'reject6 *:*': 'reject [0000:0000:0000:0000:0000:0000:0000:0000]/0:*', + 'accept6 [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:*': 'accept [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:*', + 'reject6 [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:*': 'reject [FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:*', + '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:*', + 'accept6 *4:*': 'accept 0.0.0.0/0:*', + 'accept6 *6:*': 'accept [0000:0000:0000:0000:0000:0000:0000:0000]/0:*', } for rule_arg, expected_str in test_inputs.items(): @@ -96,8 +99,8 @@ class TestExitPolicyRule(unittest.TestCase): '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), - 'reject6 *:*': (True, True), - 'reject6 *:80': (True, False), + 'reject6 *:*': (False, True), + 'reject6 *:80': (False, False), 'reject6 [0000:0000:0000:0000:0000:0000:0000:0000]/128:80': (False, False), 'accept 192.168.0.1:0-65535': (False, True), @@ -110,7 +113,7 @@ class TestExitPolicyRule(unittest.TestCase): is_address_wildcard, is_port_wildcard = attr rule = ExitPolicyRule(rule_arg) - self.assertEqual(is_address_wildcard, rule.is_address_wildcard()) + self.assertEqual(is_address_wildcard, rule.is_address_wildcard(), '%s (wildcard expected %s and actually %s)' % (rule_arg, is_address_wildcard, rule.is_address_wildcard())) self.assertEqual(is_port_wildcard, rule.is_port_wildcard()) # check that when appropriate a /0 is reported as *not* being a wildcard @@ -393,6 +396,5 @@ class TestExitPolicyRule(unittest.TestCase): # wildcards match all ipv6 but *not* ipv4 rule = ExitPolicyRule('accept6 *:*') - self.assertTrue(rule.is_ipv6_only) self.assertTrue(rule.is_match('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', 443)) self.assertFalse(rule.is_match('192.168.0.1', 443))