Commit a73e50f2 authored by juga's avatar juga
Browse files

Store relays' ed25519 master key

* RelayList is now a list of RelayNS instead of RouterStatusEntryV3
  to have master_key_ed25519 as an attribute
* create pytest fixture to start Tor with tests
* create test to check master_key_ed25519
parent a9b3967d
from stem.descriptor.router_status_entry import RouterStatusEntryV3
import sbws.util.stem as stem_utils
from stem import Flag
from stem import DescriptorUnavailable
......@@ -11,6 +13,18 @@ from sbws.globals import resolve
log = logging.getLogger(__name__)
class RelayNS(RouterStatusEntryV3):
"""Inherit from RouterStatusEntryV3 and add the attribute
:param str ed25519: the ed25519 master key base 64 encoded.
def __init__(self, ed25519=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if ed25519 is not None:
self.master_key_ed25519 = ed25519
class RelayList:
''' Keeps a list of all relays in the current Tor network and updates it
transparently in the background. Provides useful interfaces for getting
......@@ -68,6 +82,40 @@ class RelayList:
# return [r for r in relays if r.measured is not None]
return [r for r in relays if not r.is_unmeasured]
def relay_ed25519_master_key(self, ns):
"""Obtain ed25519 master key of the relay represented by
the network status relay line.
:param RouterStatusEntryV3 ns: the network status relay
:returns: str, the ed25519 master key base 64 encoded without
trailing '='s.
# In theory this is never going to be the case?
if ns.identifier is None or ns.identifier_type != 'ed25519':
log.debug('Getting microdescriptor to obtain ed25519 identity.')
mdesc = self._controller.get_microdescriptor(ns.fingerprint, None)
if mdesc is not None:
if 'ed25519' in mdesc.identifiers.keys():
ed25519 = mdesc.identifiers['ed25519'].rstrip('=')
log.debug('Found ed25519 master key.')
return ed25519
log.debug('No ed25519 master-key found')
log.debug('Could not get microdescriptor')
# In case Tor can not retrive microdescriptors,
# try with server descriptors.
log.debug('Getting server descriptor to obtain '
'ed25519 master key.')
sdesc = self._controller.get_server_descriptor(ns.fingerprint,
if sdesc is not None:
ed25519 = sdesc.ed25519_master_key().rstrip('=')
log.debug('Found ed25519 master key.')
return ed25519
log.debug('Could not get server descriptor')
return None
log.debug('Relay has already ed25519 master key')
return ns.identifier
def exits_can_exit_to(self, host, port):
Return exits that can MOST LIKELY exit to the given host:port. **host**
......@@ -131,7 +179,14 @@ class RelayList:
def _init_relays(self):
c = self._controller
assert stem_utils.is_controller_okay(c)
return [ns for ns in c.get_network_statuses()]
relays = []
# for each network status relay, obtain the ed25519 master key
# and generate a new list of RelayNS objects
for ns in c.get_network_statuses():
ed25519 = self.relay_ed25519_master_key(ns)
rns = RelayNS(ed25519=ed25519, content=ns._raw_contents)
return relays
def _refresh(self):
self._relays = self._init_relays()
......@@ -2,8 +2,9 @@ from sbws.lib.resultdump import ResultError
from sbws.lib.resultdump import ResultSuccess
from sbws.lib.resultdump import Result
from sbws.lib.resultdump import write_result_to_datadir
from sbws.util.config import get_config
from sbws.util.config import get_config, _get_default_config
from sbws.util.parser import create_parser
import sbws.util.stem as stem_utils
import sbws.core.init
from tempfile import TemporaryDirectory
import pytest
......@@ -61,6 +62,19 @@ def datadir(request):
return D(request.fspath.dirpath("data"))
def start_tor(request, tmpdir):
"""Star Tor or connect to existing socket in a temporal directory."""
conf = _get_default_config()
home = tmpdir.join('.sbws')
conf['paths']['sbws_home'] = home.strpath
controller, _ = stem_utils.init_controller(
if not controller:
controller = stem_utils.launch_tor(conf)
return controller
def parser():
return create_parser()
from sbws.lib.relaylist import RelayList
def test_relaylist_master_key_ed25519(start_tor):
# This test starts tor, so it is slow. And it will fail whenever there are
# network problems
controller = start_tor
rl = RelayList(None, None, controller)
relay = [r for r in rl.relays if r.nickname == 'moria1'][0]
assert relay.fingerprint == '9695DFC35FFEB861329B9F1AB04C46397020CE31'
assert relay.identifier is None
assert relay.master_key_ed25519 == \
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment