commit d5eabee949f3bbee347db11525978be45b00725c Author: Damian Johnson atagar@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"),)
tor-commits@lists.torproject.org