mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-16 04:29:08 +00:00
add transport for bridge
This commit is contained in:
parent
58711df5d3
commit
a527456db5
6
cmdtr.py
6
cmdtr.py
@ -12,7 +12,7 @@ from trezorlib.protobuf_json import pb2json
|
|||||||
def parse_args(commands):
|
def parse_args(commands):
|
||||||
parser = argparse.ArgumentParser(description='Commandline tool for Trezor devices.')
|
parser = argparse.ArgumentParser(description='Commandline tool for Trezor devices.')
|
||||||
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Prints communication to device')
|
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Prints communication to device')
|
||||||
parser.add_argument('-t', '--transport', dest='transport', choices=['usb', 'serial', 'pipe', 'socket'], default='usb', help="Transport used for talking with the device")
|
parser.add_argument('-t', '--transport', dest='transport', choices=['usb', 'serial', 'pipe', 'socket', 'bridge'], default='usb', help="Transport used for talking with the device")
|
||||||
parser.add_argument('-p', '--path', dest='path', default='', help="Path used by the transport (usually serial port)")
|
parser.add_argument('-p', '--path', dest='path', default='', help="Path used by the transport (usually serial port)")
|
||||||
# parser.add_argument('-dt', '--debuglink-transport', dest='debuglink_transport', choices=['usb', 'serial', 'pipe', 'socket'], default='usb', help="Debuglink transport")
|
# parser.add_argument('-dt', '--debuglink-transport', dest='debuglink_transport', choices=['usb', 'serial', 'pipe', 'socket'], default='usb', help="Debuglink transport")
|
||||||
# parser.add_argument('-dp', '--debuglink-path', dest='debuglink_path', default='', help="Path used by the transport (usually serial port)")
|
# parser.add_argument('-dp', '--debuglink-path', dest='debuglink_path', default='', help="Path used by the transport (usually serial port)")
|
||||||
@ -67,6 +67,10 @@ def get_transport(transport_string, path, **kwargs):
|
|||||||
from trezorlib.transport_socket import SocketTransportClient
|
from trezorlib.transport_socket import SocketTransportClient
|
||||||
return SocketTransportClient(path, **kwargs)
|
return SocketTransportClient(path, **kwargs)
|
||||||
|
|
||||||
|
if transport_string == 'bridge':
|
||||||
|
from trezorlib.transport_bridge import BridgeTransport
|
||||||
|
return BridgeTransport(path, **kwargs)
|
||||||
|
|
||||||
if transport_string == 'fake':
|
if transport_string == 'fake':
|
||||||
from trezorlib.transport_fake import FakeTransport
|
from trezorlib.transport_fake import FakeTransport
|
||||||
return FakeTransport(path, **kwargs)
|
return FakeTransport(path, **kwargs)
|
||||||
|
@ -4,13 +4,14 @@ sys.path = ['../',] + sys.path
|
|||||||
from trezorlib.transport_pipe import PipeTransport
|
from trezorlib.transport_pipe import PipeTransport
|
||||||
from trezorlib.transport_hid import HidTransport
|
from trezorlib.transport_hid import HidTransport
|
||||||
from trezorlib.transport_socket import SocketTransportClient
|
from trezorlib.transport_socket import SocketTransportClient
|
||||||
|
from trezorlib.transport_bridge import BridgeTransport
|
||||||
|
|
||||||
devices = HidTransport.enumerate()
|
devices = HidTransport.enumerate()
|
||||||
|
|
||||||
if len(devices) > 0:
|
if len(devices) > 0:
|
||||||
if devices[0][1] != None:
|
if devices[0][1] != None:
|
||||||
print 'Using TREZOR'
|
print 'Using TREZOR'
|
||||||
TRANSPORT = HidTransport
|
TRANSPORT = BridgeTransport
|
||||||
TRANSPORT_ARGS = (devices[0],)
|
TRANSPORT_ARGS = (devices[0],)
|
||||||
TRANSPORT_KWARGS = {'debug_link': False}
|
TRANSPORT_KWARGS = {'debug_link': False}
|
||||||
DEBUG_TRANSPORT = HidTransport
|
DEBUG_TRANSPORT = HidTransport
|
||||||
|
@ -41,10 +41,10 @@ __version__='0.0.5'
|
|||||||
__author__='Paul Dovbush <dpp@dpp.su>'
|
__author__='Paul Dovbush <dpp@dpp.su>'
|
||||||
|
|
||||||
|
|
||||||
import json # py2.6+ TODO: add support for other JSON serialization modules
|
import json
|
||||||
from google.protobuf.descriptor import FieldDescriptor as FD
|
from google.protobuf.descriptor import FieldDescriptor as FD
|
||||||
import binascii
|
import binascii
|
||||||
|
import types_pb2 as types
|
||||||
|
|
||||||
class ParseError(Exception): pass
|
class ParseError(Exception): pass
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ _ftype2js = {
|
|||||||
#FD.TYPE_MESSAGE: pb2json, #handled specially
|
#FD.TYPE_MESSAGE: pb2json, #handled specially
|
||||||
FD.TYPE_BYTES: lambda x: binascii.hexlify(x),
|
FD.TYPE_BYTES: lambda x: binascii.hexlify(x),
|
||||||
FD.TYPE_UINT32: int,
|
FD.TYPE_UINT32: int,
|
||||||
FD.TYPE_ENUM: int,
|
FD.TYPE_ENUM: str,
|
||||||
FD.TYPE_SFIXED32: float,
|
FD.TYPE_SFIXED32: float,
|
||||||
FD.TYPE_SFIXED64: float,
|
FD.TYPE_SFIXED64: float,
|
||||||
FD.TYPE_SINT32: int,
|
FD.TYPE_SINT32: int,
|
||||||
@ -132,7 +132,7 @@ _js2ftype = {
|
|||||||
# FD.TYPE_MESSAGE: json2pb, #handled specially
|
# FD.TYPE_MESSAGE: json2pb, #handled specially
|
||||||
FD.TYPE_BYTES: lambda x: binascii.unhexlify(x),
|
FD.TYPE_BYTES: lambda x: binascii.unhexlify(x),
|
||||||
FD.TYPE_UINT32: int,
|
FD.TYPE_UINT32: int,
|
||||||
FD.TYPE_ENUM: int,
|
FD.TYPE_ENUM: lambda x: getattr(types, x),
|
||||||
FD.TYPE_SFIXED32: float,
|
FD.TYPE_SFIXED32: float,
|
||||||
FD.TYPE_SFIXED64: float,
|
FD.TYPE_SFIXED64: float,
|
||||||
FD.TYPE_SINT32: int,
|
FD.TYPE_SINT32: int,
|
||||||
|
@ -19,7 +19,7 @@ class Transport(object):
|
|||||||
def _close(self):
|
def _close(self):
|
||||||
raise NotImplementedException("Not implemented")
|
raise NotImplementedException("Not implemented")
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
raise NotImplementedException("Not implemented")
|
raise NotImplementedException("Not implemented")
|
||||||
|
|
||||||
def _read(self):
|
def _read(self):
|
||||||
@ -51,7 +51,7 @@ class Transport(object):
|
|||||||
def write(self, msg):
|
def write(self, msg):
|
||||||
ser = msg.SerializeToString()
|
ser = msg.SerializeToString()
|
||||||
header = struct.pack(">HL", mapping.get_type(msg), len(ser))
|
header = struct.pack(">HL", mapping.get_type(msg), len(ser))
|
||||||
self._write("##%s%s" % (header, ser))
|
self._write("##%s%s" % (header, ser), msg)
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
if not self.ready_to_read():
|
if not self.ready_to_read():
|
||||||
@ -73,6 +73,9 @@ class Transport(object):
|
|||||||
|
|
||||||
def _parse_message(self, data):
|
def _parse_message(self, data):
|
||||||
(msg_type, data) = data
|
(msg_type, data) = data
|
||||||
|
if msg_type == 'protobuf':
|
||||||
|
return data
|
||||||
|
else:
|
||||||
inst = mapping.get_class(msg_type)()
|
inst = mapping.get_class(msg_type)()
|
||||||
inst.ParseFromString(data)
|
inst.ParseFromString(data)
|
||||||
return inst
|
return inst
|
||||||
|
74
trezorlib/transport_bridge.py
Normal file
74
trezorlib/transport_bridge.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
'''BridgeTransport implements transport TREZOR Bridge (aka trezord).'''
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import requests
|
||||||
|
import protobuf_json
|
||||||
|
import json
|
||||||
|
import mapping
|
||||||
|
from transport import Transport
|
||||||
|
import messages_pb2 as proto
|
||||||
|
|
||||||
|
TREZORD_HOST = 'http://localhost:21324'
|
||||||
|
CONFIG_URL = 'https://mytrezor.com/data/plugin/config_signed.bin'
|
||||||
|
|
||||||
|
class BridgeTransport(Transport):
|
||||||
|
def __init__(self, device, *args, **kwargs):
|
||||||
|
|
||||||
|
r = requests.get(CONFIG_URL)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('Could not fetch config from %s' % CONFIG_URL)
|
||||||
|
|
||||||
|
config = binascii.unhexlify(r.text)
|
||||||
|
|
||||||
|
r = requests.post(TREZORD_HOST + '/configure', data=config)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('trezord: Could not configure')
|
||||||
|
|
||||||
|
r = requests.get(TREZORD_HOST + '/enumerate')
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('trezord: Could not enumerate devices')
|
||||||
|
enum = r.json()
|
||||||
|
|
||||||
|
if len(enum) < 1:
|
||||||
|
raise Exception('trezord: No devices found')
|
||||||
|
|
||||||
|
self.path = enum[0]['path']
|
||||||
|
self.session = None
|
||||||
|
self.response = None
|
||||||
|
|
||||||
|
super(BridgeTransport, self).__init__(device, *args, **kwargs)
|
||||||
|
|
||||||
|
def _open(self):
|
||||||
|
r = requests.post(TREZORD_HOST + '/acquire/%s' % self.path)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('trezord: Could not acquire session')
|
||||||
|
resp = r.json()
|
||||||
|
self.session = resp['session']
|
||||||
|
|
||||||
|
def _close(self):
|
||||||
|
r = requests.post(TREZORD_HOST + '/release/%s' % self.session)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('trezord: Could not release session')
|
||||||
|
else:
|
||||||
|
self.session = None
|
||||||
|
|
||||||
|
def ready_to_read(self):
|
||||||
|
return self.response != None
|
||||||
|
|
||||||
|
def _write(self, msg, protobuf_msg):
|
||||||
|
cls = protobuf_msg.__class__.__name__
|
||||||
|
msg = protobuf_json.pb2json(protobuf_msg)
|
||||||
|
payload = '{"type": "%s","message": %s}' % (cls, json.dumps(msg))
|
||||||
|
r = requests.post(TREZORD_HOST + '/call/%s' % self.session, data=payload)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception('trezord: Could not write message')
|
||||||
|
else:
|
||||||
|
self.response = r.json()
|
||||||
|
|
||||||
|
def _read(self):
|
||||||
|
if self.response == None:
|
||||||
|
raise Exception('No response stored')
|
||||||
|
cls = getattr(proto, self.response['type'])
|
||||||
|
inst = cls()
|
||||||
|
pb = protobuf_json.json2pb(inst, self.response['message'])
|
||||||
|
return ('protobuf', pb)
|
@ -17,7 +17,7 @@ class FakeTransport(Transport):
|
|||||||
def ready_to_read(self):
|
def ready_to_read(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _read(self):
|
def _read(self):
|
||||||
|
@ -96,7 +96,7 @@ class HidTransport(Transport):
|
|||||||
def ready_to_read(self):
|
def ready_to_read(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
msg = bytearray(msg)
|
msg = bytearray(msg)
|
||||||
while len(msg):
|
while len(msg):
|
||||||
# Report ID, data padded to 63 bytes
|
# Report ID, data padded to 63 bytes
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
'''TransportFake implements fake wire transport over local named pipe.
|
'''PipeTransport implements fake wire transport over local named pipe.
|
||||||
Use this transport for talking with trezor simulator.'''
|
Use this transport for talking with trezor simulator.'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -42,7 +42,7 @@ class PipeTransport(Transport):
|
|||||||
rlist, _, _ = select([self.read_f], [], [], 0)
|
rlist, _, _ = select([self.read_f], [], [], 0)
|
||||||
return len(rlist) > 0
|
return len(rlist) > 0
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
try:
|
try:
|
||||||
self.write_f.write(msg)
|
self.write_f.write(msg)
|
||||||
self.write_f.flush()
|
self.write_f.flush()
|
||||||
|
@ -22,7 +22,7 @@ class SerialTransport(Transport):
|
|||||||
rlist, _, _ = select([self.serial], [], [], 0)
|
rlist, _, _ = select([self.serial], [], [], 0)
|
||||||
return len(rlist) > 0
|
return len(rlist) > 0
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
try:
|
try:
|
||||||
self.serial.write(msg)
|
self.serial.write(msg)
|
||||||
self.serial.flush()
|
self.serial.flush()
|
||||||
|
@ -29,7 +29,7 @@ class SocketTransportClient(Transport):
|
|||||||
rlist, _, _ = select([self.socket], [], [], 0)
|
rlist, _, _ = select([self.socket], [], [], 0)
|
||||||
return len(rlist) > 0
|
return len(rlist) > 0
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
self.socket.sendall(msg)
|
self.socket.sendall(msg)
|
||||||
|
|
||||||
def _read(self):
|
def _read(self):
|
||||||
@ -89,7 +89,7 @@ class SocketTransport(Transport):
|
|||||||
return self.ready_to_read()
|
return self.ready_to_read()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _write(self, msg):
|
def _write(self, msg, protobuf_msg):
|
||||||
if self.filelike:
|
if self.filelike:
|
||||||
# None on disconnected client
|
# None on disconnected client
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user