mirror of
https://github.com/romanz/amodem.git
synced 2026-05-10 05:17:38 +08:00
trezor-agent: automatic support for git identity
The agent uses local 'git config', and chooses the url marked as "trezor = true".
This commit is contained in:
@@ -83,20 +83,15 @@ class Client(object):
|
|||||||
return (r, s)
|
return (r, s)
|
||||||
|
|
||||||
|
|
||||||
def _split(s, *parts):
|
_identity_regexp = re.compile(''.join([
|
||||||
return re.match(regexp, s).groups()
|
|
||||||
|
|
||||||
|
|
||||||
_parts = [
|
|
||||||
'^'
|
'^'
|
||||||
r'(?:(?P<proto>.*)://)?',
|
r'(?:(?P<proto>.*)://)?',
|
||||||
r'(?:(?P<user>.*)@)?',
|
r'(?:(?P<user>.*)@)?',
|
||||||
r'(?P<host>.*?)',
|
r'(?P<host>.*?)',
|
||||||
r'(?::(?P<port>\w*))?',
|
r'(?::(?P<port>\w*))?',
|
||||||
r'(?:/(?P<path>.*))?',
|
r'(?P<path>/.*)?',
|
||||||
'$'
|
'$'
|
||||||
]
|
]))
|
||||||
_identity_regexp = re.compile(''.join(_parts))
|
|
||||||
|
|
||||||
def _string_to_identity(s):
|
def _string_to_identity(s):
|
||||||
m = _identity_regexp.match(s)
|
m = _identity_regexp.match(s)
|
||||||
@@ -117,13 +112,14 @@ def _identity_to_string(identity):
|
|||||||
if identity.port:
|
if identity.port:
|
||||||
result.append(':' + identity.port)
|
result.append(':' + identity.port)
|
||||||
if identity.path:
|
if identity.path:
|
||||||
result.append('/' + identity.path)
|
result.append(identity.path)
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
|
|
||||||
def _get_address(identity):
|
def _get_address(identity):
|
||||||
index = struct.pack('<L', identity.index)
|
index = struct.pack('<L', identity.index)
|
||||||
addr = index + _identity_to_string(identity)
|
addr = index + _identity_to_string(identity)
|
||||||
|
log.debug('address string: %r', addr)
|
||||||
digest = formats.hashfunc(addr).digest()
|
digest = formats.hashfunc(addr).digest()
|
||||||
s = io.BytesIO(bytearray(digest))
|
s = io.BytesIO(bytearray(digest))
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from . import trezor
|
from . import trezor
|
||||||
from . import server
|
from . import server
|
||||||
@@ -10,12 +12,27 @@ import logging
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def identity_from_gitconfig():
|
||||||
|
out = subprocess.check_output(args='git config --list --local'.split())
|
||||||
|
config = dict(line.split('=', 1) for line in out.split())
|
||||||
|
|
||||||
|
name_regex = re.compile(r'^remote\..*\.trezor$')
|
||||||
|
names = [k for k in config if name_regex.match(k)]
|
||||||
|
assert len(names) == 1
|
||||||
|
name, = names
|
||||||
|
|
||||||
|
name, _ = name.rsplit('.', 1) # extract TREZOR's remote name
|
||||||
|
url = config[name + '.url']
|
||||||
|
assert url.startswith('git@')
|
||||||
|
return url.replace(':', '/') # git SSH URLs use ':' for relative paths
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
fmt = '%(asctime)s %(levelname)-12s %(message)-100s [%(filename)s:%(lineno)d]'
|
fmt = '%(asctime)s %(levelname)-12s %(message)-100s [%(filename)s:%(lineno)d]'
|
||||||
p = argparse.ArgumentParser()
|
p = argparse.ArgumentParser()
|
||||||
p.add_argument('-v', '--verbose', default=0, action='count')
|
p.add_argument('-v', '--verbose', default=0, action='count')
|
||||||
|
|
||||||
p.add_argument('identity', type=str,
|
p.add_argument('identity', type=str, default=None,
|
||||||
help='proto://[user@]host[:port][/path]')
|
help='proto://[user@]host[:port][/path]')
|
||||||
|
|
||||||
g = p.add_mutually_exclusive_group()
|
g = p.add_mutually_exclusive_group()
|
||||||
@@ -28,14 +45,23 @@ def main():
|
|||||||
args = p.parse_args()
|
args = p.parse_args()
|
||||||
|
|
||||||
levels = [logging.WARNING, logging.INFO, logging.DEBUG]
|
levels = [logging.WARNING, logging.INFO, logging.DEBUG]
|
||||||
level = levels[min(args.verbose, len(levels))]
|
level = levels[min(args.verbose, len(levels) - 1)]
|
||||||
logging.basicConfig(level=level, format=fmt)
|
logging.basicConfig(level=level, format=fmt)
|
||||||
|
|
||||||
with trezor.Client(factory=trezor.TrezorLibrary) as client:
|
with trezor.Client(factory=trezor.TrezorLibrary) as client:
|
||||||
identity = client.get_identity(label=args.identity)
|
|
||||||
|
label = args.identity
|
||||||
|
command = args.command
|
||||||
|
|
||||||
|
if label == 'git':
|
||||||
|
label = identity_from_gitconfig()
|
||||||
|
if command:
|
||||||
|
command = ['git'] + command
|
||||||
|
|
||||||
|
identity = client.get_identity(label=label)
|
||||||
public_key = client.get_public_key(identity=identity)
|
public_key = client.get_public_key(identity=identity)
|
||||||
|
|
||||||
command, use_shell = args.command, False
|
use_shell = False
|
||||||
if args.connect:
|
if args.connect:
|
||||||
to_ascii = lambda s: s.encode('ascii')
|
to_ascii = lambda s: s.encode('ascii')
|
||||||
command = ['ssh', to_ascii(identity.host)]
|
command = ['ssh', to_ascii(identity.host)]
|
||||||
@@ -44,6 +70,7 @@ def main():
|
|||||||
if identity.port:
|
if identity.port:
|
||||||
command += ['-p', to_ascii(identity.port)]
|
command += ['-p', to_ascii(identity.port)]
|
||||||
log.debug('SSH connect: %r', command)
|
log.debug('SSH connect: %r', command)
|
||||||
|
command = args.command + command
|
||||||
|
|
||||||
if args.shell:
|
if args.shell:
|
||||||
command, use_shell = os.environ['SHELL'], True
|
command, use_shell = os.environ['SHELL'], True
|
||||||
|
|||||||
Reference in New Issue
Block a user