first init

This commit is contained in:
ISMAIL MASSERAN
2026-09-01 10:12:31 +08:00
commit ca6e55f853
718 changed files with 204746 additions and 0 deletions
@@ -0,0 +1,76 @@
"""
A wxValidator that matches APDU in hexadecimal such as::
A4 A0 00 00 02
A4A0000002
__author__ = "https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import re
import string
import wx
# a regexp to match ATRs and APDUs
hexbyte = "[0-9a-fA-F]{1,2}"
apduregexp = re.compile("((%s)[ ]*)*" % hexbyte)
class APDUHexValidator(wx.PyValidator):
"""A wxValidator that matches APDU in hexadecimal such as:
A4 A0 00 00 02
A4A0000002"""
def __init__(self):
wx.Validator.__init__(self)
self.Bind(wx.EVT_CHAR, self.OnChar)
def Clone(self):
return APDUHexValidator()
def Validate(self, win):
tc = self.GetWindow()
value = tc.GetValue()
if not apduregexp.match(value):
return False
return True
def OnChar(self, event):
key = event.GetKeyCode()
if wx.WXK_SPACE == key or chr(key) in string.hexdigits:
value = event.GetEventObject().GetValue() + chr(key)
if apduregexp.match(value):
event.Skip()
return
if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
event.Skip()
return
if not wx.Validator.IsSilent():
wx.Bell()
return
@@ -0,0 +1,83 @@
"""Graphical APDU Tracer.
__author__ = "gemalto https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
# wxPython GUI modules (https://www.wxpython.org/)
import wx
from smartcard.CardConnectionObserver import CardConnectionObserver
from smartcard.util import toHexString
[
wxID_APDUTEXTCTRL,
] = [wx.NewId() for x in range(1)]
class APDUTracerPanel(wx.Panel, CardConnectionObserver):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
boxsizer = wx.BoxSizer(wx.HORIZONTAL)
self.apdutextctrl = wx.TextCtrl(
self,
wxID_APDUTEXTCTRL,
"",
pos=wx.DefaultPosition,
style=wx.TE_MULTILINE | wx.TE_READONLY,
)
boxsizer.Add(self.apdutextctrl, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(boxsizer)
self.SetAutoLayout(True)
self.Bind(wx.EVT_TEXT_MAXLEN, self.OnMaxLength, self.apdutextctrl)
def OnMaxLength(self, evt):
"""Reset text buffer when max length is reached."""
self.apdutextctrl.SetValue("")
evt.Skip()
def update(self, cardconnection, ccevent):
"""CardConnectionObserver callback."""
apduline = ""
if "connect" == ccevent.type:
apduline += "connecting to " + cardconnection.getReader()
elif "disconnect" == ccevent.type:
apduline += "disconnecting from " + cardconnection.getReader()
elif "command" == ccevent.type:
apduline += "> " + toHexString(ccevent.args[0])
elif "response" == ccevent.type:
if [] == ccevent.args[0]:
apduline += "< %-2X %-2X" % tuple(ccevent.args[-2:])
else:
apduline += (
"< "
+ toHexString(ccevent.args[0])
+ "%-2X %-2X" % tuple(ccevent.args[-2:])
)
self.apdutextctrl.AppendText(apduline + "\n")
@@ -0,0 +1,394 @@
"""wxPython panel display cards/readers as a TreeCtrl.
__author__ = "gemalto https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
# smartcard imports
from threading import RLock
# wxPython GUI modules (https://www.wxpython.org/)
import wx
import smartcard.wx.SimpleSCardApp
from smartcard.CardMonitoring import CardMonitor, CardObserver
from smartcard.Exceptions import CardConnectionException, NoCardException
from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver
from smartcard.util import toHexString
from smartcard.wx import ICO_READER, ICO_SMARTCARD
class BaseCardTreeCtrl(wx.TreeCtrl):
"""Base class for the smart card and reader tree controls."""
def __init__(
self,
parent,
ID=wx.NewId(),
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=0,
clientpanel=None,
):
"""Constructor. Initializes a smartcard or reader tree control."""
wx.TreeCtrl.__init__(
self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS
)
self.clientpanel = clientpanel
self.parent = parent
isz = (16, 16)
il = wx.ImageList(isz[0], isz[1])
self.capindex = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_HELP_BOOK, wx.ART_OTHER, isz)
)
self.fldrindex = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz)
)
self.fldropenindex = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz)
)
if None != ICO_SMARTCARD:
self.cardimageindex = il.Add(wx.Bitmap(ICO_SMARTCARD, wx.BITMAP_TYPE_ICO))
if None != ICO_READER:
self.readerimageindex = il.Add(wx.Bitmap(ICO_READER, wx.BITMAP_TYPE_ICO))
self.il = il
self.SetImageList(self.il)
def Repaint(self):
self.Refresh()
class CardTreeCtrl(BaseCardTreeCtrl):
"""The CardTreeCtrl monitors inserted cards and notifies the
application client dialog of any card activation."""
def __init__(
self,
parent,
ID=wx.NewId(),
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=0,
clientpanel=None,
):
"""Constructor. Create a smartcard tree control."""
BaseCardTreeCtrl.__init__(
self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS, clientpanel
)
self.root = self.AddRoot("Smartcards")
self.SetItemData(self.root, None)
self.SetItemImage(self.root, self.fldrindex, wx.TreeItemIcon_Normal)
self.SetItemImage(self.root, self.fldropenindex, wx.TreeItemIcon_Expanded)
self.Expand(self.root)
def OnAddCards(self, addedcards):
"""Called when a card is inserted.
Adds a smart card to the smartcards tree."""
parentnode = self.root
for cardtoadd in addedcards:
childCard = self.AppendItem(parentnode, toHexString(cardtoadd.atr))
self.SetItemText(childCard, toHexString(cardtoadd.atr))
self.SetItemData(childCard, cardtoadd)
self.SetItemImage(childCard, self.cardimageindex, wx.TreeItemIcon_Normal)
self.SetItemImage(childCard, self.cardimageindex, wx.TreeItemIcon_Expanded)
self.Expand(childCard)
self.Expand(self.root)
self.EnsureVisible(self.root)
self.Repaint()
def OnRemoveCards(self, removedcards):
"""Called when a card is removed.
Removes a card from the tree."""
parentnode = self.root
for cardtoremove in removedcards:
(childCard, cookie) = self.GetFirstChild(parentnode)
while childCard.IsOk():
if self.GetItemText(childCard) == toHexString(cardtoremove.atr):
self.Delete(childCard)
(childCard, cookie) = self.GetNextChild(parentnode, cookie)
self.Expand(self.root)
self.EnsureVisible(self.root)
self.Repaint()
class ReaderTreeCtrl(BaseCardTreeCtrl):
"""The ReaderTreeCtrl monitors inserted cards and readers and notifies the
application client dialog of any card activation."""
def __init__(
self,
parent,
ID=wx.NewId(),
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=0,
clientpanel=None,
):
"""Constructor. Create a reader tree control."""
BaseCardTreeCtrl.__init__(
self, parent, ID, pos, size, wx.TR_SINGLE | wx.TR_NO_BUTTONS, clientpanel
)
self.mutex = RLock()
self.root = self.AddRoot("Smartcard Readers")
self.SetItemData(self.root, None)
self.SetItemImage(self.root, self.fldrindex, wx.TreeItemIcon_Normal)
self.SetItemImage(self.root, self.fldropenindex, wx.TreeItemIcon_Expanded)
self.Expand(self.root)
def AddATR(self, readernode, atr):
"""Add an ATR to a reader node."""
capchild = self.AppendItem(readernode, atr)
self.SetItemData(capchild, None)
self.SetItemImage(capchild, self.cardimageindex, wx.TreeItemIcon_Normal)
self.SetItemImage(capchild, self.cardimageindex, wx.TreeItemIcon_Expanded)
self.Expand(capchild)
return capchild
def GetATR(self, reader):
"""Return the ATR of the card inserted into the reader."""
atr = "no card inserted"
try:
if not type(reader) is str:
connection = reader.createConnection()
connection.connect()
atr = toHexString(connection.getATR())
connection.disconnect()
except NoCardException:
pass
except CardConnectionException:
pass
return atr
def OnAddCards(self, addedcards):
"""Called when a card is inserted.
Adds the smart card child to the reader node."""
self.mutex.acquire()
try:
parentnode = self.root
for cardtoadd in addedcards:
(childReader, cookie) = self.GetFirstChild(parentnode)
found = False
while childReader.IsOk() and not found:
if self.GetItemText(childReader) == str(cardtoadd.reader):
(childCard, cookie2) = self.GetFirstChild(childReader)
self.SetItemText(childCard, toHexString(cardtoadd.atr))
self.SetItemData(childCard, cardtoadd)
found = True
else:
(childReader, cookie) = self.GetNextChild(parentnode, cookie)
# reader was not found, add reader node
# this happens when card monitoring thread signals
# added cards before reader monitoring thread signals
# added readers
if not found:
childReader = self.AppendItem(parentnode, str(cardtoadd.reader))
self.SetItemData(childReader, cardtoadd.reader)
self.SetItemImage(
childReader, self.readerimageindex, wx.TreeItemIcon_Normal
)
self.SetItemImage(
childReader, self.readerimageindex, wx.TreeItemIcon_Expanded
)
childCard = self.AddATR(childReader, toHexString(cardtoadd.atr))
self.SetItemData(childCard, cardtoadd)
self.Expand(childReader)
self.Expand(self.root)
finally:
self.mutex.release()
self.EnsureVisible(self.root)
self.Repaint()
def OnAddReaders(self, addedreaders):
"""Called when a reader is inserted.
Adds the smart card reader to the smartcard readers tree."""
self.mutex.acquire()
try:
parentnode = self.root
for readertoadd in addedreaders:
# is the reader already here?
found = False
(childReader, cookie) = self.GetFirstChild(parentnode)
while childReader.IsOk() and not found:
if self.GetItemText(childReader) == str(readertoadd):
found = True
else:
(childReader, cookie) = self.GetNextChild(parentnode, cookie)
if not found:
childReader = self.AppendItem(parentnode, str(readertoadd))
self.SetItemData(childReader, readertoadd)
self.SetItemImage(
childReader, self.readerimageindex, wx.TreeItemIcon_Normal
)
self.SetItemImage(
childReader, self.readerimageindex, wx.TreeItemIcon_Expanded
)
self.AddATR(childReader, self.GetATR(readertoadd))
self.Expand(childReader)
self.Expand(self.root)
finally:
self.mutex.release()
self.EnsureVisible(self.root)
self.Repaint()
def OnRemoveCards(self, removedcards):
"""Called when a card is removed.
Removes the card from the tree."""
self.mutex.acquire()
try:
parentnode = self.root
for cardtoremove in removedcards:
(childReader, cookie) = self.GetFirstChild(parentnode)
found = False
while childReader.IsOk() and not found:
if self.GetItemText(childReader) == str(cardtoremove.reader):
(childCard, cookie2) = self.GetFirstChild(childReader)
self.SetItemText(childCard, "no card inserted")
found = True
else:
(childReader, cookie) = self.GetNextChild(parentnode, cookie)
self.Expand(self.root)
finally:
self.mutex.release()
self.EnsureVisible(self.root)
self.Repaint()
def OnRemoveReaders(self, removedreaders):
"""Called when a reader is removed.
Removes the reader from the smartcard readers tree."""
self.mutex.acquire()
try:
parentnode = self.root
for readertoremove in removedreaders:
(childReader, cookie) = self.GetFirstChild(parentnode)
while childReader.IsOk():
if self.GetItemText(childReader) == str(readertoremove):
self.Delete(childReader)
else:
(childReader, cookie) = self.GetNextChild(parentnode, cookie)
self.Expand(self.root)
finally:
self.mutex.release()
self.EnsureVisible(self.root)
self.Repaint()
class CardAndReaderTreePanel(wx.Panel):
"""Panel containing the smart card and reader tree controls."""
class _CardObserver(CardObserver):
"""Inner CardObserver. Gets notified of card insertion
removal by the CardMonitor."""
def __init__(self, cardtreectrl):
self.cardtreectrl = cardtreectrl
def update(self, observable, handlers):
"""CardObserver callback that is notified
when cards are added or removed."""
addedcards, removedcards = handlers
self.cardtreectrl.OnRemoveCards(removedcards)
self.cardtreectrl.OnAddCards(addedcards)
class _ReaderObserver(ReaderObserver):
"""Inner ReaderObserver. Gets notified of reader insertion/removal
by the ReaderMonitor."""
def __init__(self, readertreectrl):
self.readertreectrl = readertreectrl
def update(self, observable, handlers):
"""ReaderObserver callback that is notified when
readers are added or removed."""
addedreaders, removedreaders = handlers
self.readertreectrl.OnRemoveReaders(removedreaders)
self.readertreectrl.OnAddReaders(addedreaders)
def __init__(self, parent, appstyle, clientpanel):
"""Constructor. Create a smartcard and reader tree control on the
left-hand side of the application main frame.
@param parent: the tree panel parent
@param appstyle: a combination of the following styles (bitwise or |)
- TR_SMARTCARD: display a smartcard tree panel
- TR_READER: display a reader tree panel
- default is TR_DEFAULT = TR_SMARTCARD
@param clientpanel: the client panel to notify of smartcard and reader events
"""
wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
sizer = wx.BoxSizer(wx.VERTICAL)
# create the smartcard tree
if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD:
self.cardtreectrl = CardTreeCtrl(self, clientpanel=clientpanel)
# create the smartcard insertion observer
self.cardtreecardobserver = self._CardObserver(self.cardtreectrl)
# register as a CardObserver; we will ge
# notified of added/removed cards
self.cardmonitor = CardMonitor()
self.cardmonitor.addObserver(self.cardtreecardobserver)
sizer.Add(self.cardtreectrl, flag=wx.EXPAND | wx.ALL, proportion=1)
# create the reader tree
if appstyle & smartcard.wx.SimpleSCardApp.TR_READER:
self.readertreectrl = ReaderTreeCtrl(self, clientpanel=clientpanel)
# create the reader insertion observer
self.readertreereaderobserver = self._ReaderObserver(self.readertreectrl)
# register as a ReaderObserver; we will ge
# notified of added/removed readers
self.readermonitor = ReaderMonitor()
self.readermonitor.addObserver(self.readertreereaderobserver)
# create the smartcard insertion observer
self.readertreecardobserver = self._CardObserver(self.readertreectrl)
# register as a CardObserver; we will get
# notified of added/removed cards
self.cardmonitor = CardMonitor()
self.cardmonitor.addObserver(self.readertreecardobserver)
sizer.Add(self.readertreectrl, flag=wx.EXPAND | wx.ALL, proportion=1)
self.SetSizer(sizer)
self.SetAutoLayout(True)
def OnDestroy(self, event):
"""Called on panel destruction."""
# deregister observers
if hasattr(self, "cardmonitor"):
self.cardmonitor.deleteObserver(self.cardtreecardobserver)
if hasattr(self, "readermonitor"):
self.readermonitor.deleteObserver(self.readertreereaderobserver)
self.cardmonitor.deleteObserver(self.readertreecardobserver)
event.Skip()
@@ -0,0 +1,102 @@
"""wxPython toolbar with reader icons implementing ReaderObserver.
__author__ = "gemalto https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import wx
from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver
from smartcard.wx import ICO_READER, ICO_SMARTCARD
class ReaderComboBox(wx.ComboBox, ReaderObserver):
def __init__(self, parent):
"""Constructor. Registers as ReaderObserver to get
notifications of reader insertion/removal."""
wx.ComboBox.__init__(
self,
parent,
wx.NewId(),
size=(170, -1),
style=wx.CB_DROPDOWN | wx.CB_SORT,
choices=[],
)
# register as a ReaderObserver; we will get
# notified of added/removed readers
self.readermonitor = ReaderMonitor()
self.readermonitor.addObserver(self)
def update(self, observable, handlers):
"""Toolbar ReaderObserver callback that is notified when
readers are added or removed."""
addedreaders, removedreaders = handlers
for reader in addedreaders:
item = self.Append(str(reader))
self.SetClientData(item, reader)
for reader in removedreaders:
item = self.FindString(str(reader))
if wx.NOT_FOUND != item:
self.Delete(item)
selection = self.GetSelection()
# if wx.NOT_FOUND == selection:
# self.SetSelection(0)
class ReaderToolbar(wx.ToolBar):
"""ReaderToolbar. Contains controls to select a reader from a listbox
and connect to the cards."""
def __init__(self, parent):
"""Constructor, creating the reader toolbar."""
wx.ToolBar.__init__(
self,
parent,
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.SIMPLE_BORDER | wx.TB_HORIZONTAL | wx.TB_FLAT | wx.TB_TEXT,
name="Reader Toolbar",
)
# create bitmaps for toolbar
tsize = (16, 16)
if None != ICO_READER:
bmpReader = wx.Bitmap(ICO_READER, wx.BITMAP_TYPE_ICO)
else:
bmpReader = wx.ArtProvider_GetBitmap(wx.ART_HELP_BOOK, wx.ART_OTHER, tsize)
if None != ICO_SMARTCARD:
bmpCard = wx.Bitmap(ICO_SMARTCARD, wx.BITMAP_TYPE_ICO)
else:
bmpCard = wx.ArtProvider_GetBitmap(wx.ART_HELP_BOOK, wx.ART_OTHER, tsize)
self.readercombobox = ReaderComboBox(self)
# create and add controls
self.AddSimpleTool(
10, bmpReader, "Select smart card reader", "Select smart card reader"
)
self.AddControl(self.readercombobox)
self.AddSeparator()
self.AddSimpleTool(20, bmpCard, "Connect to smartcard", "Connect to smart card")
self.AddSeparator()
self.Realize()
@@ -0,0 +1,93 @@
"""Simple wxPython wxApp for smartcard.
__author__ = "gemalto https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import wx
from smartcard.wx.SimpleSCardAppFrame import SimpleSCardAppFrame
TR_SMARTCARD = 0x001
TR_READER = 0x002
TB_SMARTCARD = 0x004
TB_READER = 0x008
PANEL_APDUTRACER = 0x010
TR_DEFAULT = TR_SMARTCARD
class SimpleSCardApp(wx.App):
"""The SimpleSCardApp class represents the smart card application.
SimpleSCardApp is a subclass of wx.App.
"""
def __init__(
self,
appname="",
apppanel=None,
appstyle=TR_DEFAULT,
appicon=None,
pos=(-1, -1),
size=(-1, -1),
):
r"""Constructor for simple smart card application.
@param appname: the application name
@param apppanel: the application panel to display in the application frame
@param appicon: the application icon file; the default is no icon
@param appstyle: a combination of the following styles (bitwise or |)
- TR_SMARTCARD: display a smartcard tree panel
- TR_READER: display a reader tree panel
- TB_SMARTCARD: display a smartcard toolbar
- TB_SMARTCARD: display a reader toolbar
- PANEL_APDUTRACER: display an APDU tracer panel
- default is TR_DEFAULT = TR_SMARTCARD
@param pos: the application position as a (x,y) tuple; default is (-1,-1)
@param size: the application window size as a (x,y) tuple; default is (-1,-1)
Example:
C{app = SimpleSCardApp(
appname = 'A simple smartcard application',
apppanel = testpanel.MyPanel,
appstyle = TR_READER | TR_SMARTCARD,
appicon = 'resources\mysmartcard.ico')}
"""
self.appname = appname
self.apppanel = apppanel
self.appstyle = appstyle
self.appicon = appicon
self.pos = pos
self.size = size
wx.App.__init__(self, False)
def OnInit(self):
"""Create and display application frame."""
self.frame = SimpleSCardAppFrame(
self.appname,
self.apppanel,
self.appstyle,
self.appicon,
self.pos,
self.size,
)
self.frame.Show(True)
self.SetTopWindow(self.frame)
return True
@@ -0,0 +1,63 @@
"""Smartcard event observer.
__author__ = "gemalto https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
class SimpleSCardAppEventObserver:
"""This interface defines the event handlers
called by the SimpleSCardApp."""
def __init__(self):
self.selectedcard = None
self.selectedreader = None
# callbacks from SimpleCardAppFrame controls
def OnActivateCard(self, card):
"""Called when a card is activated in the reader
tree control or toolbar."""
self.selectedcard = card
def OnActivateReader(self, reader):
"""Called when a reader is activated in the reader
tree control or toolbar."""
self.selectedreader = reader
def OnDeactivateCard(self, card):
"""Called when a card is deactivated in the reader
tree control or toolbar."""
pass
def OnDeselectCard(self, card):
"""Called when a card is selected in the reader
tree control or toolbar."""
self.selectedcard = None
def OnSelectCard(self, card):
"""Called when a card is selected in the reader
tree control or toolbar."""
self.selectedcard = card
def OnSelectReader(self, reader):
"""Called when a reader is selected in the reader
tree control or toolbar."""
self.selectedreader = reader
@@ -0,0 +1,343 @@
"""Simple wxpython frame for smart card application.
__author__ = "gemalto https://www.gemalto.com/"
__date__ = "November 2006"
__version__ = "1.4.0"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import os.path
import wx
import smartcard
import smartcard.wx
from smartcard.wx import APDUTracerPanel, CardAndReaderTreePanel, ReaderToolbar
from smartcard.wx.SimpleSCardAppEventObserver import SimpleSCardAppEventObserver
[
wxID_SIMPLESCARDAPP_FRAME,
] = [wx.NewId() for x in range(1)]
class BlankPanel(wx.Panel, SimpleSCardAppEventObserver):
"""A blank panel in case no panel is provided to SimpleSCardApp."""
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
sizer = wx.GridSizer(1, 1, 0)
self.SetSizer(sizer)
self.SetAutoLayout(True)
class TreeAndUserPanelPanel(wx.Panel):
"""The panel that contains the Card/Reader TreeCtrl
and the user provided Panel."""
def __init__(self, parent, apppanelclass, appstyle):
"""
Constructor. Creates the panel with two panels:
- the left-hand panel is holding the smartcard and/or reader tree
- the right-hand panel is holding the application dialog
@param apppanelclass: the class of the panel to instantiate in the
L{SimpleSCardAppFrame}
@param appstyle: a combination of the following styles (bitwise or |)
- TR_SMARTCARD: display a smartcard tree panel
- TR_READER: display a reader tree panel
- TB_SMARTCARD: display a smartcard toolbar
- TB_SMARTCARD: display a reader toolbar
- default is TR_DEFAULT = TR_SMARTCARD
"""
wx.Panel.__init__(self, parent, -1)
self.parent = parent
self.selectedcard = None
boxsizer = wx.BoxSizer(wx.HORIZONTAL)
# create user dialog
if None != apppanelclass:
self.dialogpanel = apppanelclass(self)
else:
self.dialogpanel = BlankPanel(self)
# create card/reader tree control
if (
appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD
or appstyle & smartcard.wx.SimpleSCardApp.TR_READER
):
self.readertreepanel = CardAndReaderTreePanel.CardAndReaderTreePanel(
self, appstyle, self.dialogpanel
)
boxsizer.Add(self.readertreepanel, 1, wx.EXPAND | wx.ALL, 5)
boxsizer.Add(self.dialogpanel, 2, wx.EXPAND | wx.ALL)
if appstyle & smartcard.wx.SimpleSCardApp.TR_READER:
self.Bind(
wx.EVT_TREE_ITEM_ACTIVATED,
self.OnActivateReader,
self.readertreepanel.readertreectrl,
)
self.Bind(
wx.EVT_TREE_SEL_CHANGED,
self.OnSelectReader,
self.readertreepanel.readertreectrl,
)
self.Bind(
wx.EVT_TREE_ITEM_RIGHT_CLICK,
self.OnReaderRightClick,
self.readertreepanel.readertreectrl,
)
self.Bind(
wx.EVT_TREE_ITEM_COLLAPSED,
self.OnItemCollapsed,
self.readertreepanel.readertreectrl,
)
if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD:
self.Bind(
wx.EVT_TREE_ITEM_ACTIVATED,
self.OnActivateCard,
self.readertreepanel.cardtreectrl,
)
self.Bind(
wx.EVT_TREE_SEL_CHANGED,
self.OnSelectCard,
self.readertreepanel.cardtreectrl,
)
self.Bind(
wx.EVT_TREE_ITEM_RIGHT_CLICK,
self.OnCardRightClick,
self.readertreepanel.cardtreectrl,
)
self.SetSizer(boxsizer)
self.SetAutoLayout(True)
def ActivateCard(self, card):
"""Activate a card."""
if not hasattr(card, "connection"):
card.connection = card.createConnection()
if None != self.parent.apdutracerpanel:
card.connection.addObserver(self.parent.apdutracerpanel)
card.connection.connect()
self.dialogpanel.OnActivateCard(card)
def DeactivateCard(self, card):
"""Deactivate a card."""
if hasattr(card, "connection"):
card.connection.disconnect()
if None != self.parent.apdutracerpanel:
card.connection.deleteObserver(self.parent.apdutracerpanel)
delattr(card, "connection")
self.dialogpanel.OnDeactivateCard(card)
def OnActivateCard(self, event):
"""Called when the user activates a card in the tree."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.cardtreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.ActivateCard(itemdata)
else:
self.dialogpanel.OnDeselectCard(itemdata)
def OnActivateReader(self, event):
"""Called when the user activates a reader in the tree."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.readertreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.ActivateCard(itemdata)
elif isinstance(itemdata, smartcard.reader.Reader.Reader):
self.dialogpanel.OnActivateReader(itemdata)
event.Skip()
def OnItemCollapsed(self, event):
item = event.GetItem()
self.readertreepanel.readertreectrl.Expand(item)
def OnCardRightClick(self, event):
"""Called when user right-clicks a node in the card tree control."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.cardtreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.selectedcard = itemdata
if not hasattr(self, "connectID"):
self.connectID = wx.NewId()
self.disconnectID = wx.NewId()
self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID)
self.Bind(wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID)
menu = wx.Menu()
if not hasattr(self.selectedcard, "connection"):
menu.Append(self.connectID, "Connect")
else:
menu.Append(self.disconnectID, "Disconnect")
self.PopupMenu(menu)
menu.Destroy()
def OnReaderRightClick(self, event):
"""Called when user right-clicks a node in the reader tree control."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.readertreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.selectedcard = itemdata
if not hasattr(self, "connectID"):
self.connectID = wx.NewId()
self.disconnectID = wx.NewId()
self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID)
self.Bind(wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID)
menu = wx.Menu()
if not hasattr(self.selectedcard, "connection"):
menu.Append(self.connectID, "Connect")
else:
menu.Append(self.disconnectID, "Disconnect")
self.PopupMenu(menu)
menu.Destroy()
def OnConnect(self, event):
if isinstance(self.selectedcard, smartcard.Card.Card):
self.ActivateCard(self.selectedcard)
def OnDisconnect(self, event):
if isinstance(self.selectedcard, smartcard.Card.Card):
self.DeactivateCard(self.selectedcard)
def OnSelectCard(self, event):
"""Called when the user selects a card in the tree."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.cardtreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.dialogpanel.OnSelectCard(itemdata)
else:
self.dialogpanel.OnDeselectCard(itemdata)
def OnSelectReader(self, event):
"""Called when the user selects a reader in the tree."""
item = event.GetItem()
if item:
itemdata = self.readertreepanel.readertreectrl.GetItemData(item)
if isinstance(itemdata, smartcard.Card.Card):
self.dialogpanel.OnSelectCard(itemdata)
elif isinstance(itemdata, smartcard.reader.Reader.Reader):
self.dialogpanel.OnSelectReader(itemdata)
else:
self.dialogpanel.OnDeselectCard(itemdata)
class SimpleSCardAppFrame(wx.Frame):
"""The main frame of the simple smartcard application."""
def __init__(
self,
appname,
apppanelclass,
appstyle,
appicon,
pos=(-1, -1),
size=(-1, -1),
):
"""
Constructor. Creates the frame with two panels:
- the left-hand panel is holding the smartcard and/or reader tree
- the right-hand panel is holding the application dialog
@param appname: name of the application
@param apppanelclass: the class of the panel to instantiate in the
L{SimpleSCardAppFrame}
@param appstyle: a combination of the following styles (bitwise or |)
- TR_SMARTCARD: display a smartcard tree panel
- TR_READER: display a reader tree panel
- TB_SMARTCARD: display a smartcard toolbar
- TB_SMARTCARD: display a reader toolbar
- PANEL_APDUTRACER: display an APDU tracer panel
- default is TR_DEFAULT = TR_SMARTCARD
@param pos: the application position as a (x,y) tuple; default is (-1,-1)
@param size: the application window size as a (x,y) tuple; default is (-1,-1)
"""
wx.Frame.__init__(
self,
None,
wxID_SIMPLESCARDAPP_FRAME,
appname,
pos=pos,
size=size,
style=wx.DEFAULT_FRAME_STYLE,
)
if appicon:
_icon = wx.Icon(appicon, wx.BITMAP_TYPE_ICO)
self.SetIcon(_icon)
elif os.path.exists(smartcard.wx.ICO_SMARTCARD):
_icon = wx.Icon(smartcard.wx.ICO_SMARTCARD, wx.BITMAP_TYPE_ICO)
self.SetIcon(_icon)
boxsizer = wx.BoxSizer(wx.VERTICAL)
self.treeuserpanel = TreeAndUserPanelPanel(self, apppanelclass, appstyle)
boxsizer.Add(self.treeuserpanel, 3, wx.EXPAND | wx.ALL)
# create a toolbar if required
if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD:
self.toolbar = ReaderToolbar.ReaderToolbar(self)
self.SetToolBar(self.toolbar)
else:
self.toolbar = None
# create an apdu tracer console if required
if appstyle & smartcard.wx.SimpleSCardApp.PANEL_APDUTRACER:
self.apdutracerpanel = APDUTracerPanel.APDUTracerPanel(self)
boxsizer.Add(self.apdutracerpanel, 1, wx.EXPAND | wx.ALL)
else:
self.apdutracerpanel = None
self.SetSizer(boxsizer)
self.SetAutoLayout(True)
self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD:
self.Bind(
wx.EVT_COMBOBOX, self.OnReaderComboBox, self.toolbar.readercombobox
)
def OnCloseFrame(self, evt):
"""Called when frame is closed, i.e. on wx.EVT_CLOSE"""
evt.Skip()
def OnExit(self, evt):
"""Called when frame application exits."""
self.Close(True)
evt.Skip()
def OnReaderComboBox(self, event):
"""Called when the user activates a reader in the toolbar combo box."""
cb = event.GetEventObject()
reader = cb.GetClientData(cb.GetSelection())
if isinstance(reader, smartcard.reader.Reader.Reader):
self.treeuserpanel.dialogpanel.OnActivateReader(reader)
@@ -0,0 +1,49 @@
"""wxpython smartcard utility module.
__author__ = "https://www.gemalto.com/"
Copyright 2001-2012 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
This file is part of pyscard.
pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import os.path
import sys
def main_is_frozen():
return hasattr(sys, "frozen") or hasattr(sys, "importers")
ICO_SMARTCARD = None
ICO_READER = None
# running from a script, i.e. not running from standalone exe built with py2exe
if not main_is_frozen():
ICO_SMARTCARD = os.path.join(
os.path.dirname(__file__), "resources", "smartcard.ico"
)
ICO_READER = os.path.join(os.path.dirname(__file__), "resources", "reader.ico")
# running from a standalone exe built with py2exe
# resources expected images directory
else:
if os.path.exists(os.path.join("images", "smartcard.ico")):
ICO_SMARTCARD = os.path.join("images", "smartcard.ico")
if os.path.exists(os.path.join("images", "reader.ico")):
ICO_READER = os.path.join("images", "reader.ico")
Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B