[tor-commits] [stem/master] Support for HS_DESC_CONTENT events

atagar at torproject.org atagar at torproject.org
Sat Mar 14 21:22:36 UTC 2015


commit 162206da75b2eab2e8ab7b2866e70493d44d31d4
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Mar 14 14:05:04 2015 -0700

    Support for HS_DESC_CONTENT events
    
    Usually I don't had support before an event is in tor, but HS_DESC_CONTENT is
    tantalizingly close and I want to help #14847 along. This helped highlight a
    couple issues we should address.
---
 stem/response/events.py      |   50 +++++++++++++++++++++++-
 test/unit/response/events.py |   88 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/stem/response/events.py b/stem/response/events.py
index cdf0ba7..20676c6 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -49,7 +49,7 @@ class Event(stem.response.ControlMessage):
     if not str(self).strip():
       raise stem.ProtocolError('Received a blank tor event. Events must at the very least have a type.')
 
-    self.type = str(self).split().pop(0)
+    self.type = str(self).split()[0]
     self.arrived_at = arrived_at
 
     # if we're a recognized event type then translate ourselves into that subclass
@@ -230,6 +230,9 @@ class AuthDirNewDescEvent(Event):
     elif lines[-1] != 'OK':
       raise stem.ProtocolError("AUTHDIR_NEWDESCS doesn't end with an 'OK'")
 
+    # TODO: For stem 2.0.0 we should consider changing 'descriptor' to a
+    # ServerDescriptor instance.
+
     self.action = lines[1]
     self.message = lines[2]
     self.descriptor = '\n'.join(lines[3:-1])
@@ -655,6 +658,44 @@ class HSDescEvent(Event):
     self._log_if_unrecognized('authentication', stem.HSAuth)
 
 
+class HSDescContentEvent(Event):
+  """
+  Provides the content of hidden service descriptors we fetch.
+
+  The HS_DESC_CONTENT event was introduced in tor version 0.2.7.1-alpha.
+
+  .. versionadded:: 1.4.0
+
+  :var str address: hidden service address
+  :var str descriptor_id: descriptor identifier
+  :var str directory: hidden service directory servicing the request
+  :var str directory_fingerprint: hidden service directory's finterprint
+  :var str directory_nickname: hidden service directory's nickname if it was provided
+  :var stem.descriptor.hidden_service_descriptor.HiddenServiceDescriptor descriptor: descriptor that was retrieved
+  """
+
+  # TODO: Double check that this version is correct when #14847 is merged, then add to stem.version.Requirement.
+  # _VERSION_ADDED = stem.version.Requirement.EVENT_HS_DESC_CONTENT
+  _POSITIONAL_ARGS = ('address', 'descriptor_id', 'directory')
+
+  def _parse(self):
+    if self.address == 'UNKNOWN':
+      self.address = None
+
+    self.directory_fingerprint = None
+    self.directory_nickname = None
+
+    try:
+      self.directory_fingerprint, self.directory_nickname = \
+        stem.control._parse_circ_entry(self.directory)
+    except stem.ProtocolError:
+      raise stem.ProtocolError("HS_DESC_CONTENT's directory doesn't match a ServerSpec: %s" % self)
+
+    self.descriptor = list(stem.descriptor.hidden_service_descriptor._parse_file(
+      io.BytesIO(str_tools._to_bytes('\n'.join(str(self).splitlines()[1:]))),
+    ))[0]
+
+
 class LogEvent(Event):
   """
   Tor logging event. These are the most visible kind of event since, by
@@ -695,6 +736,9 @@ class NetworkStatusEvent(Event):
   def _parse(self):
     content = str(self).lstrip('NS\n').rstrip('\nOK')
 
+    # TODO: For stem 2.0.0 consider changing 'desc' to 'descriptors' to match
+    # our other events.
+
     self.desc = list(stem.descriptor.router_status_entry._parse_file(
       io.BytesIO(str_tools._to_bytes(content)),
       True,
@@ -720,6 +764,9 @@ class NewConsensusEvent(Event):
   def _parse(self):
     content = str(self).lstrip('NEWCONSENSUS\n').rstrip('\nOK')
 
+    # TODO: For stem 2.0.0 consider changing 'desc' to 'descriptors' to match
+    # our other events.
+
     self.desc = list(stem.descriptor.router_status_entry._parse_file(
       io.BytesIO(str_tools._to_bytes(content)),
       True,
@@ -1259,6 +1306,7 @@ EVENT_TYPE_TO_CLASS = {
   'ERR': LogEvent,
   'GUARD': GuardEvent,
   'HS_DESC': HSDescEvent,
+  'HS_DESC_CONTENT': HSDescContentEvent,
   'INFO': LogEvent,
   'NEWCONSENSUS': NewConsensusEvent,
   'NEWDESC': NewDescEvent,
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index c4d0ac8..2797a02 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -206,6 +206,74 @@ HS_DESC_FAILED = '650 HS_DESC FAILED ajhb7kljbiru65qo NO_AUTH \
 $67B2BDA4264D8A189D9270E28B1D30A262838243 \
 b3oeducbhjmbqmgw2i3jtz4fekkrinwj REASON=NOT_FOUND'
 
+# HS_DESC_CONTENT is unreleased (plan is tor 0.2.7.1-alpha, #14847)
+
+HS_DESC_CONTENT_EVENT = """\
+650+HS_DESC_CONTENT facebookcorewwwi riwvyw6njgvs4koel4heqs7w4bssnmlw $8A30C9E8F5954EE286D29BD65CADEA6991200804~YorkshireTOR
+rendezvous-service-descriptor riwvyw6njgvs4koel4heqs7w4bssnmlw
+version 2
+permanent-key
+-----BEGIN RSA PUBLIC KEY-----
+MIGJAoGBALfng/krEfrBcvblDiM3PAkowkiAKxLoTsXt3nPEzyTP6Cw+Gdr0ODje
+hmxTngN1pKiH7szk4Q1p2RabOrUHWwXmGXeDDNs00fcyU6HupgqsCoKOqCsmPac6
+/58apC64A7xHeS02wtfWJp6qiZ8i6GGu6xWXRWux+ShPgcHvkajRAgMahU8=
+-----END RSA PUBLIC KEY-----
+secret-id-part vnb2j6ftvkvghypd4yyypsl3qmpjyq3j
+publication-time 2015-03-13 19:00:00
+protocol-versions 2,3
+introduction-points
+-----BEGIN MESSAGE-----
+aW50cm9kdWN0aW9uLXBvaW50IHNqbm1xbmdraXl3YmtkeXBjb2FqdHY2dmNtNjY2
+NmR6CmlwLWFkZHJlc3MgMTk4LjIzLjE4Ny4xNTgKb25pb24tcG9ydCA0NDMKb25p
+b24ta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpNSUdKQW9HQkFO
+MUNsaERkZDNSWHdwT0hMZUNNYlVvNFlISDNEMUxnR0pXbEFPVnBxQ3ZSbDhEbjIv
+UWpGeHNVCnJGaG9WUzRDUjlNVFIzMnlsSnJ0R2JTcWxRVm1HY3M3bnZ5RDU5YVky
+em9RVGhIdm1lWVUwS0ZzQTc5ZFNyTW0KUDR5WnZFSkZmdkpQODRySWd0TlVtZ3R4
+aHQzVzNiR2FVMUNBNGU4bjBza2hYWXdRRzg1MUFnTUJBQUU9Ci0tLS0tRU5EIFJT
+QSBQVUJMSUMgS0VZLS0tLS0Kc2VydmljZS1rZXkKLS0tLS1CRUdJTiBSU0EgUFVC
+TElDIEtFWS0tLS0tCk1JR0pBb0dCQUxDajREUTJPaTJhRjF4WE1iNjhsSHFJQnN5
+NjRSbXFjTUpNb1d3THF4WTFiREcwbnE0Nlk5eHYKVnBPVzAxTmQrYnF3b3BIa0J2
+TzllSGVKTm9NN1BYMmtVWmQ5RlFQSUJHbWdCZ0dxenV6a2lQTEFpbHhtWHRQbwpN
+cnRheGdzRTR6MjlWYnJUV2Q0SHFKSDJFOWNybDdzeHhiTGVvSDFLRjZzSm5lMFlP
+WGlyQWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQppbnRyb2R1
+Y3Rpb24tcG9pbnQgYmhzbjVhdDNzaDIzZGZ5cmNxYnU1bDV6NGs1Z3RueHAKaXAt
+YWRkcmVzcyAxMDQuMTI4Ljc4LjEwNwpvbmlvbi1wb3J0IDMwMDIKb25pb24ta2V5
+Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpNSUdKQW9HQkFMYk5HdU0v
+RlNnZEJjOTFZSjNQOXRoVC9vQzRWOFZDZzZBcjk5WlFHRldhVGlRdXRjNGZLWC9F
+CnR1TGRjdzBsRmxVbXhPZXNXMVduaVkxaVFDOW9yUkQ3cGE1amNES0EyRThDb3kv
+WmYzYTlXNFNRRzYxakswUzcKYlNGVk9LUHQ3TDUvT21pK05icStsSnB5MmdCTnFU
+TWt0U0k0YklPUlY1aUpWWkRWU21qVkFnTUJBQUU9Ci0tLS0tRU5EIFJTQSBQVUJM
+SUMgS0VZLS0tLS0Kc2VydmljZS1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtF
+WS0tLS0tCk1JR0pBb0dCQU5YOVJobHRobkZkbXFXQVRsNGJ4dTBrR0UyNWlYcm83
+VzFvM05GV3Q4cG8rL25oU080aVZRMHQKWVZzSGwyZEdGSVNKcWxqK3FaTXh1emVL
+ZmNwV3dHQnZMR1FaTDZJYUxJMUxkWSt6YzBaNjFFdWx5dXRFWFl5bAo3djFwRWN2
+dGFJSDhuRXdzQnZlU1ZWUVJ5cFI4b3BnbXhmMWFKWmdzZVdMSE5hZ0JwNW81QWdN
+QkFBRT0KLS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQppbnRyb2R1Y3Rpb24t
+cG9pbnQgbTVibGd0dHRscWc1Mno1emJlcW82a2ViczQ0bG1wd2EKaXAtYWRkcmVz
+cyAxNzYuMzEuMzUuMTQ5Cm9uaW9uLXBvcnQgNDQzCm9uaW9uLWtleQotLS0tLUJF
+R0lOIFJTQSBQVUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTnVORFlobFF2RG9TNEFa
+cE5nUkFLUmZhRjAzVWFSM0JrSXo3UC8zOVB4NjZueDc1bG5wQ1pMYwpkSHl4cGJu
+UWp2ekE0UzdjUUVnYXUyQkgyeUtzU1NBL3ZXUHk4OVJBWUVhaUV2TlZQS1hRWmNw
+cnY0WXdmejU0CmRuY2VJNG51NVFQM0E3SUpkSi9PYTlHMklhdHA3OVBlTzJkN2Rq
+L3pzWFNKMkxvRXgyZWRBZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0t
+LS0tCnNlcnZpY2Uta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpN
+SUdKQW9HQkFLbU9KbXB6ZVphVkZXaVlkMms5SHY1TWpidUY0eDBUKzlXclV4Z041
+N2o2Uk1CVFZQZ0lVM2hUCkdCY3dwWjR2NDduNitIbVg4VHFNTFlVZkc1bTg1cm8x
+SHNKMWVObnh2cW9iZVFVMW13TXdHdDMwbkJ6Y0F2NzMKbWFsYmlYRkxiOVdsK1hl
+OTBRdXZhbjZTenhERkx5STFPbzA2aGVUeVZwQ3d0QVVvejhCVEFnTUJBQUU9Ci0t
+LS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0KCg==
+-----END MESSAGE-----
+signature
+-----BEGIN SIGNATURE-----
+s9Z0zWHsoPuqLw3GOwA6cv68vCFybnitIK4vD0MbNKF5qrOfKydZzGWfN09PuShy
+H8Gr6aBYoz7HmlD7KyeGz9xdwRdouP+LW5YREOCORuwYnu5chWtB4iVJ0N1tIzSp
+nHIs1lSrV7Ux2WQ3qSVj505fTGSCmaQRBX726ZlTPW0=
+-----END SIGNATURE-----
+
+.
+650 OK
+"""
+
 # NEWCONSENSUS event from v0.2.1.30.
 
 NEWCONSENSUS_EVENT = """650+NEWCONSENSUS
@@ -798,6 +866,26 @@ class TestEvents(unittest.TestCase):
     self.assertEqual('b3oeducbhjmbqmgw2i3jtz4fekkrinwj', event.descriptor_id)
     self.assertEqual(HSDescReason.NOT_FOUND, event.reason)
 
+  def test_hs_desc_content_event(self):
+    event = _get_event(HS_DESC_CONTENT_EVENT)
+
+    self.assertTrue(isinstance(event, stem.response.events.HSDescContentEvent))
+    self.assertEqual('facebookcorewwwi', event.address)
+    self.assertEqual('riwvyw6njgvs4koel4heqs7w4bssnmlw', event.descriptor_id)
+    self.assertEqual('$8A30C9E8F5954EE286D29BD65CADEA6991200804~YorkshireTOR', event.directory)
+    self.assertEqual('8A30C9E8F5954EE286D29BD65CADEA6991200804', event.directory_fingerprint)
+    self.assertEqual('YorkshireTOR', event.directory_nickname)
+
+    desc = event.descriptor
+    self.assertEqual('riwvyw6njgvs4koel4heqs7w4bssnmlw', desc.descriptor_id)
+    self.assertEqual(2, desc.version)
+    self.assertTrue('MIGJAoGBALf' in desc.permanent_key)
+    self.assertEqual('vnb2j6ftvkvghypd4yyypsl3qmpjyq3j', desc.secret_id_part)
+    self.assertEqual(datetime.datetime(2015, 3, 13, 19, 0, 0), desc.published)
+    self.assertEqual([2, 3], desc.protocol_versions)
+    self.assertEqual(3, len(desc.introduction_points()))
+    self.assertTrue('s9Z0zWHsoPu' in desc.signature)
+
   def test_newdesc_event(self):
     event = _get_event(NEWDESC_SINGLE)
     expected_relays = (('B3FA3110CC6F42443F039220C134CBD2FC4F0493', 'Sakura'),)



More information about the tor-commits mailing list