commit caee7d6c968fd6cd9912dc4a554d66e303316b61 Author: Damian Johnson atagar@torproject.org Date: Sat Mar 23 19:50:52 2013 -0700
Switching exit policy's can_exit_to() and is_match() be permissive
Switching how the ExitPolicy's can_exit_to() and ExitPolicyRule's is_match() handle an undefined address or port. Previously we reported if we matched or allowed exiting to *all* instance of the defined destination. Now, however, rather if we match against *any*.
Change was requested by Aaron Johnson. You can still get the old behavior by setting the 'strict' argument. --- stem/exit_policy.py | 29 ++++++++++++++++++----------- test/unit/exit_policy/rule.py | 33 ++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/stem/exit_policy.py b/stem/exit_policy.py index d187d62..2b0d6d4 100644 --- a/stem/exit_policy.py +++ b/stem/exit_policy.py @@ -156,29 +156,31 @@ class ExitPolicy(object): self._summary_representation = None self._can_exit_to_cache = {}
- def can_exit_to(self, address = None, port = None): + def can_exit_to(self, address = None, port = None, strict = False): """ Checks if this policy allows exiting to a given destination or not. If the - address or port is omitted then this will check if we allow for its - wildcard. + address or port is omitted then this will check if we're allowed to exit to + any instances of the defined address or port.
:param str address: IPv4 or IPv6 address (with or without brackets) :param int port: port number + :param bool strict: if the address or port is excluded then check if we can + exit to **all** instances of the defined address or port
:returns: **True** if exiting to this destination is allowed, **False** otherwise """
- if not (address, port) in self._can_exit_to_cache: + if not (address, port, strict) in self._can_exit_to_cache: result = self._is_allowed_default
for rule in self._get_rules(): - if rule.is_match(address, port): + if rule.is_match(address, port, strict): result = rule.is_accept break
- self._can_exit_to_cache[(address, port)] = result + self._can_exit_to_cache[(address, port, strict)] = result
- return self._can_exit_to_cache[(address, port)] + return self._can_exit_to_cache[(address, port, strict)]
def is_exiting_allowed(self): """ @@ -529,13 +531,16 @@ class ExitPolicyRule(object):
return self.min_port in (0, 1) and self.max_port == 65535
- def is_match(self, address = None, port = None): + def is_match(self, address = None, port = None, strict = False): """ **True** if we match against the given destination, **False** otherwise. If - the address or port is omitted then that'll only match against a wildcard. + the address or port is omitted then this will check if we're allowed to + exit to any instances of the defined address or port.
:param str address: IPv4 or IPv6 address (with or without brackets) :param int port: port number + :param bool strict: if the address or port is excluded then check if we can + exit to **all** instances of the defined address or port
:returns: **bool** indicating if we match against this destination
@@ -566,7 +571,8 @@ class ExitPolicyRule(object): # mask applied matches.
if address is None: - return False + if strict: + return False else: comparison_addr_bin = int(stem.util.connection._get_address_binary(address), 2) comparison_addr_bin &= self._get_mask_bin() @@ -576,7 +582,8 @@ class ExitPolicyRule(object):
if not self.is_port_wildcard(): if port is None: - return False + if strict: + return False elif port < self.min_port or port > self.max_port: return False
diff --git a/test/unit/exit_policy/rule.py b/test/unit/exit_policy/rule.py index 1bf3911..0fe369b 100644 --- a/test/unit/exit_policy/rule.py +++ b/test/unit/exit_policy/rule.py @@ -216,8 +216,10 @@ class TestExitPolicyRule(unittest.TestCase): ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): True, ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): True, ("192.168.0.1", None): True, - (None, 80): True, - (None, None): True, + (None, 80, False): True, + (None, 80, True): True, + (None, None, False): True, + (None, None, True): True, }, "reject 255.255.255.255/0:*": { ("192.168.0.1", 80): True, @@ -226,8 +228,10 @@ class TestExitPolicyRule(unittest.TestCase): ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", 80): False, ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): False, ("192.168.0.1", None): True, - (None, 80): False, - (None, None): False, + (None, 80, False): True, + (None, 80, True): False, + (None, None, False): True, + (None, None, True): False, }, }
@@ -249,7 +253,8 @@ class TestExitPolicyRule(unittest.TestCase): ("192.168.0.50", 80): True, ("192.168.0.51", 80): False, ("192.168.0.49", 80): False, - (None, 80): False, + (None, 80, False): True, + (None, 80, True): False, ("192.168.0.50", None): True, }, "reject 0.0.0.0/24:*": { @@ -259,7 +264,8 @@ class TestExitPolicyRule(unittest.TestCase): ("0.0.1.0", 80): False, ("0.1.0.0", 80): False, ("1.0.0.0", 80): False, - (None, 80): False, + (None, 80, False): True, + (None, 80, True): False, ("0.0.0.0", None): True, }, } @@ -278,7 +284,8 @@ class TestExitPolicyRule(unittest.TestCase): ("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]", 80): True, ("FE80:0000:0000:0000:0202:B3FF:FE1E:8330", 80): False, ("FE80:0000:0000:0000:0202:B3FF:FE1E:8328", 80): False, - (None, 80): False, + (None, 80, False): True, + (None, 80, True): False, ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None): True, }, "reject [FE80:0000:0000:0000:0202:B3FF:FE1E:8329]/112:*": { @@ -287,8 +294,10 @@ class TestExitPolicyRule(unittest.TestCase): ("FE80:0000:0000:0000:0202:B3FF:FE1E:FFFF", 80): True, ("FE80:0000:0000:0000:0202:B3FF:FE1F:8329", 80): False, ("FE81:0000:0000:0000:0202:B3FF:FE1E:8329", 80): False, - (None, 80): False, - ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None): True, + (None, 80, False): True, + (None, 80, True): False, + ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None, False): True, + ("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", None, True): True, }, }
@@ -305,7 +314,8 @@ class TestExitPolicyRule(unittest.TestCase): ("192.168.0.50", 81): False, ("192.168.0.50", 79): False, (None, 80): True, - ("192.168.0.50", None): False, + ("192.168.0.50", None, False): True, + ("192.168.0.50", None, True): False, }, "reject *:80-85": { ("192.168.0.50", 79): False, @@ -314,7 +324,8 @@ class TestExitPolicyRule(unittest.TestCase): ("192.168.0.50", 85): True, ("192.168.0.50", 86): False, (None, 83): True, - ("192.168.0.50", None): False, + ("192.168.0.50", None, False): True, + ("192.168.0.50", None, True): False, }, }
tor-commits@lists.torproject.org