701 Commits

Author SHA1 Message Date
Damian Johnson
6af714a4bd Rewrite ONION_CLIENT_AUTH_VIEW parsing
Mig5's parser was a fine proof of concept but stem parses everything within the
spec. Our list_hidden_service_auth() method now returns either a credential or
dictionary of credentials based on if we're requesting a single service or
everything.
2020-08-06 16:56:39 -07:00
Damian Johnson
4f55589f83 Add Sphinx sphinx_autodoc_typehints plugin
Our methods document parater types twice...

  def my_method(my_arg: str) => None:
    """
    Dummy method.

    :param str my_arg: sample argument
    """

The method signature and :param: reStructured tag both cite our my_arg type.
By using Sphinx's sphinx_autodoc_typehints plugin we can drop our parameter
types...

  https://github.com/agronholm/sphinx-autodoc-typehints

Deduplication aside this makes our API docs look nicer by stripping Python
type hints from our signatures. In other words...

  stem.util.system.is_available(command: str, cached: bool = True) → bool

  Parameters:

    command (str) -- command to search for
    cached (bool) -- makes use of available cached results if True

... becomes...

  stem.util.system.is_available(command, cached=True)

  Parameters:

    command (str) -- command to search for
    cached (bool) -- makes use of available cached results if True
2020-05-16 17:33:01 -07:00
Damian Johnson
a22ebbda06 Disable buggy cross referencing
Sphinx attempts to create cross-references for attribute and variable names...

  https://github.com/sphinx-doc/sphinx/issues/2549
  https://github.com/sphinx-doc/sphinx/issues/3866

This results in numerous warnings of the form...

  WARNING: more than one target found for cross-reference 'digest'

Adapting a patch from the tickets above. Sphinx deprecated override_domain(),
so using add_domain() instead...

  https://www.sphinx-doc.org/en/2.0/extdev/appapi.html#sphinx.application.Sphinx.override_domain
2020-05-14 16:18:22 -07:00
Damian Johnson
0354799f58 Ignore __all__ attributes when bulding site
Sphinx emits the following warnings...

  WARNING: missing attribute mentioned in :members: or __all__: module stem, attribute directory
  WARNING: missing attribute mentioned in :members: or __all__: module stem, attribute process
  WARNING: missing attribute mentioned in :members: or __all__: module stem.descriptor, attribute remote
  WARNING: missing attribute mentioned in :members: or __all__: module stem.response, attribute getinfo
  WARNING: missing attribute mentioned in :members: or __all__: module stem.response, attribute getconf
  WARNING: missing attribute mentioned in :members: or __all__: module stem.response, attribute authchallenge
  WARNING: missing attribute mentioned in :members: or __all__: module stem.util, attribute lru_cache
  WARNING: missing attribute mentioned in :members: or __all__: module stem.util, attribute ordereddict
  WARNING: missing attribute mentioned in :members: or __all__: module stem.util, attribute term
  WARNING: missing attribute mentioned in :members: or __all__: module stem.util, attribute test_tools

These submodules all exist, but importlib.import_module() does not have
attributes corresponding to them unless we've transitively imported its code
prior to Sphinx's attempt to reference it.

Honestly I don't fully grok the nuance behind how importlib works, but this
configuration flag resolves these warnings so calling it good.
2020-05-13 18:07:47 -07:00
Damian Johnson
f99633ca62 Drop explicit __init__ from automodule
The only visible difference I can see between including '__init__' verses
excluding it for automodule declarations is class names. If we include it the
page cites classes as...

  stem.descriptor.__init__.DigestHash

... whereas without it the page renders...

  stem.descriptor.DigestHash

The second is obviously correct so dropping the suffix.
2020-05-13 15:56:07 -07:00
Damian Johnson
63eb5136fa Fix favicon links
The favicon on our website works, but the build warns...

  WARNING: logo file 'logo.png' does not exist
  WARNING: favicon file 'favicon.png' does not exist
2020-05-12 16:16:44 -07:00
Damian Johnson
06aba288d1 Fix smartquotes configuration
Sphinx deprecated the configuration option we used to disable smartquotes...

  RemovedInSphinx17Warning: html_use_smartypants option is deprecated. Smart
  quotes are on by default; if you want to disable or customize them, use the
  smart_quotes option in docutils.conf.

Despite this warning the actual configuration name they went with doesn't have
an underscore...

  https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-smartquotes
2020-05-12 16:06:49 -07:00
Damian Johnson
c78e068cef Fix autodoc configuration
Autodoc deprecated its autodoc_default_flags configuration in version 1.8. As a
result with new Sphinx versions our API documentation is empty. Moving to their
new configuration mechanism...

  https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_flags
2020-05-11 16:28:05 -07:00
Damian Johnson
c84b5c8fc3 Sphinx fixes
Just correcting a few minor sphinx warnings...

  /home/atagar/Desktop/stem/docs/download.rst:165: WARNING: Inline interpreted text or phrase reference start-string without end-string.
  /home/atagar/Desktop/stem/docs/tutorials/east_of_the_sun.rst:65: WARNING: Literal block ends without a blank line; unexpected unindent.
  /home/atagar/Desktop/stem/docs/tutorials/mirror_mirror_on_the_wall.rst:2: WARNING: Duplicate explicit target name: "benchmark script".
  /home/atagar/Desktop/stem/docs/tutorials/mirror_mirror_on_the_wall.rst:2: WARNING: Duplicate explicit target name: "benchmark script".
2020-05-11 16:19:57 -07:00
Damian Johnson
13e401de58 Include mypy among faq's static checks 2020-05-11 14:32:15 -07:00
Damian Johnson
cfdc193df9 Changelog entry 2020-03-30 20:09:22 -07:00
Damian Johnson
7a0a8dd8d4 Extrainfo descriptor transport lines fail validation
Oops! Transport lines effectviely never appear aside from raw bridge
descriptors (which we never see), so I didn't have a live example to
test with.

Now we have one. DocTor's descriptor validation check is failing with...

  03/05/2020 00:35:33 [WARNING] Unable to retrieve the extrainfo descriptors: Transport line has a malformed address: transport obfs4 [2001:985:e77:5:fd34:f56b:c2d1:e98c]:10394 cert=dJ/a+vnP+eFv7FDaVUqWCVlyrqf8FlOva2YAEkDUwiGQuorZf4Oc6FXSdyn8b4pUmZj/WA,iat-mode=0

Caught thanks to GeKo.
2020-03-04 17:56:56 -08:00
Damian Johnson
c1c4e7a288 Remove deprecated modules
We're dropping stem.descriptor's reader and export module due to lack of use...

  * I wrote stem.descriptor.reader at Karsten's suggestion to read descriptors
    from disk, and track when those on-disk files change. The design seemed to
    be for usage within CollecTor, but never was.

    In practice stem.descriptor.from_file() provides a simpler mechanism to
    read descriptors form disk.

  * stem.descriptor.export was contributed by a university student in Stem's
    early days. I've never used it nor found anyone else who does.

    This module serializes descriptors to a CSV, which is moot since
    descriptors already have a string representation we can read and
    write...

      with open('/path/to/descriptor', 'w') as descriptor_file:
        descriptor_file.write(str(my_descriptor))

      my_descriptor = stem.descriptor.from_file('/path/to/descriptor', 'server-descriptor 1.0')
2020-01-31 15:03:03 -08:00
Damian Johnson
fb40101e44 Ignore BrokenPipeError when closing
Our jenkins tests our failing pretty routinely with python 3.7. It turns out
that this is my bad - unlike python 2.x the socket module frequently (but
inconsistently) raises a BrokenPipeError when closing a file based socket.

Why would anyone care that the socket they're closing isn't working?
That's... kinda the point. Oh well - ignoring these exceptions.
2020-01-30 14:26:43 -08:00
Damian Johnson
bdd376bd9e Update FAQ concering compatible python versions 2020-01-05 13:27:40 -08:00
Damian Johnson
7cfd6f71ec Stem release 1.8.0 2019-12-29 15:10:13 -08:00
Damian Johnson
ff2bd2948e Revise CollecTor example
The example we provided did not deduplicate relays, causing us to cite relays
repeatedly for each descriptor they published.
2019-12-29 15:10:08 -08:00
Damian Johnson
f450fce04c Missing changelog entry 2019-12-28 14:16:35 -08:00
Damian Johnson
7852f528d3 Change bug tracker links to github
Tor is preparing to move to Gitlab. Rather than follow it I'm moving to GitHub.
Just finished migraing our tickets so now updating the bug tracker links.
2019-12-20 16:51:08 -08:00
hannelorestetx
947c0c1150 Update links in tutorials 2019-12-12 15:47:33 -08:00
Damian Johnson
9b8d769260 Expand event listener tutorial
George had a great question today about catching event listener exceptions...

  https://lists.torproject.org/pipermail/tor-dev/2019-November/014092.html

Expanding our event listener tutorial to dive a bit deeper into this topic.
2019-11-27 16:39:14 -08:00
Damian Johnson
bd5c8aaaa9 Move arrived_at from the Event class to ControlMessage
Our Event's arrived_at attribute has a couple wrinkes...

  * This timestamp reflects when the event was **parsed** rather than
    **received**, so it becomes inaccurate if our event loop gets bogged down.

  * There's nothing event specific about this attribute. It should apply to all
    controller messages.

As such moving this up to the parent class. I first spotted the bug via the
following script...

  import time

  from stem.control import EventType, Controller

  def slow_handler(event):
    print("processing a BW event that's %0.1f seconds old" % (time.time() - event.arrived_at))
    time.sleep(5)

  with Controller.from_port() as controller:
    controller.authenticate()
    controller.add_event_listener(slow_handler, EventType.BW)
    time.sleep(10)

Previously this produced...

  % python demo.py
  processing a BW event that's 0.0 seconds old
  processing a BW event that's 0.0 seconds old
  processing a BW event that's 0.0 seconds old
  processing a BW event that's 0.0 seconds old

... and now we get...

  % python demo.py
  processing a BW event that's 0.4 seconds old
  processing a BW event that's 4.4 seconds old
  processing a BW event that's 8.4 seconds old
2019-11-27 15:49:32 -08:00
Damian Johnson
5b1fc94f6c Validate mandatory fields are present 2019-08-24 17:12:50 -07:00
Damian Johnson
f307434824 Rename stem.descriptor.hidden_service_descriptor module
Dropping the redundant '_descriptor' suffix from this module name. The old name
still works as an alias.
2019-08-21 15:23:18 -07:00
Damian Johnson
acfcc58b01 Missing changelog entry 2019-08-19 17:16:18 -07:00
Damian Johnson
66279fc842 Update dizum's address
Alex recently migrated dizum. Updating ourselves to the new address...

  https://trac.torproject.org/projects/tor/ticket/31406
  https://gitweb.torproject.org/tor.git/commit/?id=5a1c3e4
2019-08-19 17:15:53 -07:00
Damian Johnson
6a44d21134 Add CollecTor to our descriptor tutorial
Replacing our deprecated stem.descriptor.reader example with usage of our new
collector module.
2019-08-17 13:22:53 -07:00
Damian Johnson
a4ecadb65c Add stem.descriptor.get_bandwidth_file()
Tor now provides bandwidth files over its DirPort. Adding our corresponding
function to download them...

  https://trac.torproject.org/projects/tor/ticket/26902

From what I can tell these statistics are available in practice for our next
hour's consensus, but not the present one...

  atagar@morrigan:~$ curl -s 128.31.0.34:9131/tor/status-vote/next/bandwidth | wc -l
  8987

  atagar@morrigan:~$ curl -s 128.31.0.34:9131/tor/status-vote/current/bandwidth | wc -l
  0
2019-05-30 11:09:16 -07:00
Damian Johnson
8f1f69b752 Drop website republication script
While authoring stem's website I used this script to automatically
republish changes. Years ago I wised up and swapped to cron...

  stem@staticiforme:~$ crontab -l
  */5 * * * * /home/stem/build_site

  stem@staticiforme:~$ cat /home/stem/build_site
  #!/bin/sh

  export PATH=/home/stem/bin:$PATH
  export PYTHONPATH=/home/stem/lib/python

  cd /home/stem/stem
  git pull

  cd docs
  make clean
  make html

  sudo -u mirroradm static-master-update-component stem.torproject.org
  echo "$(date)" > /home/stem/site_last_built

This republication script was specifically for our own site and hasn't been
used in years. Dropping the script in response to...

  https://trac.torproject.org/projects/tor/ticket/30593
2019-05-27 16:25:20 -07:00
Damian Johnson
a69ebcae61 Include directory module in API docs
Adding the directory module to our api docs, and fixing a few table of contents
issues...

  /home/atagar/Desktop/stem/docs/api/directory.rst: WARNING: document isn't included in any toctree
  /home/atagar/Desktop/stem/docs/contents.rst: WARNING: document isn't included in any toctree
  /home/atagar/Desktop/stem/docs/tutorials/examples/check_digests.rst: WARNING: document isn't included in any toctree
  /home/atagar/Desktop/stem/docs/tutorials/examples/download_descriptor.rst: WARNING: document isn't included in any toctree

The last outstanding one (contents.rst) is for the table of contents itself,
and adding it causes a circular reference warning...

  /home/atagar/Desktop/stem/docs/contents.rst: WARNING: circular toctree references detected, ignoring: contents <- contents

Not quite sure what sphinx wants us to do about that one so leaving it alone.
2019-05-26 12:12:48 -07:00
Damian Johnson
1451ee967a Fix 'invalid escape sequence' warnings
Python 3.6 is deprecating invalid escape sequences [1][2], and as such
pycodestyle 2.5.0 generates warnings for them [3]...

  * /home/atagar/Desktop/stem/stem/descriptor/bandwidth_file.py
    line 264  - W605 invalid escape sequence '\*'        | :var dict measurements: **\*** mapping of relay fingerprints to their
    line 267  - W605 invalid escape sequence '\*'        | :var dict header: **\*** header metadata
    line 268  - W605 invalid escape sequence '\*'        | :var datetime timestamp: **\*** time when these metrics were published
    line 269  - W605 invalid escape sequence '\*'        | :var str version: **\*** document format version
    line 294  - W605 invalid escape sequence '\*'        | **\*** attribute is either required when we're parsed with validation or has

The trick is that there's two layers of escaping at play...

  * For Python '\*' is not a valid escape sequence, and as such as a string
    it's equivilant to '\\*'...

    >>> '\*' == '\\*'
    True

  * For Sphinx and regexes '\*' is meaningful. All the 'invalid escapes' cited
    by pycodestyle are for those.

Simple to fix. This replaces all invalid escape sequences with their valid
counterpart.

[1] https://docs.python.org/3/whatsnew/3.6.html#deprecated-python-behavior
[2] https://bugs.python.org/issue27364
[3] https://trac.torproject.org/projects/tor/ticket/27270
2019-05-26 11:34:33 -07:00
teor
a39cecedd6 shellcheck: Fix argument quoting issues in docs/republish
Closes ticket 30953.
2019-05-24 11:56:45 -07:00
Damian Johnson
87cea952a2 Fix ExitPolicy thread safety bug
Interesting catch from juga! I don't have a repro for the stacktrace they cite,
but the only way our input_rules could potentially be None is if two threads
attempt to parse the input_rules at the same time.

Creating a local reference for the input_rules to avoid this while remaining
lock-free...

  https://trac.torproject.org/projects/tor/ticket/29899
2019-05-08 11:09:51 -07:00
Illia Volochii
f4c40e7a73 Update PyPI links 2019-04-17 13:38:07 -07:00
Damian Johnson
f8c830205f Note ed25519 improvement in the changelog
Yikes. Illia's patch is phenominal, really the only really worth adding is the
changelog entry.
2019-04-10 11:02:58 -07:00
Illia Volochii
f58577435c
Start using the cryptography package for verifying Ed25519 signatures 2019-04-10 00:23:34 +03:00
Damian Johnson
9b1897578a Add a get_start_time() method
On reflection, process initialization time is cachable whereas uptime is not.
Adding a get_start_time() method, not only for its own usefulness but because
it inherrantly lets us make get_uptime() a cached method.
2019-04-03 10:15:41 -07:00
Damian Johnson
0081c9a612 Add a get_uptime() method
Taking advantage of our new getinfo option for determining the tor process
runtime.

  https://trac.torproject.org/projects/tor/ticket/25132
  https://gitweb.torproject.org/torspec.git/commit/?id=e9ef624
2019-04-02 11:03:02 -07:00
Damian Johnson
53ef191a08 Support HSFETCH for v3 hidden services
Tor recently added HSFETCH support for v3 services...

  https://trac.torproject.org/projects/tor/ticket/25417
  https://gitweb.torproject.org/torspec.git/commit/?id=34518e1

Leveraging this new capability takes nothing more than
providing the longer hidden service v3 address to the
command. This is neat since it means all we need to do
on our end is stop rejecting v3 addresses.

Our only use of is_valid_hidden_service_address() is
get_hidden_service_descriptor(), so simply adjusting our
helper to recognize both v2 and v3 addresses.
2019-03-03 15:22:57 -08:00
Damian Johnson
85e96a0a29 Adjust safecookie faq wording
Couple small tweaks suggested by wagon:

  https://trac.torproject.org/projects/tor/ticket/28300#comment:11
2019-03-01 16:27:44 -08:00
Damian Johnson
0fc61ddb1d Skip autocompletion for non-interactive interpreter
Sadly I forget where it was pointed out, but invoking the control port via
shell is a *lot* faster than stem...

  #!/bin/bash -e

  cmd="$@"
  pass="ControlPortPassword"

  function test_tor() {
      echo "$1" >&3
      sed "/^250 OK\r$/q" <&3
      echo QUIT >&3
      exec 3<&-
  }

  exec 3<>/dev/tcp/127.0.0.1/9051
  echo AUTHENTICATE \"$pass\" >&3
  read -u 3
  test_tor "$cmd"

  ====================

  atagar@morrigan:~$ time ./bench.sh 'GETINFO version' 1>/dev/null

  real	0m0.007s
  user	0m0.004s
  sys	0m0.003s

  ====================

  atagar@morrigan:~$ time tor-prompt --run 'GETINFO version' 1>/dev/null

  real	0m0.186s
  user	0m0.072s
  sys	0m0.030s

Generally speaking this is expected. Spinning up an interpreter takes time. But
in doing a quick investigation realized this is quite a bit slower than it
needs to be...

  total tor-prompt runtime          0.186 seconds
  --------------------------------------------------------
  python interpreter startup        0.016 seconds (9%)
  import statements                 0.079 seconds (42%)
  check if tor is running           0.014 seconds (8%)
  connect to tor                    0.009 seconds (5%)
  autocompete setup                 0.065 seconds (34%)
  invoke tor controller command     0.003 seconds (2%)

Autocompletion is only relevant when the user is presented with an interactive
interpreter. If we're merely invoking a command it's pointless.

So TL;DR: tor-prompt is now ~34% faster when used to invoke controller commands.
2019-03-01 16:25:10 -08:00
Damian Johnson
2cd7bff3bf Demonstrate how to use SAFECOOKIE authentication
Wonderful demo for authenticating using SAFECOOKIE by hand (thanks wagon!).

  https://trac.torproject.org/projects/tor/ticket/28300#comment:9
2019-02-27 14:42:37 -08:00
Damian Johnson
3e2b7a3b0d Add Vanguard and Bushel to examples
Listing a couple projects I've been meaning to take a peek at. Only took a
cursory glance but seems Mike and Iain did fantastic jobs.

I also hoped to list SelekTOR [1] somewhere. I don't know much about it, but
sounds like an interesting GUI project. However, it's java (and by extension
doesn't use stem) so I can't list it on the examples page. I have a separate
section for alternate language libraries but it's not that either, so guess I
don't have a spot to plop it. Oh well.

[1] https://www.dazzleships.net/selektor-for-linux/
2019-02-07 11:10:22 -08:00
Damian Johnson
07a6eebb30 Default 'version_flavor' attribute to 'ns'
Tor adjusted its spec to make the flavor optional, and explicitly state that if
it is not present it should default to 'ns'...

  https://gitweb.torproject.org/torspec.git/commit/?id=d97f8d980be01bda3f6122fc6220406f4592a717
2019-01-31 11:25:48 -08:00
Damian Johnson
52b1370e80 Download gzip compressed descriptors by default
Good point from starlight that we should default to downloading compressed
rather than plaintext descriptors...

  https://trac.torproject.org/projects/tor/ticket/29186

I purposefully chose a plaintext default because when I added Stem
compression support tor had relability issues with it...

  https://trac.torproject.org/projects/tor/ticket/9379

... but that hasn't been the case for years. DocTor has been downloading
compressed descriptors since 2015 so it's well past time we took some
confidence in changing the default.

  https://gitweb.torproject.org/doctor.git/commit/?id=a8e954f
2019-01-30 16:19:18 -08:00
Damian Johnson
bf49f7dddf Generate BandwidthFile api docs 2019-01-20 17:43:58 -08:00
Damian Johnson
46a12277ac Missing changelog entry 2019-01-14 10:40:36 -08:00
Damian Johnson
bf267fe1d1 Merge version 1.7.1 hotfix 2018-12-26 15:07:44 -08:00
Taylor Yu
991291cd72 Stem release 1.7.1
Hotfix release requested by Nick incorporating commit 0eb8fda...

https://trac.torproject.org/projects/tor/ticket/28731#comment:18
2018-12-26 14:57:40 -08:00
Damian Johnson
3e3d9bd5c3 Descriptor digest example
Waste not, want not. I wrote this demo script for my recent status report
(https://blog.atagar.com/november2018/), but on reflection it makes a good
example for how to use our new digest methods.
2018-12-11 10:18:58 -08:00