[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Replacing RouterStatusEntry's identity with fingerprint
commit fd58bc5a565bca11d372188a4add167775f091c1
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sun Aug 19 17:55:25 2012 -0700
Replacing RouterStatusEntry's identity with fingerprint
Truncated base64 encoding of a relay's fingerprint? Not useful. Common hex
encoded fingerprint that's used everywhere else? Very useful.
Decoding the RouterStatusEntry's identity value and adding a unit test for it.
Unfortunately the networkstatus module didn't have any unit tests at all so
this is gonna take a while to remedy...
---
run_tests.py | 4 ++-
stem/descriptor/networkstatus.py | 59 ++++++++++++++++++++++++++------
test/integ/descriptor/networkstatus.py | 14 ++++----
test/unit/descriptor/__init__.py | 2 +-
test/unit/descriptor/networkstatus.py | 27 ++++++++++++++
5 files changed, 86 insertions(+), 20 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 8d115f1..d2e4da7 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -20,6 +20,7 @@ import test.unit.descriptor.export
import test.unit.descriptor.reader
import test.unit.descriptor.server_descriptor
import test.unit.descriptor.extrainfo_descriptor
+import test.unit.descriptor.networkstatus
import test.unit.response.control_line
import test.unit.response.control_message
import test.unit.response.getinfo
@@ -114,6 +115,7 @@ UNIT_TESTS = (
test.unit.descriptor.reader.TestDescriptorReader,
test.unit.descriptor.server_descriptor.TestServerDescriptor,
test.unit.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor,
+ test.unit.descriptor.networkstatus.TestNetworkStatus,
test.unit.exit_policy.rule.TestExitPolicyRule,
test.unit.exit_policy.policy.TestExitPolicy,
test.unit.version.TestVersion,
@@ -135,7 +137,7 @@ INTEG_TESTS = (
test.integ.descriptor.reader.TestDescriptorReader,
test.integ.descriptor.server_descriptor.TestServerDescriptor,
test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor,
- test.integ.descriptor.networkstatus.TestNetworkStatusDocument,
+ test.integ.descriptor.networkstatus.TestNetworkStatus,
test.integ.version.TestVersion,
test.integ.response.protocolinfo.TestProtocolInfo,
test.integ.process.TestProcess,
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 7eab8da..485234f 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -41,6 +41,7 @@ The documents can be obtained from any of the following sources...
"""
import re
+import base64
import datetime
try:
@@ -325,7 +326,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
documents.
:var str nickname: directory authority's nickname
- :var str identity: uppercase hex fingerprint of the authority's identity key
+ :var str fingerprint: uppercase hex fingerprint of the authority's identity key
:var str address: hostname
:var str ip: current IP address
:var int dirport: current directory port
@@ -352,13 +353,13 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
"""
super(DirectoryAuthority, self).__init__(raw_content)
- self.nickname, self.identity, self.address, self.ip = None, None, None, None
+ self.nickname, self.fingerprint, self.address, self.ip = None, None, None, None
self.dirport, self.orport, self.legacy_dir_key = None, None, None
self.key_certificate, self.contact, self.vote_digest = None, None, None
content = StringIO(raw_content)
dir_source = _read_keyword_line("dir-source", content, validate)
- self.nickname, self.identity, self.address, self.ip, self.dirport, self.orport = dir_source.split(" ")
+ self.nickname, self.fingerprint, self.address, self.ip, self.dirport, self.orport = dir_source.split(" ")
self.dirport = int(self.dirport)
self.orport = int(self.orport)
@@ -431,13 +432,13 @@ class DirectorySignature(stem.descriptor.Descriptor):
class RouterStatusEntry(stem.descriptor.Descriptor):
"""
- Router descriptor object. Parses and stores router information in a router
- entry read from a v3 network status document.
+ Information about an individual router stored within a network status
+ document.
- :var NetworkStatusDocument document: **\*** document this descriptor came from
+ :var NetworkStatusDocument document: **\*** document that this descriptor came from
:var str nickname: **\*** router's nickname
- :var str identity: **\*** router's identity
+ :var str fingerprint: **\*** router's fingerprint
:var str digest: **\*** router's digest
:var datetime publication: **\*** router's publication
:var str ip: **\*** router's IP address
@@ -478,7 +479,7 @@ class RouterStatusEntry(stem.descriptor.Descriptor):
self.document = document
self.nickname = None
- self.identity = None
+ self.fingerprint = None
self.digest = None
self.publication = None
self.ip = None
@@ -519,7 +520,7 @@ class RouterStatusEntry(stem.descriptor.Descriptor):
if r:
seen_keywords.add("r")
values = r.split(" ")
- self.nickname, self.identity, self.digest = values[0], values[1], values[2]
+ self.nickname, self.fingerprint, self.digest = values[0], _decode_fingerprint(values[1]), values[2]
self.publication = _strptime(" ".join((values[3], values[4])), validate)
self.ip, self.orport, self.dirport = values[5], int(values[6]), int(values[7])
if self.dirport == 0: self.dirport = None
@@ -640,7 +641,7 @@ class RouterMicrodescriptor(RouterStatusEntry):
:var MicrodescriptorConsensus document: **\*** document this descriptor came from
:var str nickname: **\*** router's nickname
- :var str identity: **\*** router's identity
+ :var str fingerprint: **\*** router's fingerprint
:var datetime publication: **\*** router's publication
:var str ip: **\*** router's IP address
:var int orport: **\*** router's ORPort
@@ -695,7 +696,7 @@ class RouterMicrodescriptor(RouterStatusEntry):
if r:
seen_keywords.add("r")
values = r.split(" ")
- self.nickname, self.identity = values[0], values[1]
+ self.nickname, self.fingerprint = values[0], _decode_fingerprint(values[1])
self.publication = _strptime(" ".join((values[2], values[3])), validate)
self.ip, self.orport, self.dirport = values[4], int(values[5]), int(values[6])
if self.dirport == 0: self.dirport = None
@@ -764,3 +765,39 @@ class RouterMicrodescriptor(RouterStatusEntry):
"""
return self.unrecognized_lines
+
+def _decode_fingerprint(identity):
+ """
+ Decodes the 'identity' value found in consensuses into the more common hex
+ encoding of the relay's fingerprint. For example...
+
+ ::
+
+ >>> _decode_fingerprint('p1aag7VwarGxqctS7/fS0y5FU+s')
+ 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'
+
+ :param str identity: encoded fingerprint from the consensus
+
+ :returns: str with the uppercase hex encoding of the relay's fingerprint
+ """
+
+ # trailing equal signs were stripped from the identity
+ missing_padding = 28 - len(identity)
+ identity += "=" * missing_padding
+
+ fingerprint = ""
+ for char in base64.b64decode(identity):
+ # Individual characters are either standard ascii or hex encoded, and each
+ # represent two hex digits. For instnace...
+ #
+ # >>> ord('\n')
+ # 10
+ # >>> hex(10)
+ # '0xa'
+ # >>> '0xa'[2:].zfill(2).upper()
+ # '0A'
+
+ fingerprint += hex(ord(char))[2:].zfill(2).upper()
+
+ return fingerprint
+
diff --git a/test/integ/descriptor/networkstatus.py b/test/integ/descriptor/networkstatus.py
index d16929d..621bb14 100644
--- a/test/integ/descriptor/networkstatus.py
+++ b/test/integ/descriptor/networkstatus.py
@@ -17,7 +17,7 @@ import test.integ.descriptor
def _strptime(string):
return datetime.datetime.strptime(string, "%Y-%m-%d %H:%M:%S")
-class TestNetworkStatusDocument(unittest.TestCase):
+class TestNetworkStatus(unittest.TestCase):
def test_cached_consensus(self):
"""
Parses the cached-consensus file in our data directory.
@@ -59,7 +59,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
router = next(descriptors)
self.assertEquals("sumkledi", router.nickname)
- self.assertEquals("ABPSI4nNUNC3hKPkBhyzHozozrU", router.identity)
+ self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
self.assertEquals("8mCr8Sl7RF4ENU4jb0FZFA/3do8", router.digest)
self.assertEquals(_strptime("2012-07-12 04:01:55"), router.publication)
self.assertEquals("178.218.213.229", router.ip)
@@ -104,7 +104,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertEquals(expected_params, desc.params)
self.assertEquals("sumkledi", router1.nickname)
- self.assertEquals("ABPSI4nNUNC3hKPkBhyzHozozrU", router1.identity)
+ self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router1.fingerprint)
self.assertEquals("8mCr8Sl7RF4ENU4jb0FZFA/3do8", router1.digest)
self.assertEquals(_strptime("2012-07-12 04:01:55"), router1.publication)
self.assertEquals("178.218.213.229", router1.ip)
@@ -114,7 +114,7 @@ class TestNetworkStatusDocument(unittest.TestCase):
self.assertEquals(8, len(desc.directory_authorities))
self.assertEquals("tor26", desc.directory_authorities[0].nickname)
- self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", desc.directory_authorities[0].identity)
+ self.assertEquals("14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4", desc.directory_authorities[0].fingerprint)
self.assertEquals("86.59.21.38", desc.directory_authorities[0].address)
self.assertEquals("86.59.21.38", desc.directory_authorities[0].ip)
self.assertEquals(80, desc.directory_authorities[0].dirport)
@@ -152,7 +152,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
router = next(descriptors)
self.assertEquals("sumkledi", router.nickname)
- self.assertEquals("ABPSI4nNUNC3hKPkBhyzHozozrU", router.identity)
+ self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router.fingerprint)
self.assertEquals("B5n4BiALAF8B5AqafxohyYiuj7E", router.digest)
self.assertEquals(_strptime("2012-07-11 04:22:53"), router.publication)
self.assertEquals("178.218.213.229", router.ip)
@@ -189,7 +189,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
self.assertEquals(expected_params, desc.params)
self.assertEquals("sumkledi", router1.nickname)
- self.assertEquals("ABPSI4nNUNC3hKPkBhyzHozozrU", router1.identity)
+ self.assertEquals("0013D22389CD50D0B784A3E4061CB31E8CE8CEB5", router1.fingerprint)
self.assertEquals("B5n4BiALAF8B5AqafxohyYiuj7E", router1.digest)
self.assertEquals(_strptime("2012-07-11 04:22:53"), router1.publication)
self.assertEquals("178.218.213.229", router1.ip)
@@ -198,7 +198,7 @@ I/TJmV928na7RLZe2mGHCAW3VQOvV+QkCfj05VZ8CsY=
self.assertEquals(1, len(desc.directory_authorities))
self.assertEquals("turtles", desc.directory_authorities[0].nickname)
- self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", desc.directory_authorities[0].identity)
+ self.assertEquals("27B6B5996C426270A5C95488AA5BCEB6BCC86956", desc.directory_authorities[0].fingerprint)
self.assertEquals("76.73.17.194", desc.directory_authorities[0].address)
self.assertEquals("76.73.17.194", desc.directory_authorities[0].ip)
self.assertEquals(9030, desc.directory_authorities[0].dirport)
diff --git a/test/unit/descriptor/__init__.py b/test/unit/descriptor/__init__.py
index 1837a07..4793560 100644
--- a/test/unit/descriptor/__init__.py
+++ b/test/unit/descriptor/__init__.py
@@ -2,5 +2,5 @@
Unit tests for stem.descriptor.
"""
-__all__ = ["export", "reader", "extrainfo_descriptor", "server_descriptor"]
+__all__ = ["export", "reader", "extrainfo_descriptor", "server_descriptor", "networkstatus"]
diff --git a/test/unit/descriptor/networkstatus.py b/test/unit/descriptor/networkstatus.py
new file mode 100644
index 0000000..ec69367
--- /dev/null
+++ b/test/unit/descriptor/networkstatus.py
@@ -0,0 +1,27 @@
+"""
+Unit tests for stem.descriptor.networkstatus.
+"""
+
+import unittest
+
+from stem.descriptor import networkstatus
+
+class TestNetworkStatus(unittest.TestCase):
+ def test_fingerprint_decoding(self):
+ """
+ Tests for the _decode_fingerprint() helper.
+ """
+
+ # consensus identity field and fingerprint for caerSidi and Amunet1-5
+ test_values = {
+ 'p1aag7VwarGxqctS7/fS0y5FU+s': 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB',
+ 'IbhGa8T+8tyy/MhxCk/qI+EI2LU': '21B8466BC4FEF2DCB2FCC8710A4FEA23E108D8B5',
+ '20wYcbFGwFfMktmuffYj6Z1RM9k': 'DB4C1871B146C057CC92D9AE7DF623E99D5133D9',
+ 'nTv9AG1cZeFW2hXiSIEAF6JLRJ4': '9D3BFD006D5C65E156DA15E248810017A24B449E',
+ '/UKsQiOSGPi/6es0/ha1prNTeDI': 'FD42AC42239218F8BFE9EB34FE16B5A6B3537832',
+ '/nHdqoKZ6bKZixxAPzYt9Qen+Is': 'FE71DDAA8299E9B2998B1C403F362DF507A7F88B',
+ }
+
+ for arg, expected in test_values.items():
+ self.assertEqual(expected, networkstatus._decode_fingerprint(arg))
+
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits