commit 59a96efbddfab60d9a3958946b2d0a0a4525fb61
Author: Damian Johnson <atagar(a)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])