2121from .btchipException import *
2222from .ledgerWrapper import wrapCommandAPDU , unwrapResponseAPDU
2323from binascii import hexlify
24- import hid
2524import time
25+ import os
26+ import struct
27+ import socket
28+
29+ try :
30+ import hid
31+ HID = True
32+ except ImportError :
33+ HID = False
2634
2735try :
2836 from smartcard .Exceptions import NoCardException
@@ -165,29 +173,63 @@ def close(self):
165173 pass
166174 self .opened = False
167175
176+ class DongleServer (Dongle ):
177+
178+ def __init__ (self , server , port , debug = False ):
179+ self .server = server
180+ self .port = port
181+ self .debug = debug
182+ self .socket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
183+ try :
184+ self .socket .connect ((self .server , self .port ))
185+ except :
186+ raise BTChipException ("Proxy connection failed" )
187+
188+ def exchange (self , apdu , timeout = 20000 ):
189+ if self .debug :
190+ print ("=> %s" % hexlify (apdu ))
191+ self .socket .send (struct .pack (">I" , len (apdu )))
192+ self .socket .send (apdu )
193+ size = struct .unpack (">I" , self .socket .recv (4 ))[0 ]
194+ response = self .socket .recv (size )
195+ sw = struct .unpack (">H" , self .socket .recv (2 ))[0 ]
196+ if self .debug :
197+ print ("<= %s%.2x" % (hexlify (response ), sw ))
198+ if sw != 0x9000 :
199+ raise BTChipException ("Invalid status %04x" % sw , sw )
200+ return bytearray (response )
201+
202+ def close (self ):
203+ try :
204+ self .socket .close ()
205+ except :
206+ pass
207+
168208def getDongle (debug = False ):
169209 dev = None
170210 hidDevicePath = None
171- ledger = False
172- for hidDevice in hid .enumerate (0 , 0 ):
173- if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x2b7c :
174- hidDevicePath = hidDevice ['path' ]
175- if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x3b7c :
176- hidDevicePath = hidDevice ['path' ]
177- ledger = True
178- if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x4b7c :
179- hidDevicePath = hidDevice ['path' ]
180- ledger = True
181- if hidDevice ['vendor_id' ] == 0x2c97 :
182- hidDevicePath = hidDevice ['path' ]
183- ledger = True
184- if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x1807 :
185- hidDevicePath = hidDevice ['path' ]
211+ ledger = False
212+ if HID :
213+ for hidDevice in hid .enumerate (0 , 0 ):
214+ if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x2b7c :
215+ hidDevicePath = hidDevice ['path' ]
216+ if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x3b7c :
217+ hidDevicePath = hidDevice ['path' ]
218+ ledger = True
219+ if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x4b7c :
220+ hidDevicePath = hidDevice ['path' ]
221+ ledger = True
222+ if hidDevice ['vendor_id' ] == 0x2c97 :
223+ hidDevicePath = hidDevice ['path' ]
224+ ledger = True
225+ if hidDevice ['vendor_id' ] == 0x2581 and hidDevice ['product_id' ] == 0x1807 :
226+ hidDevicePath = hidDevice ['path' ]
186227 if hidDevicePath is not None :
187228 dev = hid .device ()
188229 dev .open_path (hidDevicePath )
189230 dev .set_nonblocking (True )
190231 return HIDDongleHIDAPI (dev , ledger , debug )
232+
191233 if SCARD :
192234 connection = None
193235 for reader in readers ():
@@ -206,5 +248,6 @@ def getDongle(debug=False):
206248 pass
207249 if connection is not None :
208250 return DongleSmartcard (connection , debug )
251+ if (os .getenv ("LEDGER_PROXY_ADDRESS" ) is not None ) and (os .getenv ("LEDGER_PROXY_PORT" ) is not None ):
252+ return DongleServer (os .getenv ("LEDGER_PROXY_ADDRESS" ), int (os .getenv ("LEDGER_PROXY_PORT" )), debug )
209253 raise BTChipException ("No dongle found" )
210-
0 commit comments