Merge remote-tracking branch 'upstream/master' into doc-enhancements2
This commit is contained in:
@@ -5,7 +5,7 @@ and please let me [know](https://github.com/romanz/trezor-agent/issues/new) if s
|
|||||||
work well for you. If possible:
|
work well for you. If possible:
|
||||||
|
|
||||||
* record the session (e.g. using [asciinema](https://asciinema.org))
|
* record the session (e.g. using [asciinema](https://asciinema.org))
|
||||||
* attach the GPG agent log from `~/.gnupg/{trezor,ledger}/gpg-agent.log`
|
* attach the GPG agent log from `~/.gnupg/{trezor,ledger}/gpg-agent.log` (can be [encrypted](https://keybase.io/romanz))
|
||||||
|
|
||||||
Thanks!
|
Thanks!
|
||||||
|
|
||||||
|
|||||||
@@ -115,3 +115,55 @@ Note that your local SSH configuration may ignore `trezor-agent`, if it has `Ide
|
|||||||
If you are failing to connect, try running:
|
If you are failing to connect, try running:
|
||||||
|
|
||||||
$ trezor-agent -vv user@host -- ssh -vv -oIdentitiesOnly=no user@host
|
$ trezor-agent -vv user@host -- ssh -vv -oIdentitiesOnly=no user@host
|
||||||
|
|
||||||
|
# Start the agent as a systemd unit
|
||||||
|
|
||||||
|
##### 1. Create these files in `~/.config/systemd/user`
|
||||||
|
|
||||||
|
Replace `trezor` with `keepkey` or `ledger` as required.
|
||||||
|
|
||||||
|
###### `trezor-ssh-agent.service`
|
||||||
|
|
||||||
|
````
|
||||||
|
[Unit]
|
||||||
|
Description=trezor-agent SSH agent
|
||||||
|
Requires=trezor-ssh-agent.socket
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=Simple
|
||||||
|
ExecStart=/usr/bin/trezor-agent --foreground --sock-path %t/trezor-agent/S.ssh IDENTITY
|
||||||
|
````
|
||||||
|
|
||||||
|
Replace `IDENTITY` with the identity you used when exporting the public key.
|
||||||
|
|
||||||
|
###### `trezor-ssh-agent.socket`
|
||||||
|
|
||||||
|
````
|
||||||
|
[Unit]
|
||||||
|
Description=trezor-agent SSH agent socket
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=%t/trezor-agent/S.ssh
|
||||||
|
FileDescriptorName=ssh
|
||||||
|
Service=trezor-ssh-agent.service
|
||||||
|
SocketMode=0600
|
||||||
|
DirectoryMode=0700
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
||||||
|
````
|
||||||
|
|
||||||
|
##### 2. Run
|
||||||
|
|
||||||
|
```
|
||||||
|
systemctl --user start trezor-ssh-agent.service trezor-ssh-agent.socket
|
||||||
|
systemctl --user enable trezor-ssh-agent.socket
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 3. Add this line to your `.bashrc` or equivalent file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export SSH_AUTH_SOCK=$(systemctl show --user --property=Listen trezor-ssh-agent.socket | grep -o "/run.*")
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 4. SSH will now automatically use your device key in all terminals.
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class Trezor(interface.Device):
|
|||||||
cli_handler = conn.callback_PinMatrixRequest
|
cli_handler = conn.callback_PinMatrixRequest
|
||||||
|
|
||||||
def new_handler(msg):
|
def new_handler(msg):
|
||||||
|
try:
|
||||||
if _is_open_tty(sys.stdin):
|
if _is_open_tty(sys.stdin):
|
||||||
result = cli_handler(msg) # CLI-based PIN handler
|
result = cli_handler(msg) # CLI-based PIN handler
|
||||||
else:
|
else:
|
||||||
@@ -72,6 +73,9 @@ class Trezor(interface.Device):
|
|||||||
raise self._defs.PinException(
|
raise self._defs.PinException(
|
||||||
None, 'Invalid scrambled PIN: {!r}'.format(result.pin))
|
None, 'Invalid scrambled PIN: {!r}'.format(result.pin))
|
||||||
return result
|
return result
|
||||||
|
except: # noqa
|
||||||
|
conn.init_device()
|
||||||
|
raise
|
||||||
|
|
||||||
conn.callback_PinMatrixRequest = new_handler
|
conn.callback_PinMatrixRequest = new_handler
|
||||||
|
|
||||||
@@ -81,6 +85,7 @@ class Trezor(interface.Device):
|
|||||||
cli_handler = conn.callback_PassphraseRequest
|
cli_handler = conn.callback_PassphraseRequest
|
||||||
|
|
||||||
def new_handler(msg):
|
def new_handler(msg):
|
||||||
|
try:
|
||||||
if self.__class__.cached_passphrase_ack:
|
if self.__class__.cached_passphrase_ack:
|
||||||
log.debug('re-using cached %s passphrase', self)
|
log.debug('re-using cached %s passphrase', self)
|
||||||
return self.__class__.cached_passphrase_ack
|
return self.__class__.cached_passphrase_ack
|
||||||
@@ -95,6 +100,9 @@ class Trezor(interface.Device):
|
|||||||
|
|
||||||
self.__class__.cached_passphrase_ack = ack
|
self.__class__.cached_passphrase_ack = ack
|
||||||
return ack
|
return ack
|
||||||
|
except: # noqa
|
||||||
|
conn.init_device()
|
||||||
|
raise
|
||||||
|
|
||||||
conn.callback_PassphraseRequest = new_handler
|
conn.callback_PassphraseRequest = new_handler
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,11 @@ def run_init(device_type, args):
|
|||||||
homedir = os.path.expanduser('~/.gnupg/{}'.format(device_name))
|
homedir = os.path.expanduser('~/.gnupg/{}'.format(device_name))
|
||||||
log.info('GPG home directory: %s', homedir)
|
log.info('GPG home directory: %s', homedir)
|
||||||
|
|
||||||
check_call(['rm', '-rf', homedir])
|
if os.path.exists(homedir):
|
||||||
|
log.error('GPG home directory %s exists, '
|
||||||
|
'remove it manually if required', homedir)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
check_call(['mkdir', '-p', homedir])
|
check_call(['mkdir', '-p', homedir])
|
||||||
check_call(['chmod', '700', homedir])
|
check_call(['chmod', '700', homedir])
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ def create_agent_parser(device_type):
|
|||||||
g = p.add_mutually_exclusive_group()
|
g = p.add_mutually_exclusive_group()
|
||||||
g.add_argument('-d', '--daemonize', default=False, action='store_true',
|
g.add_argument('-d', '--daemonize', default=False, action='store_true',
|
||||||
help='Daemonize the agent and print its UNIX socket path')
|
help='Daemonize the agent and print its UNIX socket path')
|
||||||
|
g.add_argument('-f', '--foreground', default=False, action='store_true',
|
||||||
|
help='Run agent in foreground with specified UNIX socket path')
|
||||||
g.add_argument('-s', '--shell', default=False, action='store_true',
|
g.add_argument('-s', '--shell', default=False, action='store_true',
|
||||||
help=('run ${SHELL} as subprocess under SSH agent, allowing '
|
help=('run ${SHELL} as subprocess under SSH agent, allowing '
|
||||||
'regular SSH-based tools to be used in the shell'))
|
'regular SSH-based tools to be used in the shell'))
|
||||||
@@ -211,6 +213,17 @@ def _dummy_context():
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
def _get_sock_path(args):
|
||||||
|
sock_path = args.sock_path
|
||||||
|
if not sock_path:
|
||||||
|
if args.foreground:
|
||||||
|
log.error('running in foreground mode requires specifying UNIX socket path')
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sock_path = tempfile.mktemp(prefix='trezor-ssh-agent-')
|
||||||
|
return sock_path
|
||||||
|
|
||||||
|
|
||||||
@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."""
|
||||||
@@ -232,9 +245,7 @@ def main(device_type):
|
|||||||
identity.identity_dict['proto'] = u'ssh'
|
identity.identity_dict['proto'] = u'ssh'
|
||||||
log.info('identity #%d: %s', index, identity.to_string())
|
log.info('identity #%d: %s', index, identity.to_string())
|
||||||
|
|
||||||
sock_path = args.sock_path
|
sock_path = _get_sock_path(args)
|
||||||
if not sock_path:
|
|
||||||
sock_path = tempfile.mktemp(prefix='trezor-ssh-agent-')
|
|
||||||
|
|
||||||
command = args.command
|
command = args.command
|
||||||
context = _dummy_context()
|
context = _dummy_context()
|
||||||
@@ -248,6 +259,8 @@ def main(device_type):
|
|||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
context = daemon.DaemonContext()
|
context = daemon.DaemonContext()
|
||||||
log.info('running the agent as a daemon on %s', sock_path)
|
log.info('running the agent as a daemon on %s', sock_path)
|
||||||
|
elif args.foreground:
|
||||||
|
log.info('running the agent on %s', sock_path)
|
||||||
|
|
||||||
use_shell = bool(args.shell)
|
use_shell = bool(args.shell)
|
||||||
if use_shell:
|
if use_shell:
|
||||||
@@ -258,7 +271,7 @@ def main(device_type):
|
|||||||
conn_factory=lambda: client.Client(device_type()),
|
conn_factory=lambda: client.Client(device_type()),
|
||||||
identities=identities, public_keys=public_keys)
|
identities=identities, public_keys=public_keys)
|
||||||
|
|
||||||
if command or args.daemonize:
|
if command or args.daemonize or args.foreground:
|
||||||
with context:
|
with context:
|
||||||
return run_server(conn=conn, command=command, sock_path=sock_path,
|
return run_server(conn=conn, command=command, sock_path=sock_path,
|
||||||
debug=args.debug, timeout=args.timeout)
|
debug=args.debug, timeout=args.timeout)
|
||||||
|
|||||||
Reference in New Issue
Block a user