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

atagar at torproject.org atagar at torproject.org
Tue Mar 4 00:00:23 UTC 2014


commit d5eabee949f3bbee347db11525978be45b00725c
Author: Damian Johnson <atagar at torproject.org>
Date:   Mon Mar 3 15:59:17 2014 -0800

    Support for HS_DESC events
    
    Adding support for tor's now HS_DESC events...
    
      https://gitweb.torproject.org/torspec.git/commitdiff/a67ac4d
      https://trac.torproject.org/10807
---
 stem/__init__.py             |   42 ++++++++++++++++++++++++++++++++++++++++++
 stem/control.py              |    3 ++-
 stem/response/events.py      |   33 +++++++++++++++++++++++++++++++++
 stem/version.py              |    2 ++
 test/unit/response/events.py |   26 ++++++++++++++++++++++++++
 5 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 2663b45..ff344c8 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -392,6 +392,32 @@ Library for working with the tor process.
   **RELAY**       relay token bucket
   **ORCONN**      bucket used for OR connections
   =============== ===========
+
+.. data:: HSDescAction (enum)
+
+  Action beeing taken in a HS_DESC event.
+
+  =============== ===========
+  HSDescAction    Description
+  =============== ===========
+  **REQUESTED**   uncached hidden service descriptor is being requested
+  **RECEIVED**    hidden service descriptor has been retrieved
+  **IGNORE**      fetched descriptor was ignored because we already have its v0 descriptor
+  **FAILED**      we were unable to retrieve the descriptor
+  =============== ===========
+
+.. data:: HSAuth (enum)
+
+  Type of authentication being used for a HS_DESC event.
+
+  ================= ===========
+  HSAuth            Description
+  ================= ===========
+  **NO_AUTH**       no authentication
+  **BASIC_AUTH**    general hidden service authentication
+  **STEALTH_AUTH**  authentication method that hides service activity from unauthorized clients
+  **UNKNOWN**       unrecognized method of authentication
+  ================= ===========
 """
 
 __version__ = '1.1.1-dev'
@@ -429,6 +455,8 @@ __all__ = [
   "CircClosureReason",
   "CircEvent",
   "HiddenServiceState",
+  "HSAuth",
+  "HSDescAction",
   "RelayEndReason",
   "StreamStatus",
   "StreamClosureReason",
@@ -736,3 +764,17 @@ TokenBucket = stem.util.enum.UppercaseEnum(
   "RELAY",
   "ORCONN",
 )
+
+HSDescAction = stem.util.enum.UppercaseEnum(
+  "REQUESTED",
+  "RECEIVED",
+  "IGNORE",
+  "FAILED",
+)
+
+HSAuth = stem.util.enum.UppercaseEnum(
+  "NO_AUTH",
+  "BASIC_AUTH",
+  "STEALTH_AUTH",
+  "UNKNOWN",
+)
diff --git a/stem/control.py b/stem/control.py
index 9dff578..b0832ed 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -122,6 +122,7 @@ providing its own for interacting at a higher level.
   **DESCCHANGED**       :class:`stem.response.events.DescChangedEvent`
   **ERR**               :class:`stem.response.events.LogEvent`
   **GUARD**             :class:`stem.response.events.GuardEvent`
+  **HS_DIR**            :class:`stem.response.events.HSDescEvent`
   **INFO**              :class:`stem.response.events.LogEvent`
   **NEWCONSENSUS**      :class:`stem.response.events.NewConsensusEvent`
   **NEWDESC**           :class:`stem.response.events.NewDescEvent`
@@ -2589,7 +2590,7 @@ def _parse_circ_path(path):
 def _parse_circ_entry(entry):
   """
   Parses a single relay's 'LongName' or 'ServerID'. See the
-  :func:`~_stem.control._parse_circ_path` function for more information.
+  :func:`~stem.control._parse_circ_path` function for more information.
 
   :param str entry: relay information to be parsed
 
diff --git a/stem/response/events.py b/stem/response/events.py
index 931127d..082ecb1 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -570,6 +570,38 @@ class GuardEvent(Event):
     self._log_if_unrecognized('status', stem.GuardStatus)
 
 
+class HSDescEvent(Event):
+  """
+  Event triggered when we fetch a hidden service descriptor that presently isn't in our cache.
+
+  The HS_DESC event was introduced in tor version 0.2.5.2-alpha.
+
+  :var stem.HSDescAction action: what is happening with the descriptor
+  :var str address: hidden service address
+  :var stem.HSAuth authentication: service's authentication method
+  :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 str descriptor_id: descriptor identifier
+  """
+
+  _VERSION_ADDED = stem.version.Requirement.EVENT_HS_DESC
+  _POSITIONAL_ARGS = ("action", "address", "authentication", "directory", "descriptor_id")
+
+  def _parse(self):
+    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's directory doesn't match a ServerSpec: %s" % self)
+
+    self._log_if_unrecognized('action', stem.HSDescAction)
+    self._log_if_unrecognized('authentication', stem.HSAuth)
+
+
 class LogEvent(Event):
   """
   Tor logging event. These are the most visible kind of event since, by
@@ -1164,6 +1196,7 @@ EVENT_TYPE_TO_CLASS = {
   "DESCCHANGED": DescChangedEvent,
   "ERR": LogEvent,
   "GUARD": GuardEvent,
+  "HS_DESC": HSDescEvent,
   "INFO": LogEvent,
   "NEWCONSENSUS": NewConsensusEvent,
   "NEWDESC": NewDescEvent,
diff --git a/stem/version.py b/stem/version.py
index d0dae78..e3ba69b 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -47,6 +47,7 @@ easily parsed and compared, for instance...
   **EVENT_CIRC_BW**                     CIRC_BW events
   **EVENT_CELL_STATS**                  CELL_STATS events
   **EVENT_TB_EMPTY**                    TB_EMPTY events
+  **EVENT_HS_DESC**                     HS_DESC events
   **EXTENDCIRCUIT_PATH_OPTIONAL**       EXTENDCIRCUIT queries can omit the path if the circuit is zero
   **FEATURE_EXTENDED_EVENTS**           'EXTENDED_EVENTS' optional feature
   **FEATURE_VERBOSE_NAMES**             'VERBOSE_NAMES' optional feature
@@ -349,6 +350,7 @@ Requirement = stem.util.enum.Enum(
   ("EVENT_CIRC_BW", Version('0.2.5.2-alpha')),
   ("EVENT_CELL_STATS", Version('0.2.5.2-alpha')),
   ("EVENT_TB_EMPTY", Version('0.2.5.2-alpha')),
+  ("EVENT_HS_DESC", Version('0.2.5.2-alpha')),
   ("EXTENDCIRCUIT_PATH_OPTIONAL", Version("0.2.2.9")),
   ("FEATURE_EXTENDED_EVENTS", Version("0.2.2.1-alpha")),
   ("FEATURE_VERBOSE_NAMES", Version("0.2.2.1-alpha")),
diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index 23e682e..28de639 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -192,6 +192,12 @@ GUARD_NEW = "650 GUARD ENTRY $36B5DBA788246E8369DBAF58577C6BC044A9A374 NEW"
 GUARD_GOOD = "650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A GOOD"
 GUARD_BAD = "650 GUARD ENTRY $5D0034A368E0ABAF663D21847E1C9B6CFA09752A=caerSidi BAD"
 
+HS_DESC_EVENT = "650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
+$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1 b3oeducbhjmbqmgw2i3jtz4fekkrinwj"
+
+HS_DESC_NO_DESC_ID = "650 HS_DESC REQUESTED ajhb7kljbiru65qo NO_AUTH \
+$67B2BDA4264D8A189D9270E28B1D30A262838243"
+
 # NEWCONSENSUS event from v0.2.1.30.
 
 NEWCONSENSUS_EVENT = """650+NEWCONSENSUS
@@ -730,6 +736,26 @@ class TestEvents(unittest.TestCase):
     self.assertEqual("caerSidi", event.endpoint_nickname)
     self.assertEqual(GuardStatus.BAD, event.status)
 
+  def test_hs_desc_event(self):
+    event = _get_event(HS_DESC_EVENT)
+
+    self.assertTrue(isinstance(event, stem.response.events.HSDescEvent))
+    self.assertEqual(HS_DESC_EVENT.lstrip("650 "), str(event))
+    self.assertEqual(HSDescAction.REQUESTED, event.action)
+    self.assertEqual("ajhb7kljbiru65qo", event.address)
+    self.assertEqual(HSAuth.NO_AUTH, event.authentication)
+    self.assertEqual("$67B2BDA4264D8A189D9270E28B1D30A262838243=europa1", event.directory)
+    self.assertEqual("67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory_fingerprint)
+    self.assertEqual("europa1", event.directory_nickname)
+    self.assertEqual("b3oeducbhjmbqmgw2i3jtz4fekkrinwj", event.descriptor_id)
+
+    event = _get_event(HS_DESC_NO_DESC_ID)
+
+    self.assertEqual("$67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory)
+    self.assertEqual("67B2BDA4264D8A189D9270E28B1D30A262838243", event.directory_fingerprint)
+    self.assertEqual(None, event.directory_nickname)
+    self.assertEqual(None, event.descriptor_id)
+
   def test_newdesc_event(self):
     event = _get_event(NEWDESC_SINGLE)
     expected_relays = (("B3FA3110CC6F42443F039220C134CBD2FC4F0493", "Sakura"),)



More information about the tor-commits mailing list