def test_metrics_consensus(self): """ Checks if consensus documents from Metrics are parsed properly. """ consensus_path = get_resource("metrics_consensus") for specify_type in (True, False): with open(consensus_path, 'rb') as descriptor_file: if specify_type: descriptors = stem.descriptor.parse_file( descriptor_file, "network-status-consensus-3 1.0") else: descriptors = stem.descriptor.parse_file(descriptor_file) router = next(descriptors) self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("8mCr8Sl7RF4ENU4jb0FZFA/3do8", router.digest) self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published) self.assertEquals("178.218.213.229", router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port)
def test_metrics_bridge_descriptor(self): """ Parses and checks our results against an extrainfo bridge descriptor from metrics. """ descriptor_file = open(get_resource("extrainfo_bridge_descriptor"), 'rb') expected_dir_v2_responses = { DirResponse.OK: 0, DirResponse.UNAVAILABLE: 0, DirResponse.NOT_FOUND: 0, DirResponse.NOT_MODIFIED: 0, DirResponse.BUSY: 0, } expected_dir_v3_responses = { DirResponse.OK: 72, DirResponse.NOT_ENOUGH_SIGS: 0, DirResponse.UNAVAILABLE: 0, DirResponse.NOT_FOUND: 0, DirResponse.NOT_MODIFIED: 0, DirResponse.BUSY: 0, } desc = next(stem.descriptor.parse_file(descriptor_file, "bridge-extra-info 1.0")) self.assertEquals("ec2bridgereaac65a3", desc.nickname) self.assertEquals("1EC248422B57D9C0BD751892FE787585407479A4", desc.fingerprint) self.assertEquals(datetime.datetime(2012, 6, 8, 2, 21, 27), desc.published) self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.read_history_end) self.assertEquals(900, desc.read_history_interval) self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.write_history_end) self.assertEquals(900, desc.write_history_interval) self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.dir_read_history_end) self.assertEquals(900, desc.dir_read_history_interval) self.assertEquals(datetime.datetime(2012, 6, 8, 2, 10, 38), desc.dir_write_history_end) self.assertEquals(900, desc.dir_write_history_interval) self.assertEquals("00A2AECCEAD3FEE033CFE29893387143146728EC", desc.digest()) self.assertEquals([], desc.get_unrecognized_lines()) read_values_start = [337920, 437248, 3995648, 48726016] self.assertEquals(read_values_start, desc.read_history_values[:4]) write_values_start = [343040, 991232, 5649408, 49548288] self.assertEquals(write_values_start, desc.write_history_values[:4]) dir_read_values_start = [0, 71680, 99328, 25600] self.assertEquals(dir_read_values_start, desc.dir_read_history_values[:4]) dir_write_values_start = [5120, 664576, 2419712, 578560] self.assertEquals(dir_write_values_start, desc.dir_write_history_values[:4]) self.assertEquals({}, desc.dir_v2_requests) self.assertEquals({}, desc.dir_v3_requests) self.assertEquals(expected_dir_v2_responses, desc.dir_v2_responses) self.assertEquals(expected_dir_v3_responses, desc.dir_v3_responses) self.assertEquals({}, desc.dir_v2_responses_unknown) self.assertEquals({}, desc.dir_v2_responses_unknown)
def test_metrics_relay_descriptor(self): """ Parses and checks our results against an extrainfo descriptor from metrics. """ descriptor_file = open(get_resource("extrainfo_relay_descriptor"), 'rb') expected_signature = """-----BEGIN SIGNATURE----- K5FSywk7qvw/boA4DQcqkls6Ize5vcBYfhQ8JnOeRQC9+uDxbnpm3qaYN9jZ8myj k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw 7LZqklu+gVvhMKREpchVqlAwXkWR44VENm24Hs+mT3M= -----END SIGNATURE-----""" desc = next( stem.descriptor.parse_file(descriptor_file, "extra-info 1.0")) self.assertEquals("NINJA", desc.nickname) self.assertEquals("B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48", desc.fingerprint) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 3, 50), desc.published) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.read_history_end) self.assertEquals(900, desc.read_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.write_history_end) self.assertEquals(900, desc.write_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_read_history_end) self.assertEquals(900, desc.dir_read_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_write_history_end) self.assertEquals(900, desc.dir_write_history_interval) self.assertEquals(expected_signature, desc.signature) self.assertEquals("00A57A9AAB5EA113898E2DD02A755E31AFC27227", desc.digest()) self.assertEquals([], desc.get_unrecognized_lines()) # The read-history, write-history, dirreq-read-history, and # dirreq-write-history lines are pretty long so just checking # the initial contents for the line and parsed values. read_values_start = [3309568, 9216, 41984, 27648, 123904] self.assertEquals(read_values_start, desc.read_history_values[:5]) write_values_start = [1082368, 19456, 50176, 272384, 485376] self.assertEquals(write_values_start, desc.write_history_values[:5]) dir_read_values_start = [0, 0, 0, 0, 33792, 27648, 48128] self.assertEquals(dir_read_values_start, desc.dir_read_history_values[:7]) dir_write_values_start = [0, 0, 0, 227328, 349184, 382976, 738304] self.assertEquals(dir_write_values_start, desc.dir_write_history_values[:7])
def test_non_ascii_descriptor(self): """ Parses a descriptor with non-ascii content. """ test.mocking.mock_method( stem.descriptor.server_descriptor.RelayDescriptor, '_validate_content', test.mocking.no_op()) descriptor_file = open(get_resource("non-ascii_descriptor"), 'rb') expected_contact = b"2048R/F171EC1F Johan Bl\xc3\xa5b\xc3\xa4ck \xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf" desc = next( stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("torrelay389752132", desc.nickname) self.assertEquals("5D47E91A1F7421A4E3255F4D04E534E9A21407BB", desc.fingerprint) self.assertEquals("130.243.230.116", desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals( b"Tor 0.2.2.35 (git-4f42b0a93422f70e) on Linux x86_64", desc.platform) self.assertEquals(stem.version.Version("0.2.2.35"), desc.tor_version) self.assertEquals("Linux x86_64", desc.operating_system) self.assertEquals(3103848, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 21, 16, 28, 14), desc.published) self.assertEquals(expected_contact, desc.contact) self.assertEquals(["1", "2"], desc.link_protocols) self.assertEquals(["1"], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals("51E9FD0DA7C235D8C0250BAFB6E1ABB5F1EF9F04", desc.extra_info_digest) self.assertEquals(["2"], desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(81920, desc.average_bandwidth) self.assertEquals(102400, desc.burst_bandwidth) self.assertEquals(84275, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy) self.assertEquals([], desc.get_unrecognized_lines()) # Make sure that we can get a string representation for this descriptor # (having non-unicode content risks a UnicodeEncodeError)... # # https://trac.torproject.org/8265 self.assertTrue(isinstance(str(desc), str))
def test_old_descriptor(self): """ Parses a relay server descriptor from 2005. """ descriptor_file = open(get_resource('old_descriptor'), 'rb') desc = next( stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0')) self.assertEquals('krypton', desc.nickname) self.assertEquals('3E2F63E2356F52318B536A12B6445373808A5D6C', desc.fingerprint) self.assertEquals('212.37.39.59', desc.address) self.assertEquals(8000, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b'Tor 0.1.0.14 on FreeBSD i386', desc.platform) self.assertEquals(stem.version.Version('0.1.0.14'), desc.tor_version) self.assertEquals('FreeBSD i386', desc.operating_system) self.assertEquals(64820, desc.uptime) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 1, 3), desc.published) self.assertEquals(None, desc.contact) self.assertEquals(None, desc.link_protocols) self.assertEquals(None, desc.circuit_protocols) self.assertEquals(True, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals(None, desc.extra_info_digest) self.assertEquals(None, desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(102400, desc.average_bandwidth) self.assertEquals(10485760, desc.burst_bandwidth) self.assertEquals(0, desc.observed_bandwidth) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 0, 48), desc.read_history_end) self.assertEquals(900, desc.read_history_interval) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 0, 48), desc.write_history_end) self.assertEquals(900, desc.write_history_interval) self.assertEquals([], desc.get_unrecognized_lines()) # The read-history and write-history lines are pretty long so just checking # the initial contents for the line and parsed values. read_values_start = [20774, 489973, 510022, 511163, 20949] self.assertEquals(read_values_start, desc.read_history_values[:5]) write_values_start = [ 81, 8848, 8927, 8927, 83, 8848, 8931, 8929, 81, 8846 ] self.assertEquals(write_values_start, desc.write_history_values[:10])
def test_metrics_cert(self): """ Checks if consensus documents from Metrics are parsed properly. """ expected_identity_key = """-----BEGIN RSA PUBLIC KEY----- MIIBigKCAYEA7cZXvDRxfjDYtr9/9UsQ852+6cmHMr8VVh8GkLwbq3RzqjkULwQ2 R9mFvG4FnqMcMKXi62rYYA3fZL1afhT804cpvyp/D3dPM8QxW88fafFAgIFP4LiD 0JYjnF8cva5qZ0nzlWnMXLb32IXSvsGSE2FRyAV0YN9a6k967LSgCfUnZ+IKMezW 1vhL9YK4QIfsDowgtVsavg63GzGmA7JvZmn77+/J5wKz11vGr7Wttf8XABbH2taX O9j/KGBOX2OKhoF3mXfZSmUO2dV9NMwtkJ7zD///Ny6sfApWV6kVP4O9TdG3bAsl +fHCoCKgF/jAAWzh6VckQTOPzQZaH5aMWfXrDlzFWg17MjonI+bBTD2Ex2pHczzJ bN7coDMRH2SuOXv8wFf27KdUxZ/GcrXSRGzlRLygxqlripUanjVGN2JvrVQVr0kz pjNjiZl2z8ZyZ5d4zQuBi074JPGgx62xAstP37v1mPw14sIWfLgY16ewYuS5bCxV lyS28jsPht9VAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signing_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAOeE3Qr1Km97gTgiB3io0EU0fqHW2ESMXVHeQuNDtCWBa0XSCEG6gx4B ZkkHjfVWqGQ7TmmzjYP9L9uCgtoKfhSvJA2w9NUMtMl8sgZmF4lcGpXXvGY9a566 Bn+3wP0lMhb/I8CPVPX+NWEjgl1noZxo1C59SO/iALGQOpxRYgmbAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_key_cert = """-----BEGIN SIGNATURE----- asvWwaMq34OfHoWUhAwh4+JDOuEUZJVIHQnedOYfQH8asS2QvW3Ma93OhrwVOC6b FyKmTJmJsl0MJGiC7tcEOlL6knsKE4CsuIw/PEcu2Rnm+R9zWxQuMYiHvGQMoDxl giOhLLs4LlzAAJlbfbd3hjF4STVAtTwmxYuIjb1Mq/JfAsx/wH3TLXgVZwj32w9s zUd9KZwwLzFiiHpC+U7zh6+wRsZfo2tlpmcaP1dTSINgVbdzPJ/DOUlx9nwTCBsE AQpUx2DpAikwrpw0zDqpQvYulcQlNLWFN/y/PkmiK8mIJk0OBMiQA7JgqWamnnk4 PwqaGv483LkBF+25JFGJmnUVve3RMc+s61+2kBcjfUMed4QaHkeCMHqlRqpfQVkk RY22NXCwrJvSMEwiy7acC8FGysqwHRyE356+Rw6TB43g3Tno9KaHEK7MHXjSHwNs GM9hAsAMRX9Ogqhq5UjDNqEsvDKuyVeyh7unSZEOip9Zr6K/+7VsVPNb8vfBRBjo -----END SIGNATURE-----""" cert_path = get_resource("metrics_cert") with open(cert_path) as cert_file: cert = next(stem.descriptor.parse_file(cert_file)) self.assertEquals(3, cert.version) self.assertEquals(None, cert.address) self.assertEquals(None, cert.dir_port) self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", cert.fingerprint) self.assertEquals(expected_identity_key, cert.identity_key) self.assertEquals(datetime.datetime(2008, 5, 9, 21, 13, 26), cert.published) self.assertEquals(datetime.datetime(2009, 5, 9, 21, 13, 26), cert.expires) self.assertEquals(expected_signing_key, cert.signing_key) self.assertEquals(None, cert.crosscert) self.assertEquals(expected_key_cert, cert.certification) self.assertEquals([], cert.get_unrecognized_lines())
def test_local_microdescriptors(self): """ Checks a small microdescriptor file with known contents. """ descriptor_path = get_resource('cached-microdescs') with open(descriptor_path, 'rb') as descriptor_file: descriptors = stem.descriptor.parse_file(descriptor_file, 'microdescriptor 1.0') router = next(descriptors) self.assertEquals(FIRST_ONION_KEY, router.onion_key) self.assertEquals(None, router.ntor_onion_key) self.assertEquals([], router.or_addresses) self.assertEquals([], router.family) self.assertEquals( stem.exit_policy.MicroExitPolicy('reject 1-65535'), router.exit_policy) self.assertEquals({b'@last-listed': b'2013-02-24 00:18:36'}, router.get_annotations()) self.assertEquals([b'@last-listed 2013-02-24 00:18:36'], router.get_annotation_lines()) router = next(descriptors) self.assertEquals(SECOND_ONION_KEY, router.onion_key) self.assertEquals(u'r5572HzD+PMPBbXlZwBhsm6YEbxnYgis8vhZ1jmdI2k=', router.ntor_onion_key) self.assertEquals([], router.or_addresses) self.assertEquals(['$6141629FA0D15A6AEAEF3A1BEB76E64C767B3174'], router.family) self.assertEquals( stem.exit_policy.MicroExitPolicy('reject 1-65535'), router.exit_policy) self.assertEquals({b'@last-listed': b'2013-02-24 00:18:37'}, router.get_annotations()) self.assertEquals([b'@last-listed 2013-02-24 00:18:37'], router.get_annotation_lines()) router = next(descriptors) self.assertEquals(THIRD_ONION_KEY, router.onion_key) self.assertEquals(None, router.ntor_onion_key) self.assertEquals([(u'2001:6b0:7:125::242', 9001, True)], router.or_addresses) self.assertEquals([], router.family) self.assertEquals( stem.exit_policy.MicroExitPolicy('accept 80,443'), router.exit_policy) self.assertEquals({b'@last-listed': b'2013-02-24 00:18:36'}, router.get_annotations()) self.assertEquals([b'@last-listed 2013-02-24 00:18:36'], router.get_annotation_lines())
def test_bridge_descriptor(self): """ Parses a bridge descriptor. """ descriptor_file = open(get_resource('bridge_descriptor'), 'rb') expected_family = set([ '$CE396C72A3D0880F74C064FEA79D68C15BD380B9', '$AB8B00C00B1347BA80A88E548FAC9EDF701D7D0E', '$8C8A470D7C23151665A7B84E75E89FCC205A3304', ]) desc = next( stem.descriptor.parse_file(descriptor_file, 'bridge-server-descriptor 1.0')) self.assertEquals('Unnamed', desc.nickname) self.assertEquals('AE54E28ED069CDF45F3009F963EE3B3D6FA26A2E', desc.fingerprint) self.assertEquals('10.45.227.253', desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals( b'Tor 0.2.3.12-alpha (git-800942b4176ca31c) on Linux x86_64', desc.platform) self.assertEquals(stem.version.Version('0.2.3.12-alpha'), desc.tor_version) self.assertEquals('Linux x86_64', desc.operating_system) self.assertEquals(186, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 22, 17, 34, 38), desc.published) self.assertEquals(b'somebody', desc.contact) self.assertEquals(['1', '2'], desc.link_protocols) self.assertEquals(['1'], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals('134F81F7A0D270B85FCD481DD10CEA34BA7B15C9', desc.extra_info_digest) self.assertEquals(['2'], desc.hidden_service_dir) self.assertEquals(expected_family, desc.family) self.assertEquals(409600, desc.average_bandwidth) self.assertEquals(819200, desc.burst_bandwidth) self.assertEquals(5120, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy) self.assertEquals('006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4', desc.digest()) self.assertEquals([], desc.get_unrecognized_lines())
def test_metrics_descriptor_multiple(self): """ Parses and checks our results against a server descriptor from metrics. """ with open(get_resource("metrics_server_desc_multiple"), 'rb') as descriptor_file: descriptors = list(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals(2, len(descriptors)) self.assertEquals("anonion", descriptors[0].nickname) self.assertEquals("9A5EC5BB866517E53962AF4D3E776536694B069E", descriptors[0].fingerprint) self.assertEquals("Unnamed", descriptors[1].nickname) self.assertEquals("5366F1D198759F8894EA6E5FF768C667F59AFD24", descriptors[1].fingerprint)
def test_non_ascii_descriptor(self): """ Parses a descriptor with non-ascii content. """ descriptor_file = open(get_resource('non-ascii_descriptor'), 'rb') expected_contact = b'1024D/04D2E818 L\xc3\xa9na\xc3\xafc Huard <lenaic dot huard AT laposte dot net>' desc = next( stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0')) self.assertEquals('Coruscant', desc.nickname) self.assertEquals('0B9821545C48E496AEED9ECC0DB506C49FF8158D', desc.fingerprint) self.assertEquals('88.182.161.122', desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(9030, desc.dir_port) self.assertEquals(b'Tor 0.2.3.25 on Linux', desc.platform) self.assertEquals(stem.version.Version('0.2.3.25'), desc.tor_version) self.assertEquals('Linux', desc.operating_system) self.assertEquals(259738, desc.uptime) self.assertEquals(datetime.datetime(2013, 5, 18, 11, 16, 19), desc.published) self.assertEquals(expected_contact, desc.contact) self.assertEquals(['1', '2'], desc.link_protocols) self.assertEquals(['1'], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals('56403D838DE152421CD401B8E57DAD4483A3D56B', desc.extra_info_digest) self.assertEquals(['2'], desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(102400, desc.average_bandwidth) self.assertEquals(204800, desc.burst_bandwidth) self.assertEquals(122818, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy) self.assertEquals([], desc.get_unrecognized_lines()) # Make sure that we can get a string representation for this descriptor # (having non-unicode content risks a UnicodeEncodeError)... # # https://trac.torproject.org/8265 self.assertTrue(isinstance(str(desc), str))
def test_metrics_bridge_consensus(self): """ Checks if the bridge documents from Metrics are parsed properly. """ consensus_path = get_resource("bridge_network_status") with open(consensus_path, 'rb') as descriptor_file: router = next(stem.descriptor.parse_file(descriptor_file)) self.assertEquals("Unnamed", router.nickname) self.assertEquals("0014A2055278DB3EB0E59EA701741416AF185558", router.fingerprint) self.assertEquals("148EF8685B8D259650AE0967D1FF8E6A870C7743", router.digest) self.assertEquals(datetime.datetime(2012, 5, 31, 15, 57, 0), router.published) self.assertEquals("10.97.236.247", router.address) self.assertEquals(443, router.or_port) self.assertEquals(None, router.dir_port)
def test_old_descriptor(self): """ Parses a relay server descriptor from 2005. """ descriptor_file = open(get_resource("old_descriptor"), 'rb') desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("krypton", desc.nickname) self.assertEquals("3E2F63E2356F52318B536A12B6445373808A5D6C", desc.fingerprint) self.assertEquals("212.37.39.59", desc.address) self.assertEquals(8000, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b"Tor 0.1.0.14 on FreeBSD i386", desc.platform) self.assertEquals(stem.version.Version("0.1.0.14"), desc.tor_version) self.assertEquals("FreeBSD i386", desc.operating_system) self.assertEquals(64820, desc.uptime) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 1, 3), desc.published) self.assertEquals(None, desc.contact) self.assertEquals(None, desc.link_protocols) self.assertEquals(None, desc.circuit_protocols) self.assertEquals(True, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals(None, desc.extra_info_digest) self.assertEquals(None, desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(102400, desc.average_bandwidth) self.assertEquals(10485760, desc.burst_bandwidth) self.assertEquals(0, desc.observed_bandwidth) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 0, 48), desc.read_history_end) self.assertEquals(900, desc.read_history_interval) self.assertEquals(datetime.datetime(2005, 12, 16, 18, 0, 48), desc.write_history_end) self.assertEquals(900, desc.write_history_interval) self.assertEquals([], desc.get_unrecognized_lines()) # The read-history and write-history lines are pretty long so just checking # the initial contents for the line and parsed values. read_values_start = [20774, 489973, 510022, 511163, 20949] self.assertEquals(read_values_start, desc.read_history_values[:5]) write_values_start = [81, 8848, 8927, 8927, 83, 8848, 8931, 8929, 81, 8846] self.assertEquals(write_values_start, desc.write_history_values[:10])
def test_metrics_vote(self): """ Checks if vote documents from Metrics are parsed properly. """ vote_path = get_resource("metrics_vote") with open(vote_path, 'rb') as descriptor_file: descriptors = stem.descriptor.parse_file(descriptor_file) router = next(descriptors) self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("0799F806200B005F01E40A9A7F1A21C988AE8FB1", router.digest) self.assertEquals(datetime.datetime(2012, 7, 11, 4, 22, 53), router.published) self.assertEquals("178.218.213.229", router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port)
def test_negative_uptime(self): """ Parses a descriptor where we are tolerant of a negative uptime, and another where we shouldn't be. """ descriptor_file = open(get_resource("negative_uptime"), 'rb') desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("TipTor", desc.nickname) self.assertEquals("137962D4931DBF08A24E843288B8A155D6D2AEDD", desc.fingerprint) self.assertEquals("62.99.247.83", desc.address) # modify the relay version so it's after when the negative uptime bug # should appear descriptor_contents = str(desc).replace("Tor 0.1.1.25", "Tor 0.1.2.7") self.assertRaises(ValueError, stem.descriptor.server_descriptor.RelayDescriptor, descriptor_contents)
def test_metrics_relay_descriptor(self): """ Parses and checks our results against an extrainfo descriptor from metrics. """ descriptor_file = open(get_resource("extrainfo_relay_descriptor"), 'rb') expected_signature = """-----BEGIN SIGNATURE----- K5FSywk7qvw/boA4DQcqkls6Ize5vcBYfhQ8JnOeRQC9+uDxbnpm3qaYN9jZ8myj k0d2aofcVbHr4fPQOSST0LXDrhFl5Fqo5um296zpJGvRUeO6S44U/EfJAGShtqWw 7LZqklu+gVvhMKREpchVqlAwXkWR44VENm24Hs+mT3M= -----END SIGNATURE-----""" desc = next(stem.descriptor.parse_file(descriptor_file, "extra-info 1.0")) self.assertEquals("NINJA", desc.nickname) self.assertEquals("B2289C3EAB83ECD6EB916A2F481A02E6B76A0A48", desc.fingerprint) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 3, 50), desc.published) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.read_history_end) self.assertEquals(900, desc.read_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.write_history_end) self.assertEquals(900, desc.write_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_read_history_end) self.assertEquals(900, desc.dir_read_history_interval) self.assertEquals(datetime.datetime(2012, 5, 5, 17, 2, 45), desc.dir_write_history_end) self.assertEquals(900, desc.dir_write_history_interval) self.assertEquals(expected_signature, desc.signature) self.assertEquals("00A57A9AAB5EA113898E2DD02A755E31AFC27227", desc.digest()) self.assertEquals([], desc.get_unrecognized_lines()) # The read-history, write-history, dirreq-read-history, and # dirreq-write-history lines are pretty long so just checking # the initial contents for the line and parsed values. read_values_start = [3309568, 9216, 41984, 27648, 123904] self.assertEquals(read_values_start, desc.read_history_values[:5]) write_values_start = [1082368, 19456, 50176, 272384, 485376] self.assertEquals(write_values_start, desc.write_history_values[:5]) dir_read_values_start = [0, 0, 0, 0, 33792, 27648, 48128] self.assertEquals(dir_read_values_start, desc.dir_read_history_values[:7]) dir_write_values_start = [0, 0, 0, 227328, 349184, 382976, 738304] self.assertEquals(dir_write_values_start, desc.dir_write_history_values[:7])
def test_non_ascii_descriptor(self): """ Parses a descriptor with non-ascii content. """ test.mocking.mock_method(stem.descriptor.server_descriptor.RelayDescriptor, '_validate_content', test.mocking.no_op()) descriptor_file = open(get_resource("non-ascii_descriptor"), 'rb') expected_contact = b"2048R/F171EC1F Johan Bl\xc3\xa5b\xc3\xa4ck \xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf" desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("torrelay389752132", desc.nickname) self.assertEquals("5D47E91A1F7421A4E3255F4D04E534E9A21407BB", desc.fingerprint) self.assertEquals("130.243.230.116", desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b"Tor 0.2.2.35 (git-4f42b0a93422f70e) on Linux x86_64", desc.platform) self.assertEquals(stem.version.Version("0.2.2.35"), desc.tor_version) self.assertEquals("Linux x86_64", desc.operating_system) self.assertEquals(3103848, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 21, 16, 28, 14), desc.published) self.assertEquals(expected_contact, desc.contact) self.assertEquals(["1", "2"], desc.link_protocols) self.assertEquals(["1"], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals("51E9FD0DA7C235D8C0250BAFB6E1ABB5F1EF9F04", desc.extra_info_digest) self.assertEquals(["2"], desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(81920, desc.average_bandwidth) self.assertEquals(102400, desc.burst_bandwidth) self.assertEquals(84275, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy) self.assertEquals([], desc.get_unrecognized_lines()) # Make sure that we can get a string representation for this descriptor # (having non-unicode content risks a UnicodeEncodeError)... # # https://trac.torproject.org/8265 self.assertTrue(isinstance(str(desc), str))
def test_non_ascii_descriptor(self): """ Parses a descriptor with non-ascii content. """ descriptor_file = open(get_resource("non-ascii_descriptor"), 'rb') expected_contact = b"1024D/04D2E818 L\xc3\xa9na\xc3\xafc Huard <lenaic dot huard AT laposte dot net>" desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("Coruscant", desc.nickname) self.assertEquals("0B9821545C48E496AEED9ECC0DB506C49FF8158D", desc.fingerprint) self.assertEquals("88.182.161.122", desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(9030, desc.dir_port) self.assertEquals(b"Tor 0.2.3.25 on Linux", desc.platform) self.assertEquals(stem.version.Version("0.2.3.25"), desc.tor_version) self.assertEquals("Linux", desc.operating_system) self.assertEquals(259738, desc.uptime) self.assertEquals(datetime.datetime(2013, 5, 18, 11, 16, 19), desc.published) self.assertEquals(expected_contact, desc.contact) self.assertEquals(["1", "2"], desc.link_protocols) self.assertEquals(["1"], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals("56403D838DE152421CD401B8E57DAD4483A3D56B", desc.extra_info_digest) self.assertEquals(["2"], desc.hidden_service_dir) self.assertEquals(set(), desc.family) self.assertEquals(102400, desc.average_bandwidth) self.assertEquals(204800, desc.burst_bandwidth) self.assertEquals(122818, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy) self.assertEquals([], desc.get_unrecognized_lines()) # Make sure that we can get a string representation for this descriptor # (having non-unicode content risks a UnicodeEncodeError)... # # https://trac.torproject.org/8265 self.assertTrue(isinstance(str(desc), str))
def test_cr_in_contact_line(self): """ Parses a descriptor with a huge contact line containing anomalous carriage returns ('\r' entries). """ descriptor_file = open(get_resource("cr_in_contact_line"), 'rb') desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("pogonip", desc.nickname) self.assertEquals("6DABD62BC65D4E6FE620293157FC76968DAB9C9B", desc.fingerprint) self.assertEquals("75.5.248.48", desc.address) # the contact info block is huge so just checking the start and end, # including some of the embedded carriage returns contact_start = "jie1 at pacbell dot net -----BEGIN PGP PUBLIC KEY BLOCK-----\rVersion:" contact_end = "YFRk3NhCY=\r=Xaw3\r-----END PGP PUBLIC KEY BLOCK-----" self.assertTrue(desc.contact.startswith(contact_start)) self.assertTrue(desc.contact.endswith(contact_end))
def test_cr_in_contact_line(self): """ Parses a descriptor with a huge contact line containing anomalous carriage returns ('\r' entries). """ descriptor_file = open(get_resource("cr_in_contact_line"), 'rb') desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("pogonip", desc.nickname) self.assertEquals("6DABD62BC65D4E6FE620293157FC76968DAB9C9B", desc.fingerprint) self.assertEquals("75.5.248.48", desc.address) # the contact info block is huge so just checking the start and end, # including some of the embedded carriage returns contact_start = b"jie1 at pacbell dot net -----BEGIN PGP PUBLIC KEY BLOCK-----\rVersion:" contact_end = b"YFRk3NhCY=\r=Xaw3\r-----END PGP PUBLIC KEY BLOCK-----" self.assertTrue(desc.contact.startswith(contact_start)) self.assertTrue(desc.contact.endswith(contact_end))
def test_bridge_descriptor(self): """ Parses a bridge descriptor. """ descriptor_file = open(get_resource("bridge_descriptor"), 'rb') expected_family = set([ "$CE396C72A3D0880F74C064FEA79D68C15BD380B9", "$AB8B00C00B1347BA80A88E548FAC9EDF701D7D0E", "$8C8A470D7C23151665A7B84E75E89FCC205A3304", ]) desc = next(stem.descriptor.parse_file(descriptor_file, "bridge-server-descriptor 1.0")) self.assertEquals("Unnamed", desc.nickname) self.assertEquals("AE54E28ED069CDF45F3009F963EE3B3D6FA26A2E", desc.fingerprint) self.assertEquals("10.45.227.253", desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b"Tor 0.2.3.12-alpha (git-800942b4176ca31c) on Linux x86_64", desc.platform) self.assertEquals(stem.version.Version("0.2.3.12-alpha"), desc.tor_version) self.assertEquals("Linux x86_64", desc.operating_system) self.assertEquals(186, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 22, 17, 34, 38), desc.published) self.assertEquals(b"somebody", desc.contact) self.assertEquals(["1", "2"], desc.link_protocols) self.assertEquals(["1"], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals("134F81F7A0D270B85FCD481DD10CEA34BA7B15C9", desc.extra_info_digest) self.assertEquals(["2"], desc.hidden_service_dir) self.assertEquals(expected_family, desc.family) self.assertEquals(409600, desc.average_bandwidth) self.assertEquals(819200, desc.burst_bandwidth) self.assertEquals(5120, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy) self.assertEquals("006FD96BA35E7785A6A3B8B75FE2E2435A13BDB4", desc.digest()) self.assertEquals([], desc.get_unrecognized_lines())
def test_metrics_consensus(self): """ Checks if consensus documents from Metrics are parsed properly. """ consensus_path = get_resource('metrics_consensus') for specify_type in (True, False): with open(consensus_path, 'rb') as descriptor_file: if specify_type: descriptors = stem.descriptor.parse_file(descriptor_file, 'network-status-consensus-3 1.0') else: descriptors = stem.descriptor.parse_file(descriptor_file) router = next(descriptors) self.assertEquals('sumkledi', router.nickname) self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint) self.assertEquals('F260ABF1297B445E04354E236F4159140FF7768F', router.digest) self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published) self.assertEquals('178.218.213.229', router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port)
def test_metrics_consensus(self): """ Checks if consensus documents from Metrics are parsed properly. """ consensus_path = get_resource("metrics_consensus") for specify_type in (True, False): with open(consensus_path, 'rb') as descriptor_file: if specify_type: descriptors = stem.descriptor.parse_file(descriptor_file, "network-status-consensus-3 1.0") else: descriptors = stem.descriptor.parse_file(descriptor_file) router = next(descriptors) self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("F260ABF1297B445E04354E236F4159140FF7768F", router.digest) self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published) self.assertEquals("178.218.213.229", router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port)
def test_local_microdescriptors(self): """ Checks a small microdescriptor file with known contents. """ descriptor_path = get_resource("cached-microdescs") with open(descriptor_path, 'rb') as descriptor_file: descriptors = stem.descriptor.parse_file(descriptor_file, "microdescriptor 1.0") router = next(descriptors) self.assertEquals(FIRST_ONION_KEY, router.onion_key) self.assertEquals(None, router.ntor_onion_key) self.assertEquals([], router.or_addresses) self.assertEquals([], router.family) self.assertEquals(stem.exit_policy.MicroExitPolicy("reject 1-65535"), router.exit_policy) self.assertEquals({b"@last-listed": b"2013-02-24 00:18:36"}, router.get_annotations()) self.assertEquals([b"@last-listed 2013-02-24 00:18:36"], router.get_annotation_lines()) router = next(descriptors) self.assertEquals(SECOND_ONION_KEY, router.onion_key) self.assertEquals(u'r5572HzD+PMPBbXlZwBhsm6YEbxnYgis8vhZ1jmdI2k=', router.ntor_onion_key) self.assertEquals([], router.or_addresses) self.assertEquals(["$6141629FA0D15A6AEAEF3A1BEB76E64C767B3174"], router.family) self.assertEquals(stem.exit_policy.MicroExitPolicy("reject 1-65535"), router.exit_policy) self.assertEquals({b"@last-listed": b"2013-02-24 00:18:37"}, router.get_annotations()) self.assertEquals([b"@last-listed 2013-02-24 00:18:37"], router.get_annotation_lines()) router = next(descriptors) self.assertEquals(THIRD_ONION_KEY, router.onion_key) self.assertEquals(None, router.ntor_onion_key) self.assertEquals([(u"2001:6b0:7:125::242", 9001, True)], router.or_addresses) self.assertEquals([], router.family) self.assertEquals(stem.exit_policy.MicroExitPolicy("accept 80,443"), router.exit_policy) self.assertEquals({b"@last-listed": b"2013-02-24 00:18:36"}, router.get_annotations()) self.assertEquals([b"@last-listed 2013-02-24 00:18:36"], router.get_annotation_lines())
def test_metrics_descriptor(self): """ Parses and checks our results against a server descriptor from metrics. """ descriptor_file = open(get_resource("example_descriptor"), 'rb') expected_family = set([ "$0CE3CFB1E9CC47B63EA8869813BF6FAB7D4540C1", "$1FD187E8F69A9B74C9202DC16A25B9E7744AB9F6", "$74FB5EFA6A46DE4060431D515DC9A790E6AD9A7C", "$77001D8DA9BF445B0F81AA427A675F570D222E6A", "$B6D83EC2D9E18B0A7A33428F8CFA9C536769E209", "$D2F37F46182C23AB747787FD657E680B34EAF892", "$E0BD57A11F00041A9789577C53A1B784473669E4", "$E5E3E9A472EAF7BE9682B86E92305DB4C71048EF", ]) expected_onion_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAJv5IIWQ+WDWYUdyA/0L8qbIkEVH/cwryZWoIaPAzINfrw1WfNZGtBmg skFtXhOHHqTRN4GPPrZsAIUOQGzQtGb66IQgT4tO/pj+P6QmSCCdTfhvGfgTCsC+ WPi4Fl2qryzTb3QO5r5x7T8OsG2IBUET1bLQzmtbC560SYR49IvVAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signing_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAKwvOXyztVKnuYvpTKt+nS3XIKeO8dVungi8qGoeS+6gkR6lDtGfBTjd uE9UIkdAl9zi8/1Ic2wsUNHE9jiS0VgeupITGZY8YOyMJJ/xtV1cqgiWhq1dUYaq 51TOtUogtAPgXPh4J+V8HbFFIcCzIh3qCO/xXo+DSHhv7SSif1VpAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signature = """-----BEGIN SIGNATURE----- dskLSPz8beUW7bzwDjR6EVNGpyoZde83Ejvau+5F2c6cGnlu91fiZN3suE88iE6e 758b9ldq5eh5mapb8vuuV3uO+0Xsud7IEOqfxdkmk0GKnUX8ouru7DSIUzUL0zqq Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= -----END SIGNATURE-----""" desc = next(stem.descriptor.parse_file(descriptor_file, "server-descriptor 1.0")) self.assertEquals("caerSidi", desc.nickname) self.assertEquals("A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB", desc.fingerprint) self.assertEquals("71.35.133.197", desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b"Tor 0.2.1.30 on Linux x86_64", desc.platform) self.assertEquals(stem.version.Version("0.2.1.30"), desc.tor_version) self.assertEquals("Linux x86_64", desc.operating_system) self.assertEquals(588217, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 1, 17, 15, 27), desc.published) self.assertEquals(b"www.atagar.com/contact", desc.contact) self.assertEquals(["1", "2"], desc.link_protocols) self.assertEquals(["1"], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals("D225B728768D7EA4B5587C13A7A9D22EBBEE6E66", desc.extra_info_digest) self.assertEquals(["2"], desc.hidden_service_dir) self.assertEquals(expected_family, desc.family) self.assertEquals(153600, desc.average_bandwidth) self.assertEquals(256000, desc.burst_bandwidth) self.assertEquals(104590, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy("reject *:*"), desc.exit_policy) self.assertEquals(expected_onion_key, desc.onion_key) self.assertEquals(expected_signing_key, desc.signing_key) self.assertEquals(expected_signature, desc.signature) self.assertEquals([], desc.get_unrecognized_lines()) self.assertEquals("2C7B27BEAB04B4E2459D89CA6D5CD1CC5F95A689", desc.digest())
def test_metrics_descriptor(self): """ Parses and checks our results against a server descriptor from metrics. """ descriptor_file = open(get_resource('example_descriptor'), 'rb') expected_family = set([ '$0CE3CFB1E9CC47B63EA8869813BF6FAB7D4540C1', '$1FD187E8F69A9B74C9202DC16A25B9E7744AB9F6', '$74FB5EFA6A46DE4060431D515DC9A790E6AD9A7C', '$77001D8DA9BF445B0F81AA427A675F570D222E6A', '$B6D83EC2D9E18B0A7A33428F8CFA9C536769E209', '$D2F37F46182C23AB747787FD657E680B34EAF892', '$E0BD57A11F00041A9789577C53A1B784473669E4', '$E5E3E9A472EAF7BE9682B86E92305DB4C71048EF', ]) expected_onion_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAJv5IIWQ+WDWYUdyA/0L8qbIkEVH/cwryZWoIaPAzINfrw1WfNZGtBmg skFtXhOHHqTRN4GPPrZsAIUOQGzQtGb66IQgT4tO/pj+P6QmSCCdTfhvGfgTCsC+ WPi4Fl2qryzTb3QO5r5x7T8OsG2IBUET1bLQzmtbC560SYR49IvVAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signing_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAKwvOXyztVKnuYvpTKt+nS3XIKeO8dVungi8qGoeS+6gkR6lDtGfBTjd uE9UIkdAl9zi8/1Ic2wsUNHE9jiS0VgeupITGZY8YOyMJJ/xtV1cqgiWhq1dUYaq 51TOtUogtAPgXPh4J+V8HbFFIcCzIh3qCO/xXo+DSHhv7SSif1VpAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signature = """-----BEGIN SIGNATURE----- dskLSPz8beUW7bzwDjR6EVNGpyoZde83Ejvau+5F2c6cGnlu91fiZN3suE88iE6e 758b9ldq5eh5mapb8vuuV3uO+0Xsud7IEOqfxdkmk0GKnUX8ouru7DSIUzUL0zqq Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= -----END SIGNATURE-----""" desc = next( stem.descriptor.parse_file(descriptor_file, 'server-descriptor 1.0')) self.assertEquals('caerSidi', desc.nickname) self.assertEquals('A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB', desc.fingerprint) self.assertEquals('71.35.133.197', desc.address) self.assertEquals(9001, desc.or_port) self.assertEquals(None, desc.socks_port) self.assertEquals(None, desc.dir_port) self.assertEquals(b'Tor 0.2.1.30 on Linux x86_64', desc.platform) self.assertEquals(stem.version.Version('0.2.1.30'), desc.tor_version) self.assertEquals('Linux x86_64', desc.operating_system) self.assertEquals(588217, desc.uptime) self.assertEquals(datetime.datetime(2012, 3, 1, 17, 15, 27), desc.published) self.assertEquals(b'www.atagar.com/contact', desc.contact) self.assertEquals(['1', '2'], desc.link_protocols) self.assertEquals(['1'], desc.circuit_protocols) self.assertEquals(False, desc.hibernating) self.assertEquals(False, desc.allow_single_hop_exits) self.assertEquals(False, desc.extra_info_cache) self.assertEquals('D225B728768D7EA4B5587C13A7A9D22EBBEE6E66', desc.extra_info_digest) self.assertEquals(['2'], desc.hidden_service_dir) self.assertEquals(expected_family, desc.family) self.assertEquals(153600, desc.average_bandwidth) self.assertEquals(256000, desc.burst_bandwidth) self.assertEquals(104590, desc.observed_bandwidth) self.assertEquals(stem.exit_policy.ExitPolicy('reject *:*'), desc.exit_policy) self.assertEquals(expected_onion_key, desc.onion_key) self.assertEquals(expected_signing_key, desc.signing_key) self.assertEquals(expected_signature, desc.signature) self.assertEquals([], desc.get_unrecognized_lines()) self.assertEquals('2C7B27BEAB04B4E2459D89CA6D5CD1CC5F95A689', desc.digest())
def test_vote(self): """ Checks that vote documents are properly parsed. """ expected_flags = set( ["Authority", "BadExit", "Exit", "Fast", "Guard", "HSDir", "Running", "Stable", "V2Dir", "Valid"]) expected_identity_key = """-----BEGIN RSA PUBLIC KEY----- MIIBigKCAYEA6uSmsoxj2MiJ3qyZq0qYXlRoG8o82SNqg+22m+t1c7MlQOZWPJYn XeMcBCt8xrTeIt2ZI+Q/Kt2QJSeD9WZRevTKk/kn5Tg2+xXPogalUU47y5tUohGz +Q8+CxtRSXpDxBHL2P8rLHvGrI69wbNHGoQkce/7gJy9vw5Ie2qzbyXk1NG6V8Fb pr6A885vHo6TbhUnolz2Wqt/kN+UorjLkN2H3fV+iGcQFv42SyHYGDLa0WwL3PJJ r/veu36S3VaHBrfhutfioi+d3d4Ya0bKwiWi5Lm2CHuuRTgMpHLU9vlci8Hunuxq HsULe2oMsr4VEic7sW5SPC5Obpx6hStHdNv1GxoSEm3/vIuPM8pINpU5ZYAyH9yO Ef22ZHeiVMMKmpV9TtFyiFqvlI6GpQn3mNbsQqF1y3XCA3Q4vlRAkpgJVUSvTxFP 2bNDobOyVCpCM/rwxU1+RCNY5MFJ/+oktUY+0ydvTen3gFdZdgNqCYjKPLfBNm9m RGL7jZunMUNvAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signing_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAJ5itcJRYNEM3Qf1OVWLRkwjqf84oXPc2ZusaJ5zOe7TVvBMra9GNyc0 NM9y6zVkHCAePAjr4KbW/8P1olA6FUE2LV9bozaU1jFf6K8B2OELKs5FUEW+n+ic GM0x6MhngyXonWOcKt5Gj+mAu5lrno9tpNbPkz2Utr/Pi0nsDhWlAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_key_crosscert = """-----BEGIN ID SIGNATURE----- RHYImGTwg36wmEdAn7qaRg2sAfql7ZCtPIL/O3lU5OIdXXp0tNn/K00Bamqohjk+ Tz4FKsKXGDlbGv67PQcZPOK6NF0GRkNh4pk89prrDO4XwtEn7rkHHdBH6/qQ7IRG GdDZHtZ1a69oFZvPWD3hUaB50xeIe7GoKdKIfdNNJ+8= -----END ID SIGNATURE-----""" expected_key_certification = """-----BEGIN SIGNATURE----- fasWOGyUZ3iMCYpDfJ+0JcMiTH25sXPWzvlHorEOyOMbaMqRYpZU4GHzt1jLgdl6 AAoR6KdamsLg5VE8xzst48a4UFuzHFlklZ5O8om2rcvDd5DhSnWWYZnYJecqB+bo dNisPmaIVSAWb29U8BpNRj4GMC9KAgGYUj8aE/KtutAeEekFfFEHTfWZ2fFp4j3m 9rY8FWraqyiF+Emq1T8pAAgMQ+79R3oZxq0TXS42Z4Anhms735ccauKhI3pDKjbl tD5vAzIHOyjAOXj7a6jY/GrnaBNuJ4qe/4Hf9UmzK/jKKwG95BPJtPTT4LoFwEB0 KG2OUeQUNoCck4nDpsZwFqPlrWCHcHfTV2iDYFV1HQWDTtZz/qf+GtB8NXsq+I1w brADmvReM2BD6p/13h0QURCI5hq7ZYlIKcKrBa0jn1d9cduULl7vgKsRCJDls/ID emBZ6pUxMpBmV0v+PrA3v9w4DlE7GHAq61FF/zju2kpqj6MInbEvI/E+e438sWsL -----END SIGNATURE-----""" expected_signature = """-----BEGIN SIGNATURE----- fskXN84wB3mXfo+yKGSt0AcDaaPuU3NwMR3ROxWgLN0KjAaVi2eV9PkPCsQkcgw3 JZ/1HL9sHyZfo6bwaC6YSM9PNiiY6L7rnGpS7UkHiFI+M96VCMorvjm5YPs3FioJ DnN5aFtYKiTc19qIC7Nmo+afPdDEf0MlJvEOP5EWl3w= -----END SIGNATURE-----""" with open(get_resource("vote"), 'rb') as descriptor_file: document = stem.descriptor.networkstatus.NetworkStatusDocumentV3(descriptor_file.read(), default_params = False) self.assertEquals(3, document.version) self.assertEquals(None, document.version_flavor) self.assertEquals(False, document.is_consensus) self.assertEquals(True, document.is_vote) self.assertEquals(False, document.is_microdescriptor) self.assertEquals(datetime.datetime(2012, 7, 12, 0, 0, 0), document.valid_after) self.assertEquals(datetime.datetime(2012, 7, 12, 1, 0, 0), document.fresh_until) self.assertEquals(datetime.datetime(2012, 7, 12, 3, 0, 0), document.valid_until) self.assertEquals(300, document.vote_delay) self.assertEquals(300, document.dist_delay) self.assertEquals([], document.client_versions) self.assertEquals([], document.server_versions) self.assertEquals(expected_flags, set(document.known_flags)) self.assertEquals({"CircuitPriorityHalflifeMsec": 30000, "bwauthpid": 1}, document.params) self.assertEquals(None, document.consensus_method) self.assertEquals({}, document.bandwidth_weights) self.assertEquals(range(1, 13), document.consensus_methods) self.assertEquals(datetime.datetime(2012, 7, 11, 23, 50, 1), document.published) self.assertEquals([], document.get_unrecognized_lines()) router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"] self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("0799F806200B005F01E40A9A7F1A21C988AE8FB1", router.digest) self.assertEquals(datetime.datetime(2012, 7, 11, 4, 22, 53), router.published) self.assertEquals("178.218.213.229", router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port) authority = document.directory_authorities[0] self.assertEquals(1, len(document.directory_authorities)) self.assertEquals("turtles", authority.nickname) self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", authority.fingerprint) self.assertEquals("76.73.17.194", authority.hostname) self.assertEquals("76.73.17.194", authority.address) self.assertEquals(9030, authority.dir_port) self.assertEquals(9090, authority.or_port) self.assertEquals("Mike Perry <email>", authority.contact) self.assertEquals(None, authority.vote_digest) self.assertEquals(None, authority.legacy_dir_key) certificate = authority.key_certificate self.assertEquals(3, certificate.version) self.assertEquals(None, certificate.address) self.assertEquals(None, certificate.dir_port) self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", certificate.fingerprint) self.assertEquals(expected_identity_key, certificate.identity_key) self.assertEquals(datetime.datetime(2011, 11, 28, 21, 51, 4), certificate.published) self.assertEquals(datetime.datetime(2012, 11, 28, 21, 51, 4), certificate.expires) self.assertEquals(expected_signing_key, certificate.signing_key) self.assertEquals(expected_key_crosscert, certificate.crosscert) self.assertEquals(expected_key_certification, certificate.certification) signature = document.signatures[0] self.assertEquals(1, len(document.signatures)) self.assertEquals("sha1", signature.method) self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", signature.identity) self.assertEquals("D5C30C15BB3F1DA27669C2D88439939E8F418FCF", signature.key_digest) self.assertEquals(expected_signature, signature.signature)
def test_consensus_v3(self): """ Checks that version 3 consensus documents are properly parsed. """ # the document's expected client and server versions are the same expected_versions = [stem.version.Version(v) for v in ( '0.2.2.35', '0.2.2.36', '0.2.2.37', '0.2.3.10-alpha', '0.2.3.11-alpha', '0.2.3.12-alpha', '0.2.3.13-alpha', '0.2.3.14-alpha', '0.2.3.15-alpha', '0.2.3.16-alpha', '0.2.3.17-beta', '0.2.3.18-rc', '0.2.3.19-rc', )] expected_flags = set( ['Authority', 'BadExit', 'Exit', 'Fast', 'Guard', 'HSDir', 'Named', 'Running', 'Stable', 'Unnamed', 'V2Dir', 'Valid']) expected_bandwidth_weights = { 'Wbd': 3335, 'Wbe': 0, 'Wbg': 3536, 'Wbm': 10000, 'Wdb': 10000, 'Web': 10000, 'Wed': 3329, 'Wee': 10000, 'Weg': 3329, 'Wem': 10000, 'Wgb': 10000, 'Wgd': 3335, 'Wgg': 6464, 'Wgm': 6464, 'Wmb': 10000, 'Wmd': 3335, 'Wme': 0, 'Wmg': 3536, 'Wmm': 10000 } expected_signature = """-----BEGIN SIGNATURE----- HFXB4497LzESysYJ/4jJY83E5vLjhv+igIxD9LU6lf6ftkGeF+lNmIAIEKaMts8H mfWcW0b+jsrXcJoCxV5IrwCDF3u1aC3diwZY6yiG186pwWbOwE41188XI2DeYPwE I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY= -----END SIGNATURE-----""" with open(get_resource('cached-consensus'), 'rb') as descriptor_file: document = stem.descriptor.networkstatus.NetworkStatusDocumentV3(descriptor_file.read(), default_params = False) self.assertEquals(3, document.version) self.assertEquals(None, document.version_flavor) self.assertEquals(True, document.is_consensus) self.assertEquals(False, document.is_vote) self.assertEquals(False, document.is_microdescriptor) self.assertEquals(datetime.datetime(2012, 7, 12, 10, 0, 0), document.valid_after) self.assertEquals(datetime.datetime(2012, 7, 12, 11, 0, 0), document.fresh_until) self.assertEquals(datetime.datetime(2012, 7, 12, 13, 0, 0), document.valid_until) self.assertEquals(300, document.vote_delay) self.assertEquals(300, document.dist_delay) self.assertEquals(expected_versions, document.client_versions) self.assertEquals(expected_versions, document.server_versions) self.assertEquals(expected_flags, set(document.known_flags)) self.assertEquals({'CircuitPriorityHalflifeMsec': 30000, 'bwauthpid': 1}, document.params) self.assertEquals(12, document.consensus_method) self.assertEquals(expected_bandwidth_weights, document.bandwidth_weights) self.assertEquals([], document.consensus_methods) self.assertEquals(None, document.published) self.assertEquals([], document.get_unrecognized_lines()) router = document.routers['0013D22389CD50D0B784A3E4061CB31E8CE8CEB5'] self.assertEquals('sumkledi', router.nickname) self.assertEquals('0013D22389CD50D0B784A3E4061CB31E8CE8CEB5', router.fingerprint) self.assertEquals('F260ABF1297B445E04354E236F4159140FF7768F', router.digest) self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published) self.assertEquals('178.218.213.229', router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port) self.assertEquals(set(['Exit', 'Fast', 'Named', 'Running', 'Valid']), set(router.flags)) authority = document.directory_authorities[0] self.assertEquals(8, len(document.directory_authorities)) self.assertEquals('tor26', authority.nickname) self.assertEquals('14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4', authority.fingerprint) self.assertEquals('86.59.21.38', authority.hostname) self.assertEquals('86.59.21.38', authority.address) self.assertEquals(80, authority.dir_port) self.assertEquals(443, authority.or_port) self.assertEquals('Peter Palfrader', authority.contact) self.assertEquals('0B6D1E9A300B895AA2D0B427F92917B6995C3C1C', authority.vote_digest) self.assertEquals(None, authority.legacy_dir_key) self.assertEquals(None, authority.key_certificate) signature = document.signatures[0] self.assertEquals(8, len(document.signatures)) self.assertEquals('sha1', signature.method) self.assertEquals('14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4', signature.identity) self.assertEquals('BF112F1C6D5543CFD0A32215ACABD4197B5279AD', signature.key_digest) self.assertEquals(expected_signature, signature.signature)
def test_consensus_v2(self): """ Checks that version 2 consensus documents are properly parsed. """ expected_signing_key = """-----BEGIN RSA PUBLIC KEY----- MIGJAoGBAOcrht/y5rkaahfX7sMe2qnpqoPibsjTSJaDvsUtaNP/Bq0MgNDGOR48 rtwfqTRff275Edkp/UYw3G3vSgKCJr76/bqOHCmkiZrnPV1zxNfrK18gNw2Cxre0 nTA+fD8JQqpPtb8b0SnG9kwy75eS//sRu7TErie2PzGMxrf9LH0LAgMBAAE= -----END RSA PUBLIC KEY-----""" expected_signature = """-----BEGIN SIGNATURE----- 2nXCxVje3wzn6HrIFRNMc0nc48AhMVpHZyPwRKGXkuYfTQG55uvwQDaFgJHud4RT 27QhWltau3K1evhnzhKcpbTXwkVv1TBYJSzL6rEeAn8cQ7ZiCyqf4EJCaNcem3d2 TpQQk3nNQF8z6UIvdlvP+DnJV4izWVkQEZgUZgIVM0E= -----END SIGNATURE-----""" with open(get_resource("cached-consensus-v2"), 'rb') as descriptor_file: descriptor_file.readline() # strip header document = stem.descriptor.networkstatus.NetworkStatusDocumentV2(descriptor_file.read()) self.assertEquals(2, document.version) self.assertEquals("18.244.0.114", document.hostname) self.assertEquals("18.244.0.114", document.address) self.assertEquals(80, document.dir_port) self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", document.fingerprint) self.assertEquals("arma at mit dot edu", document.contact) self.assertEquals(expected_signing_key, document.signing_key) self.assertEquals(67, len(document.client_versions)) self.assertEquals("0.0.9rc2", document.client_versions[0]) self.assertEquals("0.1.1.10-alpha-cvs", document.client_versions[-1]) self.assertEquals(67, len(document.server_versions)) self.assertEquals("0.0.9rc2", document.server_versions[0]) self.assertEquals("0.1.1.10-alpha-cvs", document.server_versions[-1]) self.assertEquals(datetime.datetime(2005, 12, 16, 0, 13, 46), document.published) self.assertEquals(["Names", "Versions"], document.options) self.assertEquals("moria2", document.signing_authority) self.assertEquals(expected_signature, document.signature) self.assertEquals([], document.get_unrecognized_lines()) self.assertEqual(3, len(document.routers)) router1 = document.routers["719BE45DE224B607C53707D0E2143E2D423E74CF"] self.assertEquals("moria2", router1.nickname) self.assertEquals("719BE45DE224B607C53707D0E2143E2D423E74CF", router1.fingerprint) self.assertEquals("B7F3F0975B87889DD1285FD57A1B1BB617F65432", router1.digest) self.assertEquals(datetime.datetime(2005, 12, 15, 6, 57, 18), router1.published) self.assertEquals("18.244.0.114", router1.address) self.assertEquals(443, router1.or_port) self.assertEquals(80, router1.dir_port) self.assertEquals(set(["Authority", "Fast", "Named", "Running", "Valid", "V2Dir"]), set(router1.flags)) router2 = document.routers["0928BA467056C4A689FEE4EF5D71482B6289C3D5"] self.assertEquals("stnv", router2.nickname) self.assertEquals("0928BA467056C4A689FEE4EF5D71482B6289C3D5", router2.fingerprint) self.assertEquals("22D1A7ED4199BDA7ED6C416EECD769C18E1F2A5A", router2.digest) self.assertEquals(datetime.datetime(2005, 12, 15, 16, 24, 42), router2.published) self.assertEquals("84.16.236.173", router2.address) self.assertEquals(9001, router2.or_port) self.assertEquals(None, router2.dir_port) self.assertEquals(set(["Named", "Valid"]), set(router2.flags)) router3 = document.routers["09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968"] self.assertEquals("nggrplz", router3.nickname) self.assertEquals("09E8582FF0E6F85E2B8E41C0DC0B9C9DC46E6968", router3.fingerprint) self.assertEquals("B302C2B01C94F398E3EF38939526B0651F824DD6", router3.digest) self.assertEquals(datetime.datetime(2005, 12, 15, 23, 25, 50), router3.published) self.assertEquals("194.109.109.109", router3.address) self.assertEquals(9001, router3.or_port) self.assertEquals(None, router3.dir_port) self.assertEquals(set(["Fast", "Stable", "Running", "Valid"]), set(router3.flags))
def test_consensus_v3(self): """ Checks that version 3 consensus documents are properly parsed. """ # the document's expected client and server versions are the same expected_versions = [stem.version.Version(v) for v in ( "0.2.2.35", "0.2.2.36", "0.2.2.37", "0.2.3.10-alpha", "0.2.3.11-alpha", "0.2.3.12-alpha", "0.2.3.13-alpha", "0.2.3.14-alpha", "0.2.3.15-alpha", "0.2.3.16-alpha", "0.2.3.17-beta", "0.2.3.18-rc", "0.2.3.19-rc", )] expected_flags = set( ["Authority", "BadExit", "Exit", "Fast", "Guard", "HSDir", "Named", "Running", "Stable", "Unnamed", "V2Dir", "Valid"]) expected_bandwidth_weights = { "Wbd": 3335, "Wbe": 0, "Wbg": 3536, "Wbm": 10000, "Wdb": 10000, "Web": 10000, "Wed": 3329, "Wee": 10000, "Weg": 3329, "Wem": 10000, "Wgb": 10000, "Wgd": 3335, "Wgg": 6464, "Wgm": 6464, "Wmb": 10000, "Wmd": 3335, "Wme": 0, "Wmg": 3536, "Wmm": 10000 } expected_signature = """-----BEGIN SIGNATURE----- HFXB4497LzESysYJ/4jJY83E5vLjhv+igIxD9LU6lf6ftkGeF+lNmIAIEKaMts8H mfWcW0b+jsrXcJoCxV5IrwCDF3u1aC3diwZY6yiG186pwWbOwE41188XI2DeYPwE I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY= -----END SIGNATURE-----""" with open(get_resource("cached-consensus"), 'rb') as descriptor_file: document = stem.descriptor.networkstatus.NetworkStatusDocumentV3(descriptor_file.read(), default_params = False) self.assertEquals(3, document.version) self.assertEquals(None, document.version_flavor) self.assertEquals(True, document.is_consensus) self.assertEquals(False, document.is_vote) self.assertEquals(False, document.is_microdescriptor) self.assertEquals(datetime.datetime(2012, 7, 12, 10, 0, 0), document.valid_after) self.assertEquals(datetime.datetime(2012, 7, 12, 11, 0, 0), document.fresh_until) self.assertEquals(datetime.datetime(2012, 7, 12, 13, 0, 0), document.valid_until) self.assertEquals(300, document.vote_delay) self.assertEquals(300, document.dist_delay) self.assertEquals(expected_versions, document.client_versions) self.assertEquals(expected_versions, document.server_versions) self.assertEquals(expected_flags, set(document.known_flags)) self.assertEquals({"CircuitPriorityHalflifeMsec": 30000, "bwauthpid": 1}, document.params) self.assertEquals(12, document.consensus_method) self.assertEquals(expected_bandwidth_weights, document.bandwidth_weights) self.assertEquals([], document.consensus_methods) self.assertEquals(None, document.published) self.assertEquals([], document.get_unrecognized_lines()) router = document.routers["0013D22389CD50D0B784A3E4061CB31E8CE8CEB5"] self.assertEquals("sumkledi", router.nickname) self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint) self.assertEquals("F260ABF1297B445E04354E236F4159140FF7768F", router.digest) self.assertEquals(datetime.datetime(2012, 7, 12, 4, 1, 55), router.published) self.assertEquals("178.218.213.229", router.address) self.assertEquals(80, router.or_port) self.assertEquals(None, router.dir_port) self.assertEquals(set(["Exit", "Fast", "Named", "Running", "Valid"]), set(router.flags)) authority = document.directory_authorities[0] self.assertEquals(8, len(document.directory_authorities)) self.assertEquals("tor26", authority.nickname) self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", authority.fingerprint) self.assertEquals("86.59.21.38", authority.hostname) self.assertEquals("86.59.21.38", authority.address) self.assertEquals(80, authority.dir_port) self.assertEquals(443, authority.or_port) self.assertEquals("Peter Palfrader", authority.contact) self.assertEquals("0B6D1E9A300B895AA2D0B427F92917B6995C3C1C", authority.vote_digest) self.assertEquals(None, authority.legacy_dir_key) self.assertEquals(None, authority.key_certificate) signature = document.signatures[0] self.assertEquals(8, len(document.signatures)) self.assertEquals("sha1", signature.method) self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", signature.identity) self.assertEquals("BF112F1C6D5543CFD0A32215ACABD4197B5279AD", signature.key_digest) self.assertEquals(expected_signature, signature.signature)