commit 59a96efbddfab60d9a3958946b2d0a0a4525fb61 Author: Damian Johnson atagar@torproject.org Date: Sat Jul 1 10:50:36 2017 -0700
Randomize created router status entry fields --- stem/descriptor/router_status_entry.py | 33 +++++++++++------------ test/unit/descriptor/networkstatus/document_v3.py | 4 +-- test/unit/descriptor/router_status_entry.py | 32 ++++++++-------------- test/unit/tutorial.py | 12 ++++++--- test/unit/tutorial_examples.py | 9 ++++--- 5 files changed, 43 insertions(+), 47 deletions(-)
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py index c5f21bf..34e9a6a 100644 --- a/stem/descriptor/router_status_entry.py +++ b/stem/descriptor/router_status_entry.py @@ -35,21 +35,9 @@ from stem.descriptor import ( _descriptor_components, _parse_protocol_line, _read_until_keywords, -) - -ROUTER_STATUS_ENTRY_V2_HEADER = ( - ('r', 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'), -) - -ROUTER_STATUS_ENTRY_V3_HEADER = ( - ('r', 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'), - ('s', 'Fast Named Running Stable Valid'), -) - -ROUTER_STATUS_ENTRY_MICRO_V3_HEADER = ( - ('r', 'Konata ARIJF2zbqirB9IwsW0mQznccWww 2012-09-24 13:40:40 69.64.48.168 9001 9030'), - ('m', 'aiUklwBrua82obG5AsTX+iEpkjQA2+AQHxZ7GwMfY70'), - ('s', 'Fast Guard HSDir Named Running Stable V2Dir Valid'), + _random_nickname, + _random_ipv4_address, + _random_date, )
_parse_pr_line = _parse_protocol_line('pr', 'protocols') @@ -532,7 +520,9 @@ class RouterStatusEntryV2(RouterStatusEntry): if sign: raise NotImplementedError('Signing of %s not implemented' % cls.__name__)
- return _descriptor_content(attr, exclude, sign, ROUTER_STATUS_ENTRY_V2_HEADER) + return _descriptor_content(attr, exclude, sign, ( + ('r', '%s p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE %s %s 9001 0' % (_random_nickname(), _random_date(), _random_ipv4_address())), + ))
def _name(self, is_plural = False): return 'Router status entries (v2)' if is_plural else 'Router status entry (v2)' @@ -632,7 +622,10 @@ class RouterStatusEntryV3(RouterStatusEntry): if sign: raise NotImplementedError('Signing of %s not implemented' % cls.__name__)
- return _descriptor_content(attr, exclude, sign, ROUTER_STATUS_ENTRY_V3_HEADER) + return _descriptor_content(attr, exclude, sign, ( + ('r', '%s p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE %s %s 9001 0' % (_random_nickname(), _random_date(), _random_ipv4_address())), + ('s', 'Fast Named Running Stable Valid'), + ))
def _name(self, is_plural = False): return 'Router status entries (v3)' if is_plural else 'Router status entry (v3)' @@ -708,7 +701,11 @@ class RouterStatusEntryMicroV3(RouterStatusEntry): if sign: raise NotImplementedError('Signing of %s not implemented' % cls.__name__)
- return _descriptor_content(attr, exclude, sign, ROUTER_STATUS_ENTRY_MICRO_V3_HEADER) + return _descriptor_content(attr, exclude, sign, ( + ('r', '%s ARIJF2zbqirB9IwsW0mQznccWww %s %s 9001 9030' % (_random_nickname(), _random_date(), _random_ipv4_address())), + ('m', 'aiUklwBrua82obG5AsTX+iEpkjQA2+AQHxZ7GwMfY70'), + ('s', 'Fast Guard HSDir Named Running Stable V2Dir Valid'), + ))
def _name(self, is_plural = False): return 'Router status entries (micro v3)' if is_plural else 'Router status entry (micro v3)' diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py index 3de445b..832ba9c 100644 --- a/test/unit/descriptor/networkstatus/document_v3.py +++ b/test/unit/descriptor/networkstatus/document_v3.py @@ -397,13 +397,13 @@ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= consensus_file.close()
for router in consensus.routers.values(): - self.assertEqual('caerSidi', router.nickname) + self.assertTrue(router.nickname.startswith('Unnamed'))
# second example: using stem.descriptor.parse_file
with io.BytesIO(content) as consensus_file: for router in stem.descriptor.parse_file(consensus_file, 'network-status-consensus-3 1.0'): - self.assertEqual('caerSidi', router.nickname) + self.assertTrue(router.nickname.startswith('Unnamed'))
@test.require.cryptography def test_signature_validation(self): diff --git a/test/unit/descriptor/router_status_entry.py b/test/unit/descriptor/router_status_entry.py index 166b419..a4c14e0 100644 --- a/test/unit/descriptor/router_status_entry.py +++ b/test/unit/descriptor/router_status_entry.py @@ -20,7 +20,6 @@ from test.unit.descriptor import ( )
from stem.descriptor.router_status_entry import ( - ROUTER_STATUS_ENTRY_V3_HEADER, RouterStatusEntryV2, RouterStatusEntryV3, RouterStatusEntryMicroV3, @@ -53,8 +52,8 @@ m 18,19,20 sha256=AkZH3gIvz3wunsroqh5izBJizdYuR7kn2oVbsvqgML8 m 21 sha256=AVp41YVxKEJCaoEf0+77Cdvyw5YgpyDXdob0+LSv/pE """
-expect_invalid_attr = functools.partial(base_expect_invalid_attr, RouterStatusEntryV3, 'nickname', 'caerSidi') -expect_invalid_attr_for_text = functools.partial(base_expect_invalid_attr_for_text, RouterStatusEntryV3, 'nickname', 'caerSidi') +expect_invalid_attr = functools.partial(base_expect_invalid_attr, RouterStatusEntryV3, 'nickname', 'Unnamed') +expect_invalid_attr_for_text = functools.partial(base_expect_invalid_attr_for_text, RouterStatusEntryV3, 'nickname', 'Unnamed')
def vote_document(): @@ -98,11 +97,8 @@ class TestRouterStatusEntry(unittest.TestCase): entry = RouterStatusEntryV2.create()
self.assertEqual(None, entry.document) - self.assertEqual('caerSidi', entry.nickname) - self.assertEqual('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', entry.fingerprint) + self.assertTrue(entry.nickname.startswith('Unnamed')) self.assertEqual('A106452D87BD7B803B6CE916291ED368DC5BD091', entry.digest) - self.assertEqual(datetime.datetime(2012, 8, 6, 11, 19, 31), entry.published) - self.assertEqual('71.35.150.29', entry.address) self.assertEqual(9001, entry.or_port) self.assertEqual(None, entry.dir_port) self.assertEqual(None, entry.flags) @@ -119,11 +115,8 @@ class TestRouterStatusEntry(unittest.TestCase):
expected_flags = set([Flag.FAST, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.VALID]) self.assertEqual(None, entry.document) - self.assertEqual('caerSidi', entry.nickname) - self.assertEqual('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', entry.fingerprint) + self.assertTrue(entry.nickname.startswith('Unnamed')) self.assertEqual('A106452D87BD7B803B6CE916291ED368DC5BD091', entry.digest) - self.assertEqual(datetime.datetime(2012, 8, 6, 11, 19, 31), entry.published) - self.assertEqual('71.35.150.29', entry.address) self.assertEqual(9001, entry.or_port) self.assertEqual(None, entry.dir_port) self.assertEqual(expected_flags, set(entry.flags)) @@ -148,10 +141,7 @@ class TestRouterStatusEntry(unittest.TestCase):
expected_flags = set([Flag.FAST, Flag.GUARD, Flag.HSDIR, Flag.NAMED, Flag.RUNNING, Flag.STABLE, Flag.V2DIR, Flag.VALID]) self.assertEqual(None, entry.document) - self.assertEqual('Konata', entry.nickname) - self.assertEqual('011209176CDBAA2AC1F48C2C5B4990CE771C5B0C', entry.fingerprint) - self.assertEqual(datetime.datetime(2012, 9, 24, 13, 40, 40), entry.published) - self.assertEqual('69.64.48.168', entry.address) + self.assertTrue(entry.nickname.startswith('Unnamed')) self.assertEqual(9001, entry.or_port) self.assertEqual(9030, entry.dir_port) self.assertEqual(expected_flags, set(entry.flags)) @@ -279,7 +269,7 @@ class TestRouterStatusEntry(unittest.TestCase): self.assertRaises(ValueError, RouterStatusEntryV3, content, True)
entry = RouterStatusEntryV3(content, False) - self.assertEqual('caerSidi', entry.nickname) + self.assertTrue(entry.nickname.startswith('Unnamed'))
def test_missing_r_field(self): """ @@ -315,7 +305,7 @@ class TestRouterStatusEntry(unittest.TestCase): )
for value in test_values: - r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('caerSidi', value) + r_line = '%s p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0' % value
# TODO: Initial whitespace is consumed as part of the keyword/value # divider. This is a bug in the case of V3 router status entries, but @@ -344,7 +334,7 @@ class TestRouterStatusEntry(unittest.TestCase): )
for value in test_values: - r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('p1aag7VwarGxqctS7/fS0y5FU+s', value) + r_line = 'caerSidi %s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0' % value expect_invalid_attr(self, {'r': r_line}, 'fingerprint')
def test_malformed_published_date(self): @@ -369,7 +359,7 @@ class TestRouterStatusEntry(unittest.TestCase): )
for value in test_values: - r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('2012-08-06 11:19:31', value) + r_line = 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE %s 71.35.150.29 9001 0' % value expect_invalid_attr(self, {'r': r_line}, 'published')
def test_malformed_address(self): @@ -386,7 +376,7 @@ class TestRouterStatusEntry(unittest.TestCase): )
for value in test_values: - r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1].replace('71.35.150.29', value) + r_line = 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 %s 9001 0' % value expect_invalid_attr(self, {'r': r_line}, 'address')
def test_malformed_port(self): @@ -407,7 +397,7 @@ class TestRouterStatusEntry(unittest.TestCase): if not include_or_port and not include_dir_port: continue
- r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1] + r_line = 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'
if include_or_port: r_line = r_line.replace(' 9001 ', ' %s ' % value) diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py index b0f5b71..662f1db 100644 --- a/test/unit/tutorial.py +++ b/test/unit/tutorial.py @@ -128,7 +128,9 @@ class TestTutorial(unittest.TestCase): @patch('sys.stdout', new_callable = StringIO) @patch('stem.descriptor.remote.DescriptorDownloader') def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock): - downloader_mock().get_consensus().run.return_value = [RouterStatusEntryV2.create()] + downloader_mock().get_consensus().run.return_value = [RouterStatusEntryV2.create({ + 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', + })]
exec_documentation_example('current_descriptors.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue()) @@ -137,7 +139,9 @@ class TestTutorial(unittest.TestCase): @patch('stem.control.Controller.from_port', spec = Controller) def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock): controller = from_port_mock().__enter__() - controller.get_network_statuses.return_value = [RouterStatusEntryV2.create()] + controller.get_network_statuses.return_value = [RouterStatusEntryV2.create({ + 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', + })]
exec_documentation_example('descriptor_from_tor_control_socket.py') self.assertEqual('found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue()) @@ -151,7 +155,9 @@ class TestTutorial(unittest.TestCase): for desc in parse_file(open('/home/atagar/.tor/cached-consensus')): print('found relay %s (%s)' % (desc.nickname, desc.fingerprint))
- test_file = io.BytesIO(NetworkStatusDocumentV3.content(routers = [RouterStatusEntryV3.create()])) + test_file = io.BytesIO(NetworkStatusDocumentV3.content(routers = [RouterStatusEntryV3.create({ + 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', + })])) test_file.name = '/home/atagar/.tor/cached-consensus' open_mock.return_value = test_file
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py index 50e766d..b47de51 100644 --- a/test/unit/tutorial_examples.py +++ b/test/unit/tutorial_examples.py @@ -18,7 +18,7 @@ import stem.prereq from stem.control import Controller from stem.descriptor.networkstatus import NetworkStatusDocumentV3 from stem.descriptor.remote import DIRECTORY_AUTHORITIES -from stem.descriptor.router_status_entry import ROUTER_STATUS_ENTRY_V3_HEADER, RouterStatusEntryV3 +from stem.descriptor.router_status_entry import RouterStatusEntryV3 from stem.descriptor.server_descriptor import RelayDescriptor from stem.response import ControlMessage from stem.util import str_type @@ -109,7 +109,7 @@ def _get_circ_event(id, status, hop1, hop2, hop3, purpose):
def _get_router_status(address = None, port = None, nickname = None, fingerprint_base64 = None, s_line = None): - r_line = ROUTER_STATUS_ENTRY_V3_HEADER[0][1] + r_line = 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0'
if address: r_line = r_line.replace('71.35.150.29', address) @@ -330,7 +330,10 @@ class TestTutorialExamples(unittest.TestCase): for fingerprint, relay in consensus.routers.items(): print('%s: %s' % (fingerprint, relay.nickname))
- network_status = NetworkStatusDocumentV3.create(routers = (RouterStatusEntryV3.create(),)) + network_status = NetworkStatusDocumentV3.create(routers = (RouterStatusEntryV3.create({ + 'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0', + }),)) + query_mock().run.return_value = [network_status] parse_file_mock.return_value = itertools.cycle([network_status])
tor-commits@lists.torproject.org