[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Supporting '-legacy' authority entries
commit 153ada322653f95eb21c360d3cac4fe6ad436ed7
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Thu Jan 10 08:37:17 2013 -0800
Supporting '-legacy' authority entries
Directory authorities have an alternative format if their nickname has a
'-legacy' suffix. Caught by Karsten on...
https://trac.torproject.org/7866
---
stem/descriptor/networkstatus.py | 29 ++++++++++++++++---
.../networkstatus/directory_authority.py | 23 +++++++++++++++
test/unit/descriptor/networkstatus/document_v3.py | 15 ++++++++++
3 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 5da190a..e3d5779 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -909,17 +909,24 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
"""
Directory authority information obtained from a v3 network status document.
+ Authorities can optionally use a legacy format. These are no longer found in
+ practice, but have the following differences...
+
+ * The authority's nickname ends with '-legacy'.
+ * There's no **contact** or **vote_digest** attribute.
+
:var str nickname: **\*** authority's nickname
:var str fingerprint: **\*** authority's fingerprint
:var str hostname: **\*** hostname of the authority
:var str address: **\*** authority's IP address
:var int dir_port: **\*** authority's DirPort
:var int or_port: **\*** authority's ORPort
- :var str contact: **\*** contact information
+ :var bool is_legacy: **\*** if the authority's using the legacy format
+ :var str contact: contact information, this is included if is_legacy is **False**
**Consensus Attributes:**
- :var str vote_digest: **\*** digest of the authority that contributed to the consensus
+ :var str vote_digest: digest of the authority that contributed to the consensus, this is included if is_legacy is **False**
**Vote Attributes:**
@@ -950,6 +957,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
self.address = None
self.dir_port = None
self.or_port = None
+ self.is_legacy = False
self.contact = None
self.vote_digest = None
@@ -990,7 +998,15 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
# check that we have mandatory fields
if validate:
- required_fields, excluded_fields = ["dir-source", "contact"], []
+ is_legacy, dir_source_entry = False, entries.get("dir-source")
+
+ if dir_source_entry:
+ is_legacy = dir_source_entry[0][0].split()[0].endswith("-legacy")
+
+ required_fields, excluded_fields = ["dir-source"], []
+
+ if not is_legacy:
+ required_fields += ["contact"]
if is_vote:
if not key_cert_content:
@@ -1001,7 +1017,9 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
if key_cert_content:
raise ValueError("Authority consensus entries shouldn't have a key certificate:\n%s" % content)
- required_fields += ["vote-digest"]
+ if not is_legacy:
+ required_fields += ["vote-digest"]
+
excluded_fields += ["legacy-dir-key"]
for keyword in required_fields:
@@ -1033,7 +1051,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
raise ValueError("Authority entry's 'dir-source' line must have six values: %s" % line)
if validate:
- if not stem.util.tor_tools.is_valid_nickname(dir_source_comp[0]):
+ if not stem.util.tor_tools.is_valid_nickname(dir_source_comp[0].rstrip('-legacy')):
raise ValueError("Authority's nickname is invalid: %s" % dir_source_comp[0])
elif not stem.util.tor_tools.is_valid_fingerprint(dir_source_comp[1]):
raise ValueError("Authority's fingerprint is invalid: %s" % dir_source_comp[1])
@@ -1055,6 +1073,7 @@ class DirectoryAuthority(stem.descriptor.Descriptor):
self.address = dir_source_comp[3]
self.dir_port = None if dir_source_comp[4] == '0' else int(dir_source_comp[4])
self.or_port = int(dir_source_comp[5])
+ self.is_legacy = self.nickname.endswith("-legacy")
elif keyword == 'contact':
# "contact" string
diff --git a/test/unit/descriptor/networkstatus/directory_authority.py b/test/unit/descriptor/networkstatus/directory_authority.py
index eb685df..539b6b1 100644
--- a/test/unit/descriptor/networkstatus/directory_authority.py
+++ b/test/unit/descriptor/networkstatus/directory_authority.py
@@ -22,6 +22,7 @@ class TestDirectoryAuthority(unittest.TestCase):
self.assertEqual("76.73.17.194", authority.address)
self.assertEqual(9030, authority.dir_port)
self.assertEqual(9090, authority.or_port)
+ self.assertEqual(False, authority.is_legacy)
self.assertEqual("Mike Perry <email>", authority.contact)
self.assertEqual("0B6D1E9A300B895AA2D0B427F92917B6995C3C1C", authority.vote_digest)
self.assertEqual(None, authority.legacy_dir_key)
@@ -41,6 +42,7 @@ class TestDirectoryAuthority(unittest.TestCase):
self.assertEqual("76.73.17.194", authority.address)
self.assertEqual(9030, authority.dir_port)
self.assertEqual(9090, authority.or_port)
+ self.assertEqual(False, authority.is_legacy)
self.assertEqual("Mike Perry <email>", authority.contact)
self.assertEqual(None, authority.vote_digest)
self.assertEqual(None, authority.legacy_dir_key)
@@ -55,6 +57,27 @@ class TestDirectoryAuthority(unittest.TestCase):
authority = get_directory_authority({"pepperjack": "is oh so tasty!"})
self.assertEquals(["pepperjack is oh so tasty!"], authority.get_unrecognized_lines())
+ def test_legacy_authority(self):
+ """
+ Parses an authority using the '-legacy' format.
+ """
+
+ content = "dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443"
+ authority = DirectoryAuthority(content, is_vote = False)
+
+ self.assertEqual("gabelmoo-legacy", authority.nickname)
+ self.assertEqual("81349FC1F2DBA2C2C11B45CB9706637D480AB913", authority.fingerprint)
+ self.assertEqual("212.112.245.170", authority.hostname)
+ self.assertEqual("212.112.245.170", authority.address)
+ self.assertEqual(80, authority.dir_port)
+ self.assertEqual(443, authority.or_port)
+ self.assertEqual(True, authority.is_legacy)
+ self.assertEqual(None, authority.contact)
+ self.assertEqual(None, authority.vote_digest)
+ self.assertEqual(None, authority.legacy_dir_key)
+ self.assertEqual(None, authority.key_certificate)
+ self.assertEqual([], authority.get_unrecognized_lines())
+
def test_first_line(self):
"""
Includes a non-mandatory field before the 'dir-source' line.
diff --git a/test/unit/descriptor/networkstatus/document_v3.py b/test/unit/descriptor/networkstatus/document_v3.py
index d15e88a..42603b1 100644
--- a/test/unit/descriptor/networkstatus/document_v3.py
+++ b/test/unit/descriptor/networkstatus/document_v3.py
@@ -787,6 +787,21 @@ class TestNetworkStatusDocument(unittest.TestCase):
document = NetworkStatusDocumentV3(content, validate = False)
self.assertEquals((authority1, authority2), document.directory_authorities)
+ def test_with_legacy_directory_authorities(self):
+ """
+ Includes both normal authorities and those following the '-legacy' format.
+ """
+
+ legacy_content = "dir-source gabelmoo-legacy 81349FC1F2DBA2C2C11B45CB9706637D480AB913 212.112.245.170 212.112.245.170 80 443"
+
+ authority1 = get_directory_authority({'contact': 'doctor jekyll'}, is_vote = False)
+ authority2 = DirectoryAuthority(legacy_content, validate = True, is_vote = False)
+ authority3 = get_directory_authority({'contact': 'mister hyde'}, is_vote = False)
+
+ document = get_network_status_document_v3({"vote-status": "consensus"}, authorities = (authority1, authority2, authority3))
+
+ self.assertEquals((authority1, authority2, authority3), document.directory_authorities)
+
def test_authority_validation_flag_propagation(self):
"""
Includes invalid certificate content in an authority entry. This is testing
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits