diff options
| author | Damian Johnson <atagar@torproject.org> | 2016-10-28 09:45:42 -0700 |
|---|---|---|
| committer | Damian Johnson <atagar@torproject.org> | 2016-10-29 14:14:19 -0700 |
| commit | 3cf69496466a46af56bf7b9bc789003ead7d1118 (patch) | |
| tree | 4ba09baa7c5c47ef0e3f2212bd0e5fdc52dbf508 | |
| parent | ebfd8bb67b681527089249c747844cf07fba8adf (diff) | |
Unit tests fail when no address is available
When expanding the 'private' alias for exit policies the last entry is for our
pubic address. When python is unable to determine one get_config_policy()
excludes this last entry, in turn causing our unit tests to fail...
https://trac.torproject.org/projects/tor/ticket/20476
Being more careful to treat this part of the policy as being optional.
| -rw-r--r-- | stem/exit_policy.py | 26 | ||||
| -rw-r--r-- | test/unit/exit_policy/policy.py | 14 |
2 files changed, 27 insertions, 13 deletions
diff --git a/stem/exit_policy.py b/stem/exit_policy.py index 1aa2537a..2e2b459f 100644 --- a/stem/exit_policy.py +++ b/stem/exit_policy.py @@ -165,10 +165,10 @@ def _flag_private_rules(rules): series of rules exactly matching it. """ - matches = [] + matches = [] # find all possible starting indexes for i, rule in enumerate(rules): - if i + len(PRIVATE_ADDRESSES) + 1 > len(rules): + if i + len(PRIVATE_ADDRESSES) > len(rules): break rule_str = '%s/%s' % (rule.address, rule.get_masked_bits()) @@ -180,33 +180,35 @@ def _flag_private_rules(rules): # To match the private policy the following must all be true... # # * series of addresses and bit masks match PRIVATE_ADDRESSES - # * all rules have the same port range and acceptance + # * all rules have the same port range # * all rules have the same acceptance (all accept or reject entries) + # + # The last rule is dynamically based on the relay's public address. It may + # not be present if get_config_policy() created this policy and we couldn't + # resolve our address. - rule_set = rules[start_index:start_index + len(PRIVATE_ADDRESSES) + 1] + last_index = start_index + len(PRIVATE_ADDRESSES) + rule_set = rules[start_index:last_index] + last_rule = rules[last_index] if len(rules) > last_index else None is_match = True min_port, max_port = rule_set[0].min_port, rule_set[0].max_port is_accept = rule_set[0].is_accept - for i, rule in enumerate(rule_set[:-1]): + for i, rule in enumerate(rule_set): rule_str = '%s/%s' % (rule.address, rule.get_masked_bits()) if rule_str != PRIVATE_ADDRESSES[i] or rule.min_port != min_port or rule.max_port != max_port or rule.is_accept != is_accept: is_match = False break - # The last rule is for the relay's public address, so it's dynamic. - - last_rule = rule_set[-1] - - if last_rule.is_address_wildcard() or last_rule.min_port != min_port or last_rule.max_port != max_port or last_rule.is_accept != is_accept: - is_match = False - if is_match: for rule in rule_set: rule._is_private = True + if last_rule and not last_rule.is_address_wildcard() and last_rule.min_port == min_port and last_rule.max_port == max_port and last_rule.is_accept == is_accept: + last_rule._is_private = True + def _flag_default_rules(rules): """ diff --git a/test/unit/exit_policy/policy.py b/test/unit/exit_policy/policy.py index 5c20d0d8..b1187ac5 100644 --- a/test/unit/exit_policy/policy.py +++ b/test/unit/exit_policy/policy.py @@ -5,6 +5,12 @@ Unit tests for the stem.exit_policy.ExitPolicy class. import pickle import unittest +try: + # added in python 3.3 + from unittest.mock import Mock, patch +except ImportError: + from mock import Mock, patch + from stem.exit_policy import ( DEFAULT_POLICY_RULES, get_config_policy, @@ -123,7 +129,7 @@ class TestExitPolicy(unittest.TestCase): def test_all_private_policy(self): for port in ('*', '80', '1-1024'): - private_policy = get_config_policy('reject private:%s' % port) + private_policy = get_config_policy('reject private:%s' % port, '12.34.56.78') for rule in private_policy: self.assertTrue(rule.is_private()) @@ -135,6 +141,12 @@ class TestExitPolicy(unittest.TestCase): private_policy = get_config_policy('accept private:*') self.assertEqual(ExitPolicy(), private_policy.strip_private()) + @patch('socket.gethostname', Mock(side_effect = IOError('no address'))) + def test_all_private_policy_without_network(self): + for rule in get_config_policy('reject private:80, accept *:80'): + # all rules except the ending accept are part of the private policy + self.assertEqual(str(rule) != 'accept *:80', rule.is_private()) + def test_all_default_policy(self): policy = ExitPolicy(*DEFAULT_POLICY_RULES) |
