Server Descriptor
*****************

Parsing for Tor server descriptors, which contains the infrequently
changing information about a Tor relay (contact information, exit
policy, public keys, etc). This information is provided from a few
sources…

* The control port via ‘GETINFO desc/*’ queries.

* The ‘cached-descriptors’ file in Tor’s data directory.

* Archived descriptors provided by CollecTor.

* Directory authorities and mirrors via their DirPort.

**Module Overview:**

   ServerDescriptor - Tor server descriptor.
     |- RelayDescriptor - Server descriptor for a relay.
     |  +- make_router_status_entry - Creates a router status entry for this descriptor.
     |
     |- BridgeDescriptor - Scrubbed server descriptor for a bridge.
     |  |- is_scrubbed - checks if our content has been properly scrubbed
     |  +- get_scrubbing_issues - description of issues with our scrubbing
     |
     |- digest - calculates the upper-case hex digest value for our content
     |- get_annotations - dictionary of content prior to the descriptor entry
     +- get_annotation_lines - lines that provided the annotations

stem.descriptor.server_descriptor.BridgeDistribution(enum)

   Preferred method of distributing this relay if a bridge.

   New in version 1.6.0.

   +-----------------------+---------------------------------------------------------------------+
   | BridgeDistribution    | Description                                                         |
   +=======================+=====================================================================+
   | **ANY**               | No proference, BridgeDB will pick how the bridge is distributed.    |
   +-----------------------+---------------------------------------------------------------------+
   | **HTTPS**             | Provided via the web interface.                                     |
   +-----------------------+---------------------------------------------------------------------+
   | **EMAIL**             | Provided in response to emails to bridges@torproject.org.           |
   +-----------------------+---------------------------------------------------------------------+
   | **MOAT**              | Provided in interactive menus within Tor Browser.                   |
   +-----------------------+---------------------------------------------------------------------+
   | **HYPHAE**            | Provided via a cryptographic invitation-based system.               |
   +-----------------------+---------------------------------------------------------------------+

class stem.descriptor.server_descriptor.ServerDescriptor(raw_contents, validate=False, annotations=None)

   Bases: "stem.descriptor.Descriptor"

   Common parent for server descriptors.

   Variables:
      * **nickname** (*str*) – ***** relay’s nickname

      * **fingerprint** (*str*) – identity key fingerprint

      * **published** (*datetime*) – ***** time in UTC when this
        descriptor was made

      * **address** (*str*) – ***** IPv4 address of the relay

      * **or_port** (*int*) – ***** port used for relaying

      * **socks_port** (*int*) – ***** port used as client
        (**deprecated**, always **None**)

      * **dir_port** (*int*) – ***** port used for descriptor
        mirroring

      * **platform** (*bytes*) – line with operating system and tor
        version

      * **tor_version** (*stem.version.Version*) – version of tor

      * **operating_system** (*str*) – operating system

      * **uptime** (*int*) – uptime when published in seconds

      * **contact** (*bytes*) – contact information

      * **exit_policy** (*stem.exit_policy.ExitPolicy*) – *****
        stated exit policy

      * **exit_policy_v6** (*stem.exit_policy.MicroExitPolicy*) –
        ***** exit policy for IPv6

      * **bridge_distribution** (*BridgeDistribution*) – *****
        preferred method of providing this relay’s address if a bridge

      * **family** (*set*) – ***** nicknames or fingerprints of
        declared family

      * **average_bandwidth** (*int*) – ***** average rate it’s
        willing to relay in bytes/s

      * **burst_bandwidth** (*int*) – ***** burst rate it’s willing
        to relay in bytes/s

      * **observed_bandwidth** (*int*) – ***** estimated capacity
        based on usage in bytes/s

      * **link_protocols** (*list*) – link protocols supported by
        the relay

      * **circuit_protocols** (*list*) – circuit protocols supported
        by the relay

      * **is_hidden_service_dir** (*bool*) – ***** indicates if the
        relay serves hidden service descriptors

      * **hibernating** (*bool*) – ***** hibernating when published

      * **allow_single_hop_exits** (*bool*) – ***** flag if single
        hop exiting is allowed

      * **allow_tunneled_dir_requests** (*bool*) – ***** flag if
        tunneled directory requests are accepted

      * **extra_info_cache** (*bool*) – ***** flag if a mirror for
        extra-info documents

      * **extra_info_digest** (*str*) – upper-case hex encoded
        digest of our extra-info document

      * **extra_info_sha256_digest** (*str*) – base64 encoded sha256
        digest of our extra-info document

      * **eventdns** (*bool*) – flag for evdns backend
        (**deprecated**, always unset)

      * **ntor_onion_key** (*str*) – base64 key used to encrypt
        EXTEND in the ntor protocol

      * **or_addresses** (*list*) – ***** alternative for our
        address/or_port attributes, each entry is a tuple of the form
        (address (**str**), port (**int**), is_ipv6 (**bool**))

      * **protocols** (*dict*) – mapping of protocols to their
        supported versions

   **Deprecated**, moved to extra-info descriptor…

   Variables:
      * **read_history_end** (*datetime*) – end of the sampling
        interval

      * **read_history_interval** (*int*) – seconds per interval

      * **read_history_values** (*list*) – bytes read during each
        interval

      * **write_history_end** (*datetime*) – end of the sampling
        interval

      * **write_history_interval** (*int*) – seconds per interval

      * **write_history_values** (*list*) – bytes written during
        each interval

   ***** attribute is either required when we’re parsed with
   validation or has a default value, others are left as **None** if
   undefined

   Changed in version 1.5.0: Added the allow_tunneled_dir_requests
   attribute.

   Changed in version 1.6.0: Added the extra_info_sha256_digest,
   protocols, and bridge_distribution attributes.

   Changed in version 1.7.0: Added the is_hidden_service_dir
   attribute.

   Changed in version 1.7.0: Deprecated the hidden_service_dir field,
   it’s never been populated (spec). This field will be removed in
   Stem 2.0.

   digest(hash_type='SHA1', encoding='HEX')

      Digest of this descriptor’s content. These are referenced by…

         * **Consensus**

           * Referer: "RouterStatusEntryV3" **digest** attribute

           * Format: **SHA1/BASE64**

      Changed in version 1.8.0: Added the hash_type and encoding
      arguments.

      Parameters:
         * **hash_type** (*stem.descriptor.DigestHash*) – digest
           hashing algorithm

         * **encoding** (*stem.descriptor.DigestEncoding*) – digest
           encoding

      Returns:
         **hashlib.HASH** or **str** based on our encoding argument

   get_annotations

      Provides content that appeared prior to the descriptor. If this
      comes from the cached-descriptors file then this commonly
      contains content like…

         @downloaded-at 2012-03-18 21:18:29
         @source "173.254.216.66"

      Deprecated since version 1.8.0: Users very rarely read from
      cached descriptor files any longer. This method will be removed
      in Stem 2.x. If you have some need for us to keep this please
      let me know.

      Returns:
         **dict** with the key/value pairs in our annotations

   get_annotation_lines()

      Provides the lines of content that appeared prior to the
      descriptor. This is the same as the "get_annotations()" results,
      but with the unparsed lines and ordering retained.

      Deprecated since version 1.8.0: Users very rarely read from
      cached descriptor files any longer. This method will be removed
      in Stem 2.x. If you have some need for us to keep this please
      let me know.

      Returns:
         **list** with the lines of annotation that came before this
         descriptor

class stem.descriptor.server_descriptor.RelayDescriptor(raw_contents, validate=False, annotations=None, skip_crypto_validation=False)

   Bases: "stem.descriptor.server_descriptor.ServerDescriptor"

   Server descriptor (descriptor specification)

   Variables:
      * **certificate** (*stem.certificate.Ed25519Certificate*) –
        ed25519 certificate

      * **ed25519_certificate** (*str*) – base64 encoded ed25519
        certificate

      * **ed25519_master_key** (*str*) – base64 encoded master key
        for our ed25519 certificate

      * **ed25519_signature** (*str*) – signature of this document
        using ed25519

      * **onion_key** (*str*) – ***** key used to encrypt EXTEND
        cells

      * **onion_key_crosscert** (*str*) – signature generated using
        the onion_key

      * **ntor_onion_key_crosscert** (*str*) – signature generated
        using the ntor-onion-key

      * **ntor_onion_key_crosscert_sign** (*str*) – sign of the
        corresponding ed25519 public key

      * **signing_key** (*str*) – ***** relay’s long-term identity
        key

      * **signature** (*str*) – ***** signature for this descriptor

   ***** attribute is required when we’re parsed with validation

   Changed in version 1.5.0: Added the ed25519_certificate,
   ed25519_master_key, ed25519_signature, onion_key_crosscert,
   ntor_onion_key_crosscert, and ntor_onion_key_crosscert_sign
   attributes.

   Changed in version 1.6.0: Moved from the deprecated pycrypto module
   to cryptography for validating signatures.

   Changed in version 1.6.0: Added the certificate attribute.

   Deprecated since version 1.6.0: Our **ed25519_certificate** is
   deprecated in favor of our new **certificate** attribute. The
   base64 encoded certificate is available via the certificate’s
   **encoded** attribute.

   Changed in version 1.6.0: Added the **skip_crypto_validation**
   constructor argument.

   TYPE_ANNOTATION_NAME = 'server-descriptor'

   classmethod content(attr=None, exclude=(), sign=False, signing_key=None, exit_policy=None)

      Creates descriptor content with the given attributes. Mandatory
      fields are filled with dummy information unless data is
      supplied. This doesn’t yet create a valid signature.

      New in version 1.6.0.

      Parameters:
         * **attr** (*dict*) – keyword/value mappings to be included
           in the descriptor

         * **exclude** (*list*) – mandatory keywords to exclude from
           the descriptor, this results in an invalid descriptor

         * **sign** (*bool*) – includes cryptographic signatures and
           digests if True

      Returns:
         **str** with the content of a descriptor

      Raises:
         * **ImportError** if cryptography is unavailable and sign
           is True

         * **NotImplementedError** if not implemented for this
           descriptor type

   classmethod create(attr=None, exclude=(), validate=True, sign=False, signing_key=None, exit_policy=None)

      Creates a descriptor with the given attributes. Mandatory fields
      are filled with dummy information unless data is supplied. This
      doesn’t yet create a valid signature.

      New in version 1.6.0.

      Parameters:
         * **attr** (*dict*) – keyword/value mappings to be included
           in the descriptor

         * **exclude** (*list*) – mandatory keywords to exclude from
           the descriptor, this results in an invalid descriptor

         * **validate** (*bool*) – checks the validity of the
           descriptor’s content if **True**, skips these checks
           otherwise

         * **sign** (*bool*) – includes cryptographic signatures and
           digests if True

      Returns:
         "Descriptor" subclass

      Raises:
         * **ValueError** if the contents is malformed and validate
           is True

         * **ImportError** if cryptography is unavailable and sign
           is True

         * **NotImplementedError** if not implemented for this
           descriptor type

   digest

      Provides the digest of our descriptor’s content.

      Returns:
         the digest string encoded in uppercase hex

      Raises:
         ValueError if the digest cannot be calculated

   make_router_status_entry()

      Provides a RouterStatusEntryV3 for this descriptor content.

      New in version 1.6.0.

      Returns:
         "RouterStatusEntryV3" that would be in the consensus

class stem.descriptor.server_descriptor.BridgeDescriptor(raw_contents, validate=False, annotations=None)

   Bases: "stem.descriptor.server_descriptor.ServerDescriptor"

   Bridge descriptor (bridge descriptor specification)

   Variables:
      * **ed25519_certificate_hash** (*str*) – sha256 hash of the
        original identity-ed25519

      * **router_digest_sha256** (*str*) – sha256 digest of this
        document

   Changed in version 1.5.0: Added the ed25519_certificate_hash and
   router_digest_sha256 attributes. Also added ntor_onion_key
   (previously this only belonged to unsanitized descriptors).

   TYPE_ANNOTATION_NAME = 'bridge-server-descriptor'

   classmethod content(attr=None, exclude=(), sign=False)

      Creates descriptor content with the given attributes. Mandatory
      fields are filled with dummy information unless data is
      supplied. This doesn’t yet create a valid signature.

      New in version 1.6.0.

      Parameters:
         * **attr** (*dict*) – keyword/value mappings to be included
           in the descriptor

         * **exclude** (*list*) – mandatory keywords to exclude from
           the descriptor, this results in an invalid descriptor

         * **sign** (*bool*) – includes cryptographic signatures and
           digests if True

      Returns:
         **str** with the content of a descriptor

      Raises:
         * **ImportError** if cryptography is unavailable and sign
           is True

         * **NotImplementedError** if not implemented for this
           descriptor type

   digest(hash_type='SHA1', encoding='HEX')

      Digest of this descriptor’s content. These are referenced by…

         * **Consensus**

           * Referer: "RouterStatusEntryV3" **digest** attribute

           * Format: **SHA1/BASE64**

      Changed in version 1.8.0: Added the hash_type and encoding
      arguments.

      Parameters:
         * **hash_type** (*stem.descriptor.DigestHash*) – digest
           hashing algorithm

         * **encoding** (*stem.descriptor.DigestEncoding*) – digest
           encoding

      Returns:
         **hashlib.HASH** or **str** based on our encoding argument

   is_scrubbed()

      Checks if we’ve been properly scrubbed in accordance with the
      bridge descriptor specification. Validation is a moving target
      so this may not be fully up to date.

      Returns:
         **True** if we’re scrubbed, **False** otherwise

   get_scrubbing_issues

      Provides issues with our scrubbing.

      Returns:
         **list** of strings which describe issues we have with our
         scrubbing, this list is empty if we’re properly scrubbed
