Files
vsmartcard/pace-gui/src/pinpad.py
oepen f5b2f54b2b New version of pace-gui indicates wether or not a suitable card was found.
This works by polling the card every second via opensc-tool --atr
The radio buttons have been removed to have enough space for the new label


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@148 96b47cad-a561-4643-ad3b-153ac7d7599c
2010-06-14 06:21:22 +00:00

235 lines
7.6 KiB
Python

#!/usr/bin/env python
import sys, os
import subprocess
from threading import Thread, Event
try:
import pygtk
pygtk.require("2.0")
except:
pass
try:
import gtk, gobject, glib
import pango
except:
sys.exit(1)
#glade_dir is set by the build system
from pinpad_globals import *
class PinpadGTK:
"""This a simple GTK based GUI to enter a PIN"""
def __init__(self):
btn_names = ["btnOne", "btnTwo", "btnThree", "btnFour", "btnFive",
"btnSix", "btnSeven", "btnEight", "btnNine", "btnDel",
"btnZero", "btnOk"]
self.pin = ""
#Set the Glade file
self.gladefile = glade_dir + "/pinpad.glade"
self.builder = gtk.Builder()
try:
self.builder.add_from_file(self.gladefile)
except glib.GError, e:
popup = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
e.message)
popup.run()
popup.destroy()
raise e
#Get the Main Window, and connect the "destroy" event
#Create our dictionay and connect it
dic = { "on_btnOne_clicked" : self.digit_clicked,
"on_btnTwo_clicked" : self.digit_clicked,
"on_btnThree_clicked" : self.digit_clicked,
"on_btnFour_clicked" : self.digit_clicked,
"on_btnFive_clicked" : self.digit_clicked,
"on_btnSix_clicked" : self.digit_clicked,
"on_btnSeven_clicked" : self.digit_clicked,
"on_btnEight_clicked" : self.digit_clicked,
"on_btnNine_clicked" : self.digit_clicked,
"on_btnZero_clicked" : self.digit_clicked,
"on_btnOk_clicked" : self.btnOk_clicked,
"on_btnDel_clicked" : self.btnDel_clicked,
"on_MainWindow_destroy_event" : gtk.main_quit,
"on_MainWindow_destroy" : gtk.main_quit }
self.builder.connect_signals(dic)
#Change the font for the text field
txtOutput = self.builder.get_object("txtOutput")
font = pango.FontDescription("Monospace")
txtOutput.modify_font(pango.FontDescription("sans 24"))
#Look for card and set the label accordingly
lbl_cardStatus = self.builder.get_object("lbl_cardStatus")
self.cardChecker = cardChecker(lbl_cardStatus, ePA_ATR)
gobject.idle_add(self.cardChecker.start)
#Change the font for the buttons
#For this you have to retrieve the label of each button and change
#its font
for name in btn_names:
btn = self.builder.get_object(name)
if btn.get_use_stock():
lbl = btn.child.get_children()[1]
elif isinstance(btn.child, gtk.Label):
lbl = btn.child
else:
raise ValueError("Button does not have a label")
if (name == "btnOk" or name == "btnDel"):
lbl.modify_font(pango.FontDescription("sans 16"))
else:
lbl.modify_font(pango.FontDescription("sans 20"))
#Prepare the Progress Bar window for later use
self.progressWindow = Popup(self.builder)
#Display Main Window
self.window = self.builder.get_object("MainWindow")
self.window.show()
if (self.window):
self.window.connect("destroy", self.shutdown)
def shutdown(self, widget):
self.cardChecker.stop()
self.cardChecker.join()
gtk.main_quit()
def digit_clicked(self, widget):
c = widget.get_label()
lbl = self.builder.get_object("txtOutput")
txt = lbl.get_text()
if len(txt) < 6:
lbl.set_text(txt + '*')
self.pin += widget.get_label()
def btnOk_clicked(self, widget):
#Check which radio button is checked, so we know what kind of secret to
#use for PACE
env_arg = os.environ
env_arg["PIN"] = self.pin #We alway use the eID-PIN
#We have to provide the type of secret to use via a command line parameter
param = "--pin"
try:
p = subprocess.Popen(["pace-tool", param, "-v"],
stdout=subprocess.PIPE, env=env_arg, close_fds=True)
except OSError, e:
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK, "pace-tool wurde nicht gefunden.")
popup.run()
popup.destroy()
return
line = p.stdout.readline()
self.progressWindow.show()
while gtk.events_pending():
gtk.main_iteration()
while line:
self.progressWindow.inc_fraction()
while gtk.events_pending():
gtk.main_iteration()
line = p.stdout.readline()
ret = p.poll()
self.progressWindow.hide()
if (ret == 0):
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO,
gtk.BUTTONS_OK, "PIN wurde korrekt eingegeben")
res = popup.run()
gtk.main_quit()
else:
lbl = self.builder.get_object("txtOutput")
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING,
gtk.BUTTONS_OK,
"PIN wurde falsch eingegeben. Bitte erneut versuchen")
res = popup.run()
popup.destroy()
lbl.set_text("")
self.pin = ""
def btnDel_clicked(self, widget):
self.pin = self.pin[:-1]
lbl = self.builder.get_object("txtOutput")
txt = lbl.get_text()
if len(txt) < 6:
lbl.set_text(len(self.pin) * '*')
class Popup(object):
def __init__(self, builder):
self.builder = builder
self.window = self.builder.get_object("progWindow")
self.progbar = self.builder.get_object("progBar")
def show(self):
self.window.show()
def hide(self):
self.window.hide()
def inc_fraction(self):
fraction = self.progbar.get_fraction()
if fraction < 1.0:
fraction += 0.1
else:
fraction = 0.0
self.progbar.set_fraction(fraction)
class cardChecker(Thread):
""" This class searches for a card with a given ATR and displays
wether or not it was found on the label of a widget """
def __init__(self, widget, atr, intervall=1):
Thread.__init__(self)
self._finished = Event()
self.widget = widget
self.targetATR = atr
self.intervall = intervall
def __cardCheck(self):
"""
Actually this method should make use of pyscard, but I couldn't make
it run on the OpenMoko yet. Therefor we call opensc-tool instead, which
leads to higher delays """
try:
p = subprocess.Popen(["opensc-tool", "--atr"], stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
line = p.stdout.readline().rstrip()
if line == self.targetATR:
gobject.idle_add(self.widget.set_label, STR_CARD_FOUND)
else:
gobject.idle_add(self.widget.set_label, STR_NO_CARD)
except OSError, e:
pass #FIXME
def run(self):
while (True):
if self._finished.isSet(): return
self.__cardCheck()
self._finished.wait(self.intervall)
def stop(self):
self._finished.set()
if __name__ == "__main__":
gobject.threads_init()
pinpad = PinpadGTK()
gtk.main()