-Now actually passing the (modified) Chat to PinpadGTK and to pace-tool
-PinpadGTK can now be used with different PACE secrets -Changed the display of entered digits in PinpadGTK. Underscores are used to indicate the length of the secret and are repalce by stars during PIN entry -Bugfix: Added correct thread initialisation -Changed the font size and weight of the status label git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@204 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -271,11 +271,21 @@ class CVCWindow(MokoWindow):
|
|||||||
for right in self.access_rights:
|
for right in self.access_rights:
|
||||||
if not right.is_active():
|
if not right.is_active():
|
||||||
idx = right.idx
|
idx = right.idx
|
||||||
self.chat_array[len(self.chat) - 1 - idx / 8] ^= (1 << (idx % 8))
|
self.rel_auth[len(self.chat) - 1 - idx / 8] ^= (1 << (idx % 8))
|
||||||
|
|
||||||
#super(CVCWindow, self).btnForward_clicked(widget, data)
|
#super(CVCWindow, self).btnForward_clicked(widget, data)
|
||||||
self.hide()
|
self.hide()
|
||||||
PinpadGTK()
|
newCHAT = self.__formatHexString(self.rel_auth)
|
||||||
|
PinpadGTK("pin", newCHAT)
|
||||||
|
|
||||||
|
def __formatHexString(self, int_list):
|
||||||
|
hex_str = ""
|
||||||
|
for i in int_list:
|
||||||
|
c = hex(i)[2:]
|
||||||
|
if len(c) == 1: c = "0" + c
|
||||||
|
hex_str += c + ":"
|
||||||
|
|
||||||
|
return hex_str[:-1]
|
||||||
|
|
||||||
class customCheckButton(object):
|
class customCheckButton(object):
|
||||||
"""This class provides a custom version of gtk.CheckButton.
|
"""This class provides a custom version of gtk.CheckButton.
|
||||||
@@ -308,12 +318,24 @@ class customCheckButton(object):
|
|||||||
class PinpadGTK:
|
class PinpadGTK:
|
||||||
"""This a simple GTK based GUI to enter a PIN"""
|
"""This a simple GTK based GUI to enter a PIN"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, secret="pin", chat=None, cert=None):
|
||||||
btn_names = ["btnOne", "btnTwo", "btnThree", "btnFour", "btnFive",
|
btn_names = ["btnOne", "btnTwo", "btnThree", "btnFour", "btnFive",
|
||||||
"btnSix", "btnSeven", "btnEight", "btnNine", "btnDel",
|
"btnSix", "btnSeven", "btnEight", "btnNine", "btnDel",
|
||||||
"btnZero", "btnOk"]
|
"btnZero", "btnOk"]
|
||||||
|
|
||||||
self.pin = ""
|
self.pin = ""
|
||||||
|
self.secret = secret
|
||||||
|
if self.secret == "pin" or self.secret == "can":
|
||||||
|
self.secret_len = 6
|
||||||
|
elif self.secret == "transport":
|
||||||
|
self.secret_len = 5
|
||||||
|
elif self.secret == "puk":
|
||||||
|
self.secret_len = 10
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknwon secret type: %s" % self.secret)
|
||||||
|
gtk.main_quit()
|
||||||
|
self.chat = chat
|
||||||
|
self.cert = cert
|
||||||
|
|
||||||
#Set the Glade file
|
#Set the Glade file
|
||||||
self.gladefile = glade_dir + "/pinpad.glade"
|
self.gladefile = glade_dir + "/pinpad.glade"
|
||||||
@@ -343,14 +365,16 @@ class PinpadGTK:
|
|||||||
"on_btnZero_clicked" : self.digit_clicked,
|
"on_btnZero_clicked" : self.digit_clicked,
|
||||||
"on_btnOk_clicked" : self.btnOk_clicked,
|
"on_btnOk_clicked" : self.btnOk_clicked,
|
||||||
"on_btnDel_clicked" : self.btnDel_clicked,
|
"on_btnDel_clicked" : self.btnDel_clicked,
|
||||||
"on_MainWindow_destroy_event" : gtk.main_quit,
|
"on_MainWindow_destroy_event" : self.shutdown,
|
||||||
"on_MainWindow_destroy" : gtk.main_quit }
|
"on_MainWindow_destroy" : self.shutdown }
|
||||||
|
|
||||||
self.builder.connect_signals(dic)
|
self.builder.connect_signals(dic)
|
||||||
|
|
||||||
#Change the font for the text field
|
#Change the font for the text field and set it up up properly for the
|
||||||
txtOutput = self.builder.get_object("txtOutput")
|
#type of secret we are using
|
||||||
txtOutput.modify_font(pango.FontDescription("Monospace 16"))
|
self.output = self.builder.get_object("txtOutput")
|
||||||
|
self.output.modify_font(pango.FontDescription("Monospace 16"))
|
||||||
|
self.output.set_text(self.secret_len * "_")
|
||||||
|
|
||||||
#Look for card and set the label accordingly
|
#Look for card and set the label accordingly
|
||||||
lbl_cardStatus = self.builder.get_object("lbl_cardStatus")
|
lbl_cardStatus = self.builder.get_object("lbl_cardStatus")
|
||||||
@@ -390,27 +414,43 @@ class PinpadGTK:
|
|||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
def digit_clicked(self, widget):
|
def digit_clicked(self, widget):
|
||||||
|
"""We indicate the ammount of digits with underscores
|
||||||
|
For every digit that is enterd we replace one underscore with a star
|
||||||
|
We only accept secret_len digits and ignore every additional digit"""
|
||||||
c = widget.get_label()
|
c = widget.get_label()
|
||||||
lbl = self.builder.get_object("txtOutput")
|
txt = self.output.get_text()
|
||||||
txt = lbl.get_text()
|
if len(self.pin) < self.secret_len:
|
||||||
if len(txt) < 6:
|
self.output.set_text(txt.replace("_", "*", 1))
|
||||||
lbl.set_text(txt + '*')
|
|
||||||
self.pin += widget.get_label()
|
self.pin += widget.get_label()
|
||||||
|
|
||||||
def btnOk_clicked(self, widget):
|
def btnOk_clicked(self, widget):
|
||||||
|
|
||||||
#Check which radio button is checked, so we know what kind of secret to
|
env_args = os.environ
|
||||||
#use for PACE
|
cmd = ["pace-tool"] #Contains the command and all the parameters for our subproccess
|
||||||
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
|
#We have to select the type of secret to use via a command line parameter
|
||||||
param = "--pin"
|
#and provide the actual secret via an environment variable
|
||||||
|
if self.secret == "pin" or self.secret == "transport":
|
||||||
|
cmd.append("--pin")
|
||||||
|
env_args["PIN"] = self.pin
|
||||||
|
elif self.secret == "can":
|
||||||
|
cmd.append("--can")
|
||||||
|
env_args["CAN"] = self.pin
|
||||||
|
elif self.secret == "puk":
|
||||||
|
cmd.append("--puk")
|
||||||
|
env_args["PUK"] = self.pin
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown secret type: %s" % self.secret)
|
||||||
|
|
||||||
|
#If we have a CHAT, we pass it to pace-tool
|
||||||
|
if (self.chat):
|
||||||
|
cmd.append("--chat=" + self.chat)
|
||||||
|
|
||||||
|
#Try to call pace-tool. This is a blocking call. A progress bar is being
|
||||||
|
#shown while the subprocess is running
|
||||||
try:
|
try:
|
||||||
self.cardChecker.pause() #Stop polling the card while PACE is running
|
self.cardChecker.pause() #Stop polling the card while PACE is running
|
||||||
p = subprocess.Popen(["pace-tool", param, "-v"],
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env_args, close_fds=True)
|
||||||
stdout=subprocess.PIPE, env=env_arg, close_fds=True)
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
|
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
|
||||||
@@ -420,6 +460,7 @@ class PinpadGTK:
|
|||||||
self.cardChecker.resume() #Restart cardChecker
|
self.cardChecker.resume() #Restart cardChecker
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#Animate the progress bar
|
||||||
line = p.stdout.readline()
|
line = p.stdout.readline()
|
||||||
self.progressWindow.show()
|
self.progressWindow.show()
|
||||||
while gtk.events_pending():
|
while gtk.events_pending():
|
||||||
@@ -430,9 +471,10 @@ class PinpadGTK:
|
|||||||
gtk.main_iteration()
|
gtk.main_iteration()
|
||||||
line = p.stdout.readline()
|
line = p.stdout.readline()
|
||||||
|
|
||||||
|
#Get the return value of the pace-tool process
|
||||||
ret = p.poll()
|
ret = p.poll()
|
||||||
self.progressWindow.hide()
|
self.progressWindow.hide()
|
||||||
self.cardChecker.resume() #Restart cardChecker
|
self.cardChecker.resume()
|
||||||
|
|
||||||
if (ret == 0):
|
if (ret == 0):
|
||||||
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
||||||
@@ -442,23 +484,22 @@ class PinpadGTK:
|
|||||||
popup.destroy()
|
popup.destroy()
|
||||||
self.shutdown() #FIXME
|
self.shutdown() #FIXME
|
||||||
else:
|
else:
|
||||||
lbl = self.builder.get_object("txtOutput")
|
|
||||||
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
popup = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL |
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING,
|
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING,
|
||||||
gtk.BUTTONS_OK,
|
gtk.BUTTONS_OK,
|
||||||
"PIN wurde falsch eingegeben. Bitte erneut versuchen")
|
"PIN wurde falsch eingegeben. Bitte erneut versuchen")
|
||||||
res = popup.run()
|
res = popup.run()
|
||||||
popup.destroy()
|
popup.destroy()
|
||||||
lbl.set_text("")
|
self.output.set_text(self.secret_len * "_")
|
||||||
self.pin = ""
|
self.pin = ""
|
||||||
|
|
||||||
def btnDel_clicked(self, widget):
|
def btnDel_clicked(self, widget):
|
||||||
|
"""Remove one digit from the pin and replace the last * in the output
|
||||||
|
field with an underscore"""
|
||||||
self.pin = self.pin[:-1]
|
self.pin = self.pin[:-1]
|
||||||
lbl = self.builder.get_object("txtOutput")
|
txt = self.output.get_text()
|
||||||
txt = lbl.get_text()
|
idx = txt.rfind("*")
|
||||||
if len(txt) < 6:
|
self.output.set_text(txt[:idx] + "_" + txt[idx + 1:])
|
||||||
lbl.set_text(len(self.pin) * '*')
|
|
||||||
|
|
||||||
|
|
||||||
class Popup(object):
|
class Popup(object):
|
||||||
|
|
||||||
@@ -515,7 +556,7 @@ class cardChecker(Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while (True):
|
while (True):
|
||||||
if self._finished.isSet(): return
|
if self._finished.isSet(): return
|
||||||
if self._paused.isSet(): continue
|
if self._paused.isSet(): continue
|
||||||
self.__cardCheck()
|
self.__cardCheck()
|
||||||
self._finished.wait(self.intervall)
|
self._finished.wait(self.intervall)
|
||||||
|
|
||||||
@@ -529,5 +570,6 @@ class cardChecker(Thread):
|
|||||||
self._paused.clear()
|
self._paused.clear()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
gobject.threads_init()
|
||||||
CertificateDescriptionWindow(TEST_DESCRIPTION, TEST_CVC)
|
CertificateDescriptionWindow(TEST_DESCRIPTION, TEST_CVC)
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ version = "@VERSION@"
|
|||||||
image_dir = "@prefix@/share/pixmaps"
|
image_dir = "@prefix@/share/pixmaps"
|
||||||
glade_dir = "@prefix@/share/" + name
|
glade_dir = "@prefix@/share/" + name
|
||||||
|
|
||||||
STR_NO_CARD = "<span fgcolor=\"red\" font_weight=\"bold\" font=\"11\">Keine Karte\ngefunden</span>"
|
STR_NO_CARD = "<span fgcolor=\"red\" font=\"12\">Keine Karte\ngefunden</span>"
|
||||||
STR_CARD_FOUND = "<span fgcolor=\"green\" font_weight=\"bold\" font=\"11\">Karte gefunden</span>"
|
STR_CARD_FOUND = "<span fgcolor=\"green\" font=\"12\">Karte gefunden</span>"
|
||||||
ePA_ATR = "3b:84:80:01:00:00:90:00:95"
|
ePA_ATR = "3b:84:80:01:00:00:90:00:95"
|
||||||
|
|
||||||
TEST_CVC = "\x7F\x21\x82\x01\x41\x7F\x4E\x81\xFA\x5F\x29\x01\x00\x42\x0D\x5A\x5A\x44\x56\x43\x41\x41\x54\x41\x30\x30\x30\x33\x7F\x49\x4F\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03\x86\x41\x04\x19\xD1\x75\x45\xD3\xFE\x0B\x34\x3E\x7E\xE2\xAE\x4E\x2B\xC9\x2D\x51\x35\x1C\xC1\x17\xA4\x7F\xA9\x51\x9A\xDB\x1E\x40\x5E\xE6\xB8\x12\x12\x80\xBC\xC2\xFF\xF0\x35\x7A\x19\x7D\xE7\x39\xA7\xFD\x2E\xF0\x22\x10\xEF\x34\x3C\xDB\xE7\x9E\xF9\x4B\x8E\x28\x59\x1B\xB9\x5F\x20\x0B\x5A\x5A\x44\x4B\x42\x32\x30\x30\x30\x30\x52\x7F\x4C\x12\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x02\x02\x53\x05\x00\x03\x01\xDF\x04\x5F\x25\x06\x01\x00\x00\x02\x01\x07\x5F\x24\x06\x01\x00\x00\x03\x03\x01\x65\x5E\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x80\x20\x75\xE0\xC4\xAC\x36\xC2\x5A\x33\xAC\x0E\x9A\x75\xEB\x79\x2A\x72\xF3\x31\xA5\x1E\x28\x63\x4E\xCC\x2E\xD6\x2E\x54\xF3\xC6\x93\xDA\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x02\x80\x20\x18\x12\x65\x74\x49\xFC\xF1\xD3\xDA\xD8\x3D\x13\x14\x29\x17\x5C\x61\x8B\x21\xBA\xF0\xAF\x44\xAC\xE3\x8C\xB2\xC1\x2C\xEB\x2A\x56\x5F\x37\x40\x54\x0F\x85\x09\x12\xAB\xD3\x51\xF8\xF5\x56\x9B\x53\x4A\x5C\x8F\x64\x54\x5B\x51\xA7\x34\x70\xBE\x5A\xD2\x89\xC1\x9A\x5E\x13\x52\x53\xD3\xBB\x15\x52\x26\x21\x7B\x41\xE7\xF0\x68\xB3\x52\x3F\x3A\x63\x92\x22\xAF\x2B\x62\x8C\x39\x7D\x4F\xD4\x02\x1E\xDE\x00\xDC"
|
TEST_CVC = "\x7F\x21\x82\x01\x41\x7F\x4E\x81\xFA\x5F\x29\x01\x00\x42\x0D\x5A\x5A\x44\x56\x43\x41\x41\x54\x41\x30\x30\x30\x33\x7F\x49\x4F\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03\x86\x41\x04\x19\xD1\x75\x45\xD3\xFE\x0B\x34\x3E\x7E\xE2\xAE\x4E\x2B\xC9\x2D\x51\x35\x1C\xC1\x17\xA4\x7F\xA9\x51\x9A\xDB\x1E\x40\x5E\xE6\xB8\x12\x12\x80\xBC\xC2\xFF\xF0\x35\x7A\x19\x7D\xE7\x39\xA7\xFD\x2E\xF0\x22\x10\xEF\x34\x3C\xDB\xE7\x9E\xF9\x4B\x8E\x28\x59\x1B\xB9\x5F\x20\x0B\x5A\x5A\x44\x4B\x42\x32\x30\x30\x30\x30\x52\x7F\x4C\x12\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x02\x02\x53\x05\x00\x03\x01\xDF\x04\x5F\x25\x06\x01\x00\x00\x02\x01\x07\x5F\x24\x06\x01\x00\x00\x03\x03\x01\x65\x5E\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x80\x20\x75\xE0\xC4\xAC\x36\xC2\x5A\x33\xAC\x0E\x9A\x75\xEB\x79\x2A\x72\xF3\x31\xA5\x1E\x28\x63\x4E\xCC\x2E\xD6\x2E\x54\xF3\xC6\x93\xDA\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x02\x80\x20\x18\x12\x65\x74\x49\xFC\xF1\xD3\xDA\xD8\x3D\x13\x14\x29\x17\x5C\x61\x8B\x21\xBA\xF0\xAF\x44\xAC\xE3\x8C\xB2\xC1\x2C\xEB\x2A\x56\x5F\x37\x40\x54\x0F\x85\x09\x12\xAB\xD3\x51\xF8\xF5\x56\x9B\x53\x4A\x5C\x8F\x64\x54\x5B\x51\xA7\x34\x70\xBE\x5A\xD2\x89\xC1\x9A\x5E\x13\x52\x53\xD3\xBB\x15\x52\x26\x21\x7B\x41\xE7\xF0\x68\xB3\x52\x3F\x3A\x63\x92\x22\xAF\x2B\x62\x8C\x39\x7D\x4F\xD4\x02\x1E\xDE\x00\xDC"
|
||||||
|
|||||||
@@ -39,9 +39,9 @@
|
|||||||
<object class="GtkEntry" id="txtOutput">
|
<object class="GtkEntry" id="txtOutput">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="editable">False</property>
|
<property name="editable">False</property>
|
||||||
|
<property name="max_length">10</property>
|
||||||
<property name="invisible_char">●</property>
|
<property name="invisible_char">●</property>
|
||||||
<property name="width_chars">0</property>
|
<property name="width_chars">0</property>
|
||||||
<property name="xalign">0.5</property>
|
|
||||||
<property name="truncate_multiline">True</property>
|
<property name="truncate_multiline">True</property>
|
||||||
<property name="shadow_type">out</property>
|
<property name="shadow_type">out</property>
|
||||||
<property name="invisible_char_set">True</property>
|
<property name="invisible_char_set">True</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user