Switch smartcard interface to pyscard from http://pyscard.sourceforge.net/
pycsc no longer supported API change: utils doesn't export "pycsc" anymore API change: utils.CommandLineArgumentHelper.connect now returns smartcard.CardService.CardService instance API change: cards.generic_card.Card.__init__ and ...can_handle (and therefore cards.new_card_object) now expect CardService or CardConnection instance git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@247 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
326fd9a7be
commit
c92a60fb10
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from utils import pycsc
|
||||
import utils, cards, TLV_utils, sys, binascii, time, traceback
|
||||
|
||||
STATUS_INTERVAL = 10
|
||||
|
@ -21,8 +20,8 @@ if __name__ == "__main__":
|
|||
top_level = ("".join( ["".join(e.split()) for e in arguments] )).split("/")
|
||||
top_level = [binascii.unhexlify(e) for e in top_level]
|
||||
|
||||
pycsc_card = c.connect()
|
||||
card = cards.new_card_object(pycsc_card)
|
||||
card_object = c.connect()
|
||||
card = cards.new_card_object(card_object)
|
||||
cards.generic_card.DEBUG = False
|
||||
|
||||
print >>sys.stderr, "Using %s" % card.DRIVER_NAME
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from utils import pycsc
|
||||
import smartcard
|
||||
import TLV_utils, crypto_utils, utils, binascii, fnmatch, re
|
||||
from utils import C_APDU, R_APDU
|
||||
|
||||
|
@ -122,14 +122,12 @@ class Card:
|
|||
}
|
||||
TLV_OBJECTS[TLV_utils.context_FCI] = TLV_OBJECTS[TLV_utils.context_FCP]
|
||||
|
||||
def __init__(self, card = None, reader = None):
|
||||
if card is None:
|
||||
if reader is None:
|
||||
self.card = pycsc.pycsc(protocol = pycsc.SCARD_PROTOCOL_ANY)
|
||||
else:
|
||||
self.card = pycsc.pycsc(protocol = pycsc.SCARD_PROTOCOL_ANY, reader = reader)
|
||||
else:
|
||||
def __init__(self, card):
|
||||
if not hasattr(card, "connection"):
|
||||
self.card = card
|
||||
else:
|
||||
self.card = card.connection
|
||||
self.cardservice = card
|
||||
|
||||
self._i = 0
|
||||
self.last_apdu = None
|
||||
|
@ -156,7 +154,8 @@ class Card:
|
|||
|
||||
def cmd_reset(self):
|
||||
"""Reset the card."""
|
||||
self.card.reconnect(init=pycsc.SCARD_RESET_CARD)
|
||||
# FIXME
|
||||
raise NotImplementedException
|
||||
|
||||
def cmd_parsetlv(self, start = None, end = None):
|
||||
"Decode the TLV data in the last response, start and end are optional"
|
||||
|
@ -190,14 +189,20 @@ class Card:
|
|||
"parse_tlv": cmd_parsetlv,
|
||||
"show_applications": cmd_show_applications,
|
||||
}
|
||||
|
||||
|
||||
PROTOMAP = {
|
||||
0: smartcard.scard.SCARD_PCI_T0,
|
||||
1: smartcard.scard.SCARD_PCI_T1,
|
||||
}
|
||||
def _real_send(self, apdu):
|
||||
apdu_binary = apdu.render()
|
||||
|
||||
if DEBUG:
|
||||
print ">> " + utils.hexdump(apdu_binary, indent = 3)
|
||||
|
||||
result_binary = self.card.transmit(apdu_binary)
|
||||
apdu_bytes = map(lambda x: ord(x), apdu_binary)
|
||||
data, sw1, sw2 = self.card.transmit(apdu_bytes, protocol=self.PROTOMAP[self.get_protocol()])
|
||||
result_binary = map(lambda x: chr(x), data + [sw1,sw2])
|
||||
result = R_APDU(result_binary)
|
||||
|
||||
self.last_apdu = apdu
|
||||
|
@ -249,8 +254,11 @@ class Card:
|
|||
return self.card.status().get("ATR","")
|
||||
|
||||
def can_handle(cls, card):
|
||||
"""Determine whether this class can handle a given pycsc object."""
|
||||
ATR = card.status().get("ATR","")
|
||||
"""Determine whether this class can handle a given card/connection object."""
|
||||
if hasattr(card, "connection"):
|
||||
ATR = smartcard.util.toASCIIString(card.connection.getATR())
|
||||
else:
|
||||
ATR = smartcard.util.toASCIIString(card.getATR())
|
||||
def match_list(atr, list):
|
||||
for (knownatr, mask) in list:
|
||||
if mask is None:
|
||||
|
@ -310,7 +318,8 @@ class Card:
|
|||
return "%s (SW %s)" % (retval, binascii.b2a_hex(self.last_sw))
|
||||
|
||||
def get_protocol(self):
|
||||
return ((self.card.status()["Protocol"] == pycsc.SCARD_PROTOCOL_T0) and (0,) or (1,))[0]
|
||||
hresult, reader, state, protocol, atr = smartcard.scard.SCardStatus( self.card.component.hcard )
|
||||
return ((protocol == smartcard.scard.SCARD_PROTOCOL_T0) and (0,) or (1,))[0]
|
||||
|
||||
def get_driver_name(self):
|
||||
if len(self.DRIVER_NAME) > 1:
|
||||
|
@ -321,4 +330,8 @@ class Card:
|
|||
|
||||
def close_card(self):
|
||||
"Disconnect from a card"
|
||||
del self.card # FIXME: anything else to do?
|
||||
self.card.disconnect()
|
||||
if hasattr(self, "cardservice"):
|
||||
del self.cardservice
|
||||
del self.card
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from utils import pycsc
|
||||
|
||||
import crypto_utils, utils, cards, os, re, binascii, sys, exceptions, traceback, getopt, datetime
|
||||
from shell import Shell
|
||||
|
||||
|
@ -342,8 +340,8 @@ class Cyberflex_Shell(Shell):
|
|||
if reader is None:
|
||||
reader = self.reader
|
||||
|
||||
pycsc_card = utils.CommandLineArgumentHelper.connect_to(reader)
|
||||
self.card = cards.new_card_object(pycsc_card)
|
||||
card_object = utils.CommandLineArgumentHelper.connect_to(reader)
|
||||
self.card = cards.new_card_object(card_object)
|
||||
|
||||
self.unregister_commands(self, self.NOCARD_COMMANDS)
|
||||
self.register_commands(self, self.CARD_COMMANDS)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from utils import pycsc
|
||||
import utils, cards, TLV_utils, sys, binascii, time, traceback, re
|
||||
|
||||
def fingerprint_rfid(card):
|
||||
|
@ -184,8 +183,8 @@ if __name__ == "__main__":
|
|||
c = utils.CommandLineArgumentHelper()
|
||||
(options, arguments) = c.getopt(sys.argv[1:])
|
||||
|
||||
pycsc_card = c.connect()
|
||||
card = cards.new_card_object(pycsc_card)
|
||||
card_object = c.connect()
|
||||
card = cards.new_card_object(card_object)
|
||||
cards.generic_card.DEBUG = False
|
||||
|
||||
print >>sys.stderr, "Using %s" % card.DRIVER_NAME
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from utils import pycsc
|
||||
import utils, cards, TLV_utils, sys, binascii, time, traceback
|
||||
|
||||
OPTIONS = "GW:R:"
|
||||
|
@ -25,8 +24,8 @@ if __name__ == "__main__":
|
|||
read_files = value
|
||||
|
||||
if read_files is None:
|
||||
pycsc_card = c.connect()
|
||||
card = cards.new_card_object(pycsc_card)
|
||||
card_object = c.connect()
|
||||
card = cards.new_card_object(card_object)
|
||||
cards.generic_card.DEBUG = False
|
||||
|
||||
print >>sys.stderr, "Using %s" % card.DRIVER_NAME
|
||||
|
|
91
utils.py
91
utils.py
|
@ -1,14 +1,13 @@
|
|||
try:
|
||||
import pycsc
|
||||
except ImportError,e:
|
||||
try:
|
||||
import PyCSC
|
||||
from PyCSC import pycsc # Windows
|
||||
pycsc.SCARD_PROTOCOL_ANY = PyCSC.SCARD_PROTOCOL_ANY
|
||||
except ImportError:
|
||||
raise e # raise the original exception, masking the windows-only attempt
|
||||
|
||||
import string, binascii, sys, re, getopt
|
||||
try:
|
||||
import smartcard, smartcard.CardRequest
|
||||
except ImportError:
|
||||
print >>sys.stderr, """Could not import smartcard module. Please install pyscard
|
||||
from http://pyscard.sourceforge.net/
|
||||
If you can't install pyscard and want to continue using
|
||||
pycsc you'll need to downgrade to SVN revision 246.
|
||||
"""
|
||||
raise
|
||||
|
||||
class CommandLineArgumentHelper:
|
||||
OPTIONS = "r:l"
|
||||
|
@ -17,7 +16,7 @@ class CommandLineArgumentHelper:
|
|||
reader = None
|
||||
|
||||
def list_readers():
|
||||
for index, name in enumerate(pycsc.listReader()):
|
||||
for index, name in enumerate(smartcard.System.readers()):
|
||||
print "%i: %s" % (index, name)
|
||||
list_readers = staticmethod(list_readers)
|
||||
|
||||
|
@ -32,48 +31,48 @@ class CommandLineArgumentHelper:
|
|||
def connect_to(reader):
|
||||
"Open the connection to a reader"
|
||||
|
||||
readerObject = None
|
||||
|
||||
if isinstance(reader, int) or reader.isdigit():
|
||||
reader = int(reader)
|
||||
readerName = pycsc.listReader()[reader]
|
||||
readerObject = smartcard.System.readers()[reader]
|
||||
else:
|
||||
readerName = reader
|
||||
for r in smartcard.System.readers():
|
||||
if str(r).startswith(reader):
|
||||
readerObject = r
|
||||
|
||||
newState = pycsc.getStatusChange(ReaderStates=[
|
||||
{'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_UNAWARE}
|
||||
]
|
||||
)
|
||||
if readerObject is None:
|
||||
readerObject = smartcard.System.readers()[0]
|
||||
|
||||
print "Using reader: %s" % readerName
|
||||
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
|
||||
|
||||
if not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT:
|
||||
print "Please insert card ..."
|
||||
|
||||
last_was_mute = False
|
||||
|
||||
while not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT \
|
||||
or newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
|
||||
print "Using reader: %s" % readerObject
|
||||
unpatched = False
|
||||
printed = False
|
||||
while True:
|
||||
try:
|
||||
if not unpatched:
|
||||
cardrequest = smartcard.CardRequest.CardRequest( readers=[readerObject], timeout=0.1 )
|
||||
else:
|
||||
cardrequest = smartcard.CardRequest.CardRequest( readers=[readerObject], timeout=1 )
|
||||
|
||||
try:
|
||||
newState = pycsc.getStatusChange(ReaderStates=[
|
||||
{'Reader': readerName, 'CurrentState':newState[0]['EventState']}
|
||||
], Timeout = 100
|
||||
) ## 100 ms latency from Ctrl-C to abort should be almost unnoticeable by the user
|
||||
except pycsc.PycscException, e:
|
||||
if e.args[0] == 'Command timeout.': pass ## ugly
|
||||
else: raise
|
||||
|
||||
if newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
|
||||
if not last_was_mute:
|
||||
print "Card is mute, please retry ..."
|
||||
last_was_mute = True
|
||||
else:
|
||||
last_was_mute = False
|
||||
|
||||
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
|
||||
cardservice = cardrequest.waitforcard()
|
||||
cardservice.connection.connect()
|
||||
break
|
||||
except TypeError:
|
||||
unpatched = True
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except smartcard.Exceptions.CardRequestException:
|
||||
if sys.exc_info()[1].message.endswith("Command timeout."):
|
||||
if not printed:
|
||||
print "Please insert card ..."
|
||||
printed = True
|
||||
else:
|
||||
raise
|
||||
except smartcard.Exceptions.NoCardException:
|
||||
print "Card is mute or absent. Please retry."
|
||||
|
||||
print "ATR: %s" % hexdump(newState[0]['Atr'], short = True)
|
||||
return pycsc.pycsc(reader = readerName, protocol = pycsc.SCARD_PROTOCOL_ANY)
|
||||
print "ATR: %s" % hexdump(smartcard.util.toASCIIString(cardservice.connection.getATR()), short = True)
|
||||
return cardservice
|
||||
connect_to = staticmethod(connect_to)
|
||||
|
||||
def getopt(self, argv, opts="", long_opts=[]):
|
||||
|
|
Loading…
Reference in New Issue