1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

add transport for bridge

This commit is contained in:
Pavol Rusnak 2014-07-26 16:27:28 +02:00
parent 58711df5d3
commit a527456db5
10 changed files with 103 additions and 21 deletions

View File

@ -12,7 +12,7 @@ from trezorlib.protobuf_json import pb2json
def parse_args(commands):
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('-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('-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)")
@ -66,6 +66,10 @@ def get_transport(transport_string, path, **kwargs):
if transport_string == 'socket':
from trezorlib.transport_socket import SocketTransportClient
return SocketTransportClient(path, **kwargs)
if transport_string == 'bridge':
from trezorlib.transport_bridge import BridgeTransport
return BridgeTransport(path, **kwargs)
if transport_string == 'fake':
from trezorlib.transport_fake import FakeTransport

View File

@ -4,13 +4,14 @@ sys.path = ['../',] + sys.path
from trezorlib.transport_pipe import PipeTransport
from trezorlib.transport_hid import HidTransport
from trezorlib.transport_socket import SocketTransportClient
from trezorlib.transport_bridge import BridgeTransport
devices = HidTransport.enumerate()
if len(devices) > 0:
if devices[0][1] != None:
print 'Using TREZOR'
TRANSPORT = HidTransport
TRANSPORT = BridgeTransport
TRANSPORT_ARGS = (devices[0],)
TRANSPORT_KWARGS = {'debug_link': False}
DEBUG_TRANSPORT = HidTransport

View File

@ -41,10 +41,10 @@ __version__='0.0.5'
__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
import binascii
import types_pb2 as types
class ParseError(Exception): pass
@ -112,7 +112,7 @@ _ftype2js = {
#FD.TYPE_MESSAGE: pb2json, #handled specially
FD.TYPE_BYTES: lambda x: binascii.hexlify(x),
FD.TYPE_UINT32: int,
FD.TYPE_ENUM: int,
FD.TYPE_ENUM: str,
FD.TYPE_SFIXED32: float,
FD.TYPE_SFIXED64: float,
FD.TYPE_SINT32: int,
@ -132,7 +132,7 @@ _js2ftype = {
# FD.TYPE_MESSAGE: json2pb, #handled specially
FD.TYPE_BYTES: lambda x: binascii.unhexlify(x),
FD.TYPE_UINT32: int,
FD.TYPE_ENUM: int,
FD.TYPE_ENUM: lambda x: getattr(types, x),
FD.TYPE_SFIXED32: float,
FD.TYPE_SFIXED64: float,
FD.TYPE_SINT32: int,

View File

@ -19,7 +19,7 @@ class Transport(object):
def _close(self):
raise NotImplementedException("Not implemented")
def _write(self, msg):
def _write(self, msg, protobuf_msg):
raise NotImplementedException("Not implemented")
def _read(self):
@ -51,7 +51,7 @@ class Transport(object):
def write(self, msg):
ser = msg.SerializeToString()
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):
if not self.ready_to_read():
@ -73,9 +73,12 @@ class Transport(object):
def _parse_message(self, data):
(msg_type, data) = data
inst = mapping.get_class(msg_type)()
inst.ParseFromString(data)
return inst
if msg_type == 'protobuf':
return data
else:
inst = mapping.get_class(msg_type)()
inst.ParseFromString(data)
return inst
def _read_headers(self, read_f):
# Try to read headers until some sane value are detected

View 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)

View File

@ -17,8 +17,8 @@ class FakeTransport(Transport):
def ready_to_read(self):
return False
def _write(self, msg):
def _write(self, msg, protobuf_msg):
pass
def _read(self):
raise NotImplementedException("Not implemented")
raise NotImplementedException("Not implemented")

View File

@ -96,7 +96,7 @@ class HidTransport(Transport):
def ready_to_read(self):
return False
def _write(self, msg):
def _write(self, msg, protobuf_msg):
msg = bytearray(msg)
while len(msg):
# Report ID, data padded to 63 bytes

View File

@ -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.'''
import os
@ -42,7 +42,7 @@ class PipeTransport(Transport):
rlist, _, _ = select([self.read_f], [], [], 0)
return len(rlist) > 0
def _write(self, msg):
def _write(self, msg, protobuf_msg):
try:
self.write_f.write(msg)
self.write_f.flush()

View File

@ -22,7 +22,7 @@ class SerialTransport(Transport):
rlist, _, _ = select([self.serial], [], [], 0)
return len(rlist) > 0
def _write(self, msg):
def _write(self, msg, protobuf_msg):
try:
self.serial.write(msg)
self.serial.flush()
@ -36,4 +36,4 @@ class SerialTransport(Transport):
return (msg_type, self.serial.read(datalen))
except serial.SerialException:
print "Failed to read from device"
raise
raise

View File

@ -29,7 +29,7 @@ class SocketTransportClient(Transport):
rlist, _, _ = select([self.socket], [], [], 0)
return len(rlist) > 0
def _write(self, msg):
def _write(self, msg, protobuf_msg):
self.socket.sendall(msg)
def _read(self):
@ -89,7 +89,7 @@ class SocketTransport(Transport):
return self.ready_to_read()
return False
def _write(self, msg):
def _write(self, msg, protobuf_msg):
if self.filelike:
# None on disconnected client
@ -107,4 +107,4 @@ class SocketTransport(Transport):
except Exception:
print "Failed to read from device"
self._disconnect_client()
return None
return None