- added more error handling to RelayOS

- vicc in relay mode terminates when card is removed
- created cleanup routines to use with atexit.register


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@309 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-10-09 13:33:32 +00:00
parent ae713f5b24
commit 8efb2f81a2

View File

@@ -23,13 +23,14 @@ from SmartcardFilesystem import prettyprint_anything, MF, DF, CryptoflexMF, Tran
from utils import C_APDU, R_APDU, hexdump, inttostring from utils import C_APDU, R_APDU, hexdump, inttostring
from SmartcardSAM import SAM, PassportSAM, CryptoflexSAM from SmartcardSAM import SAM, PassportSAM, CryptoflexSAM
import CardGenerator import CardGenerator
from smartcard.CardMonitoring import CardMonitor, CardObserver
from pickle import dumps, loads from pickle import dumps, loads
import socket, struct, sys, signal, atexit, traceback import socket, struct, sys, signal, atexit, traceback
import struct, getpass, anydbm import struct, getpass, anydbm
class SmartcardOS(object): class SmartcardOS(object): # {{{
"""Base class for a smart card OS""" """Base class for a smart card OS"""
mf = make_property("mf", "master file") mf = make_property("mf", "master file")
@@ -57,6 +58,7 @@ class SmartcardOS(object):
msg -- the APDU as string of characters msg -- the APDU as string of characters
""" """
return "" return ""
# }}}
class Iso7816OS(SmartcardOS): # {{{ class Iso7816OS(SmartcardOS): # {{{
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_SHORT_LE): def __init__(self, mf, sam, ins2handler=None, maxle=MAX_SHORT_LE):
@@ -364,23 +366,50 @@ class CryptoflexOS(Iso7816OS): # {{{
# }}} # }}}
class RelayOS(SmartcardOS): # {{{ class RelayOS(SmartcardOS): # {{{
import smartcard
class RelayCardObserver(smartcard.CardMonitoring.CardObserver): # {{{
def __init__(self, relayos):
self.os = relayos
def update(self, observable, (addedcards, removedcards)):
for removed in removedcards:
if removed.reader == self.os.reader:
if removed.atr == self.os.atr:
print "Card removed from %s. Terminating." % self.os.reader
sys.exit()
# }}}
def __init__(self, readernum): def __init__(self, readernum):
import smartcard import smartcard
readers = smartcard.System.listReaders()
if len(readers) <= readernum:
print "Invalid number of reader '%u' (only %u available)" % (readernum, len(readers))
sys.exit()
# XXX this is a workaround, see on sourceforge bug #3083254
# should better use
# self.reader = smartcard.System.readers()[readernum]
self.reader = readers[readernum]
try:
self.session = smartcard.Session(self.reader)
except smartcard.Exceptions.CardConnectionException, e:
print "Could not connect to card: %s" % str(e)
sys.exit()
self.atr = self.session.getATR()
self.cm = CardMonitor()
self.cm.addObserver(RelayOS.RelayCardObserver(self))
if readernum: print "Connected to card in %s" % self.session.readerName
# XXX this is a workaround, see on sourceforge bug #3083254
# should better use
# self.reader = smartcard.System.readers()[readernum]
self.reader = smartcard.System.listReaders()[readernum]
else:
self.reader = None
self.session = smartcard.Session(self.reader) atexit.register(self.stop)
print "Connected to %s" % self.session.readerName def stop(self):
self.session.close()
def getATR(self): def getATR(self):
return "".join([chr(b) for b in self.session.getATR()]) return "".join([chr(b) for b in self.atr])
def powerUp(self): def powerUp(self):
import smartcard import smartcard
@@ -388,13 +417,10 @@ class RelayOS(SmartcardOS): # {{{
self.session.getATR() self.session.getATR()
except smartcard.Exceptions.CardConnectionException: except smartcard.Exceptions.CardConnectionException:
self.session = smartcard.Session(self.reader) self.session = smartcard.Session(self.reader)
self.atr = self.session.getATR()
def powerDown(self): def powerDown(self):
import smartcard self.session.close()
try:
self.session.close()
except smartcard.Exceptions.CardConnectionException:
pass
def execute(self, msg): def execute(self, msg):
#apdu = [].append(ord(b) for b in msg) #apdu = [].append(ord(b) for b in msg)
@@ -437,14 +463,12 @@ class VirtualICC(object): # {{{
self.cardGenerator = CardGenerator.CardGenerator(type) self.cardGenerator = CardGenerator.CardGenerator(type)
#If a filename is specified, try to load the card from disk #If a filename is specified, try to load the card from disk
if filename == None: if filename != None:
print "No filename specified. The card will not be safed!"
else:
self.filename = filename self.filename = filename
if exists(filename): if exists(filename):
self.cardGenerator.loadCard(self.filename) self.cardGenerator.loadCard(self.filename)
else: else:
print "No file " + self.filename + " found. Will create new file at termination of program." print "Creating new card which will be saved in %s." % self.filename
MF, SAM = self.cardGenerator.getCard() MF, SAM = self.cardGenerator.getCard()
@@ -466,19 +490,15 @@ class VirtualICC(object): # {{{
self.sock = self.connectToPort(host, port) self.sock = self.connectToPort(host, port)
self.sock.settimeout(None) self.sock.settimeout(None)
except socket.error, e: except socket.error, e:
print "Failed to open socket: " + str(e) + ". Is pcscd running? Is vpcd installed?" print "Failed to open socket: " + str(e) + ". Is pcscd running? Is vpcd loaded?"
sys.exit() sys.exit()
self.lenlen = lenlen self.lenlen = lenlen
signal.signal(signal.SIGINT, self.signalHandler) signal.signal(signal.SIGINT, self.signalHandler)
#atexit.register(self.signalHandler) atexit.register(self.stop)
#atexit.register(saveCard)
def signalHandler(self, signal=None, frame=None): def signalHandler(self, signal=None, frame=None):
self.sock.close()
if self.filename != None:
self.cardGenerator.setCard(self.os.mf, self.os.SAM)
self.cardGenerator.saveCard(self.filename)
sys.exit() sys.exit()
@staticmethod @staticmethod
@@ -526,6 +546,12 @@ class VirtualICC(object): # {{{
answer = self.os.execute(msg) answer = self.os.execute(msg)
print "RESP (%d Bytes):\n%s\n" % (len(answer),hexdump(answer, short=True)) print "RESP (%d Bytes):\n%s\n" % (len(answer),hexdump(answer, short=True))
self.__sendToVPICC(answer) self.__sendToVPICC(answer)
def stop(self):
self.sock.close()
if self.filename != None:
self.cardGenerator.setCard(self.os.mf, self.os.SAM)
self.cardGenerator.saveCard(self.filename)
# }}} # }}}
if __name__ == "__main__": if __name__ == "__main__":