Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hex over TCP] - Allows one to exchange data in hexadecimal format #75

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ledgerblue/comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
33 changes: 24 additions & 9 deletions ledgerblue/commTCP.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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)
Expand Down Expand Up @@ -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)