diff --git a/ledgerblue/comm.py b/ledgerblue/comm.py index 4843d34..2736e3d 100644 --- a/ledgerblue/comm.py +++ b/ledgerblue/comm.py @@ -46,7 +46,11 @@ if "LEDGER_PROXY_ADDRESS" in os.environ and len(os.environ["LEDGER_PROXY_ADDRESS"]) != 0 and \ "LEDGER_PROXY_PORT" in os.environ and len(os.environ["LEDGER_PROXY_PORT"]) != 0: TCP_PROXY=(os.environ["LEDGER_PROXY_ADDRESS"], int(os.environ["LEDGER_PROXY_PORT"])) - +# Change the format of the commands/responses. +TCP_HEX=None +if "TCP_HEX" in os.environ and len(os.environ["TCP_HEX"]) != 0: + TCP_HEX=os.environ["TCP_HEX"].split(':') + TCP_PROXY = (TCP_HEX[0], int(TCP_HEX[1], 0)) # Force use of MCUPROXY if required PCSC=None if "PCSC" in os.environ and len(os.environ["PCSC"]) != 0: @@ -203,7 +207,7 @@ def getDongle(debug=False, selectCommand=None): elif MCUPROXY is not None: return getDongleHTTP(remote_host=MCUPROXY, debug=debug) elif TCP_PROXY is not None: - return getDongleTCP(server=TCP_PROXY[0], port=TCP_PROXY[1], debug=debug) + return getDongleTCP(server=TCP_PROXY[0], port=TCP_PROXY[1], debug=debug, hex_mode=(TCP_HEX is not None)) dev = None hidDevicePath = None ledger = True diff --git a/ledgerblue/commTCP.py b/ledgerblue/commTCP.py index f09a8b7..3ff786a 100644 --- a/ledgerblue/commTCP.py +++ b/ledgerblue/commTCP.py @@ -18,16 +18,17 @@ """ from .commException import CommException -from binascii import hexlify +from binascii import hexlify, unhexlify import socket import struct class DongleServer(object): - def __init__(self, server, port, debug=False): + def __init__(self, server, port, debug=False, hex_mode=False): self.server = server self.port = port self.debug = debug self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.hex_mode = hex_mode self.opened = True try: self.socket.connect((self.server, self.port)) @@ -39,13 +40,27 @@ def exchange(self, apdu, timeout=20000): def send_apdu(apdu): if self.debug: print("=> %s" % hexlify(apdu)) - self.socket.send(struct.pack(">I", len(apdu))) - self.socket.send(apdu) + + if self.hex_mode: + self.socket.send(hexlify(apdu) + b"\n") + else: + self.socket.send(struct.pack(">I", len(apdu))) + self.socket.send(apdu) def get_data(): - size = struct.unpack(">I", self.socket.recv(4))[0] - response = self.socket.recv(size) - sw = struct.unpack(">H", self.socket.recv(2))[0] + if self.hex_mode: + response = b"" + while not response.endswith(b"\n"): + response += self.socket.recv(1) + response = unhexlify(response[:-1]) + # The SW is included in what we've received. + sw = struct.unpack(">H", response[-2:])[0] + else: + size = struct.unpack(">I", self.socket.recv(4))[0] + response = self.socket.recv(size) + # The SW is to be received. + sw = struct.unpack(">H", self.socket.recv(2))[0] + if self.debug: print("<= %s%.2x" % (hexlify(response), sw)) return (sw, response) @@ -85,5 +100,5 @@ def close(self): pass self.opened = False -def getDongle(server="127.0.0.1", port=9999, debug=False): - return DongleServer(server, port, debug) +def getDongle(server="127.0.0.1", port=9999, debug=False, hex_mode=False): + return DongleServer(server, port, debug, hex_mode)