Support multiple devices

master
Roman Zeyde 6 years ago
parent 9cf73f677a
commit 385fc9457b
No known key found for this signature in database
GPG Key ID: 87CAE5FA46917CBB

@ -21,6 +21,11 @@ def _verify_support(identity):
class FakeDevice(interface.Device): class FakeDevice(interface.Device):
"""Connection to TREZOR device.""" """Connection to TREZOR device."""
@classmethod
def package_name(cls):
"""Python package name."""
return 'fake-device-agent'
def connect(self): def connect(self):
"""Return "dummy" connection.""" """Return "dummy" connection."""
log.critical('NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!') log.critical('NEVER USE THIS CODE FOR REAL-LIFE USE-CASES!!!')

@ -20,6 +20,11 @@ def _verify_support(identity, ecdh):
class KeepKey(trezor.Trezor): class KeepKey(trezor.Trezor):
"""Connection to KeepKey device.""" """Connection to KeepKey device."""
@classmethod
def package_name(cls):
"""Python package name (at PyPI)."""
return 'keepkey-agent'
@property @property
def _defs(self): def _defs(self):
from . import keepkey_defs from . import keepkey_defs

@ -36,6 +36,11 @@ def _convert_public_key(ecdsa_curve_name, result):
class LedgerNanoS(interface.Device): class LedgerNanoS(interface.Device):
"""Connection to Ledger Nano S device.""" """Connection to Ledger Nano S device."""
@classmethod
def package_name(cls):
"""Python package name (at PyPI)."""
return 'ledger-agent'
def connect(self): def connect(self):
"""Enumerate and connect to the first USB HID interface.""" """Enumerate and connect to the first USB HID interface."""
try: try:

@ -34,6 +34,11 @@ def _is_open_tty(stream):
class Trezor(interface.Device): class Trezor(interface.Device):
"""Connection to TREZOR device.""" """Connection to TREZOR device."""
@classmethod
def package_name(cls):
"""Python package name (at PyPI)."""
return 'trezor-agent'
@property @property
def _defs(self): def _defs(self):
from . import trezor_defs from . import trezor_defs

@ -11,7 +11,6 @@ See these links for more details:
import argparse import argparse
import contextlib import contextlib
import functools import functools
import pkg_resources
import logging import logging
import os import os
import re import re
@ -19,6 +18,7 @@ import subprocess
import sys import sys
import time import time
import pkg_resources
import semver import semver
@ -237,11 +237,19 @@ def run_agent(device_type):
def main(device_type): def main(device_type):
"""Parse command-line arguments.""" """Parse command-line arguments."""
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
agent_package = device_type.package_name()
resources_map = {r.key: r for r in pkg_resources.require(agent_package)}
resources = [resources_map[agent_package], resources_map['libagent']]
versions = '\n'.join('{}={}'.format(r.key, r.version) for r in resources)
parser.add_argument('--version', help='print the version info',
action='version', version=versions)
subparsers = parser.add_subparsers(title='Action', dest='action') subparsers = parser.add_subparsers(title='Action', dest='action')
subparsers.required = True subparsers.required = True
p = subparsers.add_parser('init', p = subparsers.add_parser('init',
help='Initialize hardware-based GnuPG identity') help='initialize hardware-based GnuPG identity')
p.add_argument('user_id') p.add_argument('user_id')
p.add_argument('-e', '--ecdsa-curve', default='nist256p1') p.add_argument('-e', '--ecdsa-curve', default='nist256p1')
p.add_argument('-t', '--time', type=int, default=int(time.time())) p.add_argument('-t', '--time', type=int, default=int(time.time()))
@ -249,15 +257,9 @@ def main(device_type):
p.add_argument('-s', '--subkey', default=False, action='store_true') p.add_argument('-s', '--subkey', default=False, action='store_true')
p.set_defaults(func=run_init) p.set_defaults(func=run_init)
p = subparsers.add_parser('unlock', help='Unlock the hardware device') p = subparsers.add_parser('unlock', help='unlock the hardware device')
p.add_argument('-v', '--verbose', default=0, action='count') p.add_argument('-v', '--verbose', default=0, action='count')
p.set_defaults(func=run_unlock) p.set_defaults(func=run_unlock)
trezoragent_ver = pkg_resources.require('trezor-agent')[0].version
libagent_ver = pkg_resources.require('libagent')[0].version
ver_str = '%(prog)s ' + trezoragent_ver + ', libagent ' + libagent_ver
parser.add_argument('--version', help='Print the version info',
action='version', version=ver_str)
args = parser.parse_args() args = parser.parse_args()
return args.func(device_type=device_type, args=args) return args.func(device_type=device_type, args=args)

@ -4,7 +4,6 @@ import functools
import io import io
import logging import logging
import os import os
import pkg_resources
import re import re
import subprocess import subprocess
import sys import sys
@ -12,6 +11,7 @@ import tempfile
import threading import threading
import configargparse import configargparse
import pkg_resources
from .. import device, formats, server, util from .. import device, formats, server, util
from . import client, protocol from . import client, protocol
@ -56,16 +56,17 @@ def _to_unicode(s):
return s return s
def create_agent_parser(): def create_agent_parser(device_type):
"""Create an ArgumentParser for this tool.""" """Create an ArgumentParser for this tool."""
p = configargparse.ArgParser(default_config_files=['~/.ssh/agent.config']) p = configargparse.ArgParser(default_config_files=['~/.ssh/agent.config'])
p.add_argument('-v', '--verbose', default=0, action='count') p.add_argument('-v', '--verbose', default=0, action='count')
trezoragent_ver = pkg_resources.require('trezor-agent')[0].version agent_package = device_type.package_name()
libagent_ver = pkg_resources.require('libagent')[0].version resources_map = {r.key: r for r in pkg_resources.require(agent_package)}
ver_str = '%(prog)s ' + trezoragent_ver + ', libagent ' + libagent_ver resources = [resources_map[agent_package], resources_map['libagent']]
parser.add_argument('--version', help='Print the version info', versions = '\n'.join('{}={}'.format(r.key, r.version) for r in resources)
action='version', version=ver_str) p.add_argument('--version', help='print the version info',
action='version', version=versions)
curve_names = [name for name in formats.SUPPORTED_CURVES] curve_names = [name for name in formats.SUPPORTED_CURVES]
curve_names = ', '.join(sorted(curve_names)) curve_names = ', '.join(sorted(curve_names))
@ -74,9 +75,9 @@ def create_agent_parser():
help='specify ECDSA curve name: ' + curve_names) help='specify ECDSA curve name: ' + curve_names)
p.add_argument('--timeout', p.add_argument('--timeout',
default=UNIX_SOCKET_TIMEOUT, type=float, default=UNIX_SOCKET_TIMEOUT, type=float,
help='Timeout for accepting SSH client connections') help='timeout for accepting SSH client connections')
p.add_argument('--debug', default=False, action='store_true', p.add_argument('--debug', default=False, action='store_true',
help='Log SSH protocol messages for debugging.') help='log SSH protocol messages for debugging.')
g = p.add_mutually_exclusive_group() g = p.add_mutually_exclusive_group()
g.add_argument('-s', '--shell', default=False, action='store_true', g.add_argument('-s', '--shell', default=False, action='store_true',
@ -196,7 +197,7 @@ class JustInTimeConnection(object):
@handle_connection_error @handle_connection_error
def main(device_type): def main(device_type):
"""Run ssh-agent using given hardware client factory.""" """Run ssh-agent using given hardware client factory."""
args = create_agent_parser().parse_args() args = create_agent_parser(device_type=device_type).parse_args()
util.setup_logging(verbosity=args.verbose) util.setup_logging(verbosity=args.verbose)
public_keys = None public_keys = None

Loading…
Cancel
Save