-Lots of refactoring
-Only start the card polling thread when the pinpad is shown -Added an info button to all entrys in the CertificateDescriptionWindow that might not be clear to the user git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@226 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -7,16 +7,17 @@ try:
|
|||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require("2.0")
|
pygtk.require("2.0")
|
||||||
import gtk, gobject, glib, pango
|
import gtk, gobject, glib, pango
|
||||||
except:
|
except ImportError:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pace
|
import pace
|
||||||
except:
|
except ImportError:
|
||||||
print >> sys.stderr, "Could not import pace module, please install pyPACE"
|
print >> sys.stderr, "Could not import pace module, please install pyPACE"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
from pace_gui_globals import *
|
from pace_gui_globals import AT_CHAT_STRINGS, STR_CARD_FOUND, STR_NO_CARD, IMAGES #FIXME:Fuckup
|
||||||
|
import pace_gui_globals as gui_globals
|
||||||
|
|
||||||
class MokoWindow(gtk.Window):
|
class MokoWindow(gtk.Window):
|
||||||
"""
|
"""
|
||||||
@@ -101,6 +102,9 @@ class MokoWindow(gtk.Window):
|
|||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
class CertificateDescriptionWindow(MokoWindow):
|
class CertificateDescriptionWindow(MokoWindow):
|
||||||
|
"""This window is used to display information about the service provider,
|
||||||
|
extracted from the terminal certificate and the appendant certificate
|
||||||
|
description"""
|
||||||
|
|
||||||
def __init__(self, binDescription, binCert):
|
def __init__(self, binDescription, binCert):
|
||||||
super(CertificateDescriptionWindow, self).__init__("Dienstanbieter", None)
|
super(CertificateDescriptionWindow, self).__init__("Dienstanbieter", None)
|
||||||
@@ -208,8 +212,8 @@ class CVCWindow(MokoWindow):
|
|||||||
chat = pace.cvc_get_chat(cvc)
|
chat = pace.cvc_get_chat(cvc)
|
||||||
self.chat = pace.get_binary_chat(chat)
|
self.chat = pace.get_binary_chat(chat)
|
||||||
self.rel_auth = []
|
self.rel_auth = []
|
||||||
for c in self.chat:
|
for char in self.chat:
|
||||||
self.rel_auth.append(ord(c))
|
self.rel_auth.append(ord(char))
|
||||||
self.rel_auth_len = len(self.rel_auth)
|
self.rel_auth_len = len(self.rel_auth)
|
||||||
|
|
||||||
#Extract the access rights from the CHAT and display them in the window
|
#Extract the access rights from the CHAT and display them in the window
|
||||||
@@ -219,7 +223,7 @@ class CVCWindow(MokoWindow):
|
|||||||
if (i % 8 == 0):
|
if (i % 8 == 0):
|
||||||
j += 1
|
j += 1
|
||||||
if self.rel_auth[self.rel_auth_len - j] & (1 << (i % 8)):
|
if self.rel_auth[self.rel_auth_len - j] & (1 << (i % 8)):
|
||||||
chk = customCheckButton(AT_CHAT_STRINGS[i], i, self.body)
|
chk = customCheckButton(i, self.body)
|
||||||
self.access_rights.append(chk)
|
self.access_rights.append(chk)
|
||||||
|
|
||||||
def btnForward_clicked(self, widget, data=None):
|
def btnForward_clicked(self, widget, data=None):
|
||||||
@@ -238,11 +242,13 @@ class CVCWindow(MokoWindow):
|
|||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
def __formatHexString(self, int_list):
|
def __formatHexString(self, int_list):
|
||||||
|
"""Take a list of integers and convert it to a hex string, where the
|
||||||
|
individual bytes are seperated by a colon (e.g. "0f:00:00")"""
|
||||||
hex_str = ""
|
hex_str = ""
|
||||||
for i in int_list:
|
for i in int_list:
|
||||||
c = hex(i)[2:]
|
byte = hex(i)[2:]
|
||||||
if len(c) == 1: c = "0" + c
|
if len(byte) == 1: byte = "0" + byte
|
||||||
hex_str += c + ":"
|
hex_str += byte + ":"
|
||||||
|
|
||||||
return hex_str[:-1]
|
return hex_str[:-1]
|
||||||
|
|
||||||
@@ -251,26 +257,41 @@ class customCheckButton(object):
|
|||||||
The main difference isthat the checkbox can be placed at the right
|
The main difference isthat the checkbox can be placed at the right
|
||||||
side of the label and that we can store an index with the button"""
|
side of the label and that we can store an index with the button"""
|
||||||
|
|
||||||
def __init__(self, label, index, vbox):
|
def __init__(self, index, vbox):
|
||||||
|
self.idx = index
|
||||||
|
#Fetch name and (possibly empty) helptext
|
||||||
|
strings = AT_CHAT_STRINGS[index]
|
||||||
|
self.label = strings[0]
|
||||||
|
self.helptext = strings[1]
|
||||||
|
|
||||||
#Setup a label with the name of the access right
|
#Setup a label with the name of the access right
|
||||||
self.lbl = gtk.Label(label)
|
self.lbl = gtk.Label(self.label)
|
||||||
self.lbl.set_alignment(0.0, 0.5)
|
self.lbl.set_alignment(0.0, 0.5)
|
||||||
self.lbl.set_padding(20, 0)
|
self.lbl.set_padding(20, 0)
|
||||||
self.lbl.modify_font(pango.FontDescription("bold"))
|
self.lbl.modify_font(pango.FontDescription("bold"))
|
||||||
|
|
||||||
#an image at the left side of the label
|
#If we have a helptext, put an image at the left side of the label
|
||||||
self.img = gtk.Image()
|
self.info_box = None
|
||||||
self.img.set_from_file(image_dir + "/info.png")
|
if self.helptext is not None:
|
||||||
|
self.info_box = gtk.EventBox()
|
||||||
|
img = gtk.Image()
|
||||||
|
img.set_from_file(IMAGES["info"])
|
||||||
|
self.info_box.add(img)
|
||||||
|
self.info_box.connect("button_release_event", self._show_info)
|
||||||
|
|
||||||
#...and a checkbox on the right side of the label
|
#...and a checkbox on the right side of the label
|
||||||
self.idx = index
|
|
||||||
self.chk = gtk.CheckButton("")
|
self.chk = gtk.CheckButton("")
|
||||||
self.chk.set_active(True)
|
self.chk.set_active(True)
|
||||||
self.chk.set_alignment(1.0, 0.5)
|
self.chk.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
#Insert the label and the checkbox in the vbox and add a seperator
|
#Insert the label and the checkbox in the vbox and add a seperator
|
||||||
hbox = gtk.HBox()
|
hbox = gtk.HBox()
|
||||||
hbox.pack_start(self.img, False, False)
|
if self.info_box is not None:
|
||||||
|
hbox.pack_start(self.info_box, False, False)
|
||||||
|
else: #pack empty label for spacing
|
||||||
|
spacer = gtk.Label("")
|
||||||
|
spacer.set_size_request(32, 32)
|
||||||
|
hbox.pack_start(spacer, False, False)
|
||||||
hbox.pack_start(self.lbl, True, True)
|
hbox.pack_start(self.lbl, True, True)
|
||||||
hbox.pack_start(self.chk, False, False)
|
hbox.pack_start(self.chk, False, False)
|
||||||
vbox.pack_start(gtk.HSeparator())
|
vbox.pack_start(gtk.HSeparator())
|
||||||
@@ -279,6 +300,11 @@ class customCheckButton(object):
|
|||||||
def is_active(self):
|
def is_active(self):
|
||||||
return self.chk.get_active()
|
return self.chk.get_active()
|
||||||
|
|
||||||
|
def _show_info(self, widget=None, data=None):
|
||||||
|
"""Show a messagebox containing info about the access right in
|
||||||
|
question"""
|
||||||
|
print self.helptext
|
||||||
|
|
||||||
class PinpadGTK:
|
class PinpadGTK:
|
||||||
"""This a simple GTK based GUI to enter a PIN/PUK/CAN"""
|
"""This a simple GTK based GUI to enter a PIN/PUK/CAN"""
|
||||||
|
|
||||||
@@ -297,23 +323,23 @@ class PinpadGTK:
|
|||||||
self.secret_len = 10
|
self.secret_len = 10
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknwon secret type: %s" % self.secret)
|
raise ValueError("Unknwon secret type: %s" % self.secret)
|
||||||
gtk.main_quit()
|
#gtk.main_quit()
|
||||||
self.chat = chat
|
self.chat = chat
|
||||||
self.cert = cert
|
self.cert = cert
|
||||||
|
|
||||||
#Set the Glade file
|
#Set the Glade file
|
||||||
self.gladefile = glade_dir + "/pinpad.glade"
|
self.gladefile = gui_globals.GLADE_FILE
|
||||||
self.builder = gtk.Builder()
|
self.builder = gtk.Builder()
|
||||||
try:
|
try:
|
||||||
self.builder.add_from_file(self.gladefile)
|
self.builder.add_from_file(self.gladefile)
|
||||||
except glib.GError, e:
|
except glib.GError, err:
|
||||||
#If we encounter an exception at startup, we display a popup with
|
#If we encounter an exception at startup, we display a popup with
|
||||||
#the error message
|
#the error message
|
||||||
popup = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
|
popup = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
|
||||||
gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, e.message)
|
gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, err.message)
|
||||||
popup.run()
|
popup.run()
|
||||||
popup.destroy()
|
popup.destroy()
|
||||||
raise e
|
raise err
|
||||||
|
|
||||||
#Get the Main Window, and connect the "destroy" event
|
#Get the Main Window, and connect the "destroy" event
|
||||||
#Create our dictionay and connect it
|
#Create our dictionay and connect it
|
||||||
@@ -344,10 +370,11 @@ class PinpadGTK:
|
|||||||
lbl_cardStatus = self.builder.get_object("lbl_cardStatus")
|
lbl_cardStatus = self.builder.get_object("lbl_cardStatus")
|
||||||
#Fetch the status image
|
#Fetch the status image
|
||||||
img_cardStatus = self.builder.get_object("img_cardStatus")
|
img_cardStatus = self.builder.get_object("img_cardStatus")
|
||||||
img_cardStatus.set_from_file(image_dir + "/error.png")
|
img_cardStatus.set_from_file(IMAGES["error"])
|
||||||
|
|
||||||
self.cardChecker = cardChecker(lbl_cardStatus, img_cardStatus, ePA_ATR)
|
#We only start the thread for polling the card when the window
|
||||||
gobject.idle_add(self.cardChecker.start)
|
#is shown
|
||||||
|
self.cardChecker = None
|
||||||
|
|
||||||
#Change the font for the buttons
|
#Change the font for the buttons
|
||||||
#For this you have to retrieve the label of each button and change
|
#For this you have to retrieve the label of each button and change
|
||||||
@@ -372,6 +399,11 @@ class PinpadGTK:
|
|||||||
self.window.hide()
|
self.window.hide()
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
|
"""Start the polling thread, then show the window"""
|
||||||
|
if self.cardChecker is None:
|
||||||
|
self.cardChecker = cardChecker(lbl_cardStatus, img_cardStatus,
|
||||||
|
gui_globals.ePA_ATR)
|
||||||
|
gobject.idle_add(self.cardChecker.start)
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
def set_chat(self, chat):
|
def set_chat(self, chat):
|
||||||
@@ -379,8 +411,9 @@ class PinpadGTK:
|
|||||||
|
|
||||||
def shutdown(self, widget):
|
def shutdown(self, widget):
|
||||||
"""Stop the cardChecker thread before exiting the application"""
|
"""Stop the cardChecker thread before exiting the application"""
|
||||||
self.cardChecker.stop()
|
if self.cardChecker is not None:
|
||||||
self.cardChecker.join()
|
self.cardChecker.stop()
|
||||||
|
self.cardChecker.join()
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
def digit_clicked(self, widget):
|
def digit_clicked(self, widget):
|
||||||
@@ -442,9 +475,9 @@ class PinpadGTK:
|
|||||||
try:
|
try:
|
||||||
#Stop polling the card while PACE is running
|
#Stop polling the card while PACE is running
|
||||||
self.cardChecker.pause()
|
self.cardChecker.pause()
|
||||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env_args,
|
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env_args,
|
||||||
close_fds=True)
|
close_fds=True)
|
||||||
except OSError, e:
|
except OSError:
|
||||||
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,
|
||||||
gtk.BUTTONS_OK, "pace-tool wurde nicht gefunden.")
|
gtk.BUTTONS_OK, "pace-tool wurde nicht gefunden.")
|
||||||
@@ -455,7 +488,7 @@ class PinpadGTK:
|
|||||||
|
|
||||||
#Show the animation to indicate that the program is not dead
|
#Show the animation to indicate that the program is not dead
|
||||||
waiting = gtk.Window(gtk.WINDOW_POPUP)
|
waiting = gtk.Window(gtk.WINDOW_POPUP)
|
||||||
animation = gtk.gdk.PixbufAnimation(image_dir + "/wait.gif")
|
animation = gtk.gdk.PixbufAnimation(IMAGES["wait"])
|
||||||
img = gtk.Image()
|
img = gtk.Image()
|
||||||
img.set_from_animation(animation)
|
img.set_from_animation(animation)
|
||||||
waiting.add(img)
|
waiting.add(img)
|
||||||
@@ -466,14 +499,14 @@ class PinpadGTK:
|
|||||||
waiting.show_all()
|
waiting.show_all()
|
||||||
|
|
||||||
#Try to keep the GUI responsive by taking care of the event queue
|
#Try to keep the GUI responsive by taking care of the event queue
|
||||||
line = p.stdout.readline()
|
line = proc.stdout.readline()
|
||||||
while line:
|
while line:
|
||||||
while gtk.events_pending():
|
while gtk.events_pending():
|
||||||
gtk.main_iteration()
|
gtk.main_iteration()
|
||||||
line = p.stdout.readline()
|
line = proc.stdout.readline()
|
||||||
|
|
||||||
#Get the return value of the pace-tool process
|
#Get the return value of the pace-tool process
|
||||||
ret = p.poll()
|
ret = proc.poll()
|
||||||
waiting.destroy()
|
waiting.destroy()
|
||||||
self.cardChecker.resume()
|
self.cardChecker.resume()
|
||||||
|
|
||||||
@@ -514,10 +547,10 @@ class cardChecker(Thread):
|
|||||||
self._paused = Event()
|
self._paused = Event()
|
||||||
self.lbl = lbl
|
self.lbl = lbl
|
||||||
self.img = img
|
self.img = img
|
||||||
self.targetATR = atr
|
self.target_atr = atr
|
||||||
self.intervall = intervall
|
self.intervall = intervall
|
||||||
|
|
||||||
def __cardCheck(self):
|
def _check_card(self):
|
||||||
"""
|
"""
|
||||||
Actually this method should make use of pyscard, but I couldn't make
|
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
|
it run on the OpenMoko yet. Therefor we call opensc-tool instead, which
|
||||||
@@ -527,12 +560,12 @@ class cardChecker(Thread):
|
|||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
||||||
|
|
||||||
line = proc.stdout.readline().rstrip()
|
line = proc.stdout.readline().rstrip()
|
||||||
if line == self.targetATR:
|
if line == self.target_atr:
|
||||||
gobject.idle_add(self.lbl.set_label, STR_CARD_FOUND)
|
gobject.idle_add(self.lbl.set_label, STR_CARD_FOUND)
|
||||||
gobject.idle_add(self.img.set_from_file, FILE_CARD_FOUND)
|
gobject.idle_add(self.img.set_from_file, IMAGES["apply"])
|
||||||
else:
|
else:
|
||||||
gobject.idle_add(self.lbl.set_label, STR_NO_CARD)
|
gobject.idle_add(self.lbl.set_label, STR_NO_CARD)
|
||||||
gobject.idle_add(self.img.set_from_file, FILE_NO_CARD)
|
gobject.idle_add(self.img.set_from_file, IMAGES["error"])
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Main loop: Poll the card if the thread is not paused or finished"""
|
"""Main loop: Poll the card if the thread is not paused or finished"""
|
||||||
@@ -541,7 +574,7 @@ class cardChecker(Thread):
|
|||||||
return
|
return
|
||||||
if self._paused.isSet():
|
if self._paused.isSet():
|
||||||
continue
|
continue
|
||||||
self.__cardCheck()
|
self._check_card()
|
||||||
self._finished.wait(self.intervall)
|
self._finished.wait(self.intervall)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
@@ -555,5 +588,6 @@ class cardChecker(Thread):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gobject.threads_init()
|
gobject.threads_init()
|
||||||
CertificateDescriptionWindow(TEST_DESCRIPTION, TEST_CVC)
|
CertificateDescriptionWindow(gui_globals.TEST_DESCRIPTION,
|
||||||
|
gui_globals.TEST_CVC)
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ version = "@VERSION@"
|
|||||||
image_dir = "@prefix@/share/" + name
|
image_dir = "@prefix@/share/" + name
|
||||||
glade_dir = "@prefix@/share/" + name
|
glade_dir = "@prefix@/share/" + name
|
||||||
|
|
||||||
|
GLADE_FILE = glade_dir + "/pinpad.glade"
|
||||||
|
|
||||||
STR_NO_CARD = "<span fgcolor=\"red\" font=\"12\">Ausweis</span>"
|
STR_NO_CARD = "<span fgcolor=\"red\" font=\"12\">Ausweis</span>"
|
||||||
STR_CARD_FOUND = "<span fgcolor=\"green\" font=\"12\">Ausweis</span>"
|
STR_CARD_FOUND = "<span fgcolor=\"green\" font=\"12\">Ausweis</span>"
|
||||||
|
|
||||||
@@ -13,46 +15,76 @@ FILE_CARD_FOUND = image_dir + "/apply.png"
|
|||||||
|
|
||||||
ePA_ATR = "3b:84:80:01:00:00:90:00:95"
|
ePA_ATR = "3b:84:80:01:00:00:90:00:95"
|
||||||
|
|
||||||
AT_CHAT_STRINGS = [
|
#The following strings are used as help texts for eID access rights
|
||||||
"Altersverifikation", #Age Verification
|
DOC_AGE_VERIFICATION = "foo"
|
||||||
u"Gemeindeschlüssel Verifikation", #Community ID Verification
|
DOC_COMMUNITY_ID_VERIFICATION = "foo"
|
||||||
"Pseudonymfunktion", #Restrictied Identification
|
DOC_RESTRICTED_ID = "foo"
|
||||||
"Priviligiertes Terminal", #Privileged Terminal
|
DOC_PRIVILEGED_TERMINAL = "foo"
|
||||||
"Verwendung der CAN", #CAN allowed
|
DOC_CAN_ALLOWED = "foo"
|
||||||
"PIN Managment",
|
DOC_PIN_MANAGMENT = "foo"
|
||||||
"Zertifikat einspielen", #Install Certificate
|
DOC_INSTALL_CERTIFICATE = "foo"
|
||||||
"Qualifiziertes Zertifikat einspielen", #Install Qualified Certificate
|
DOC_INSTALL_QC = "foo"
|
||||||
"Dokumenttyp lesen", #Read DG 1
|
DOC_DOCUMENT_TYPE = "foo"
|
||||||
"Staat lesen", #Read DG 2
|
DOC_STATE = "foo"
|
||||||
"Ablaufdatum lesen", #Read DG 3
|
DOC_EXPIRY_DATE = "foo"
|
||||||
"Vorname lesen", #Read DG 4
|
|
||||||
"Nachname lesen", #Read DG 5
|
IMAGES = {
|
||||||
u"Künstlername lesen", #Read DG 6
|
"apply": image_dir + "/apply.png",
|
||||||
"Doktorgrad lesen", #Read DG 7
|
"error": image_dir + "/error.png",
|
||||||
"Geburtsdatum lesen", #Read DG 8
|
"info" : image_dir + "/info.png",
|
||||||
"Geburtsort lesen", #Read DG 9
|
"wait" : image_dir + "/wait.gif"
|
||||||
u"Ungültig", #Read DG 10
|
}
|
||||||
u"Ungültig", #Read DG 11
|
|
||||||
u"Ungültig", #Read DG 12
|
#Authentication Terminal CHAT
|
||||||
u"Ungültig", #Read DG 13
|
AT_CHAT_STRINGS = {
|
||||||
u"Ungültig", #Read DG 14
|
#Age Verification
|
||||||
u"Ungültig", #Read DG 15
|
0: ("Altersverifikation", DOC_AGE_VERIFICATION),
|
||||||
u"Ungültig", #Read DG 16
|
#Community ID Verification
|
||||||
"Adresse lesen", #Read DG 17
|
1: (u"Gemeindeschlüssel Verifikation", DOC_COMMUNITY_ID_VERIFICATION),
|
||||||
u"Gemeindeschlüssel lesen", #Read DG 18
|
#Restrictied Identification
|
||||||
u"Ungültig", #Read DG 19
|
2: ("Pseudonymfunktion", DOC_RESTRICTED_ID),
|
||||||
u"Ungültig", #Read DG 20
|
#Privileged Terminal
|
||||||
u"Ungültig", #Read DG 21
|
3: ("Priviligiertes Terminal", DOC_PRIVILEGED_TERMINAL),
|
||||||
u"Ungültig", #RFU
|
#CAN allowed
|
||||||
u"Ungültig", #RFU
|
4: ("Verwendung der CAN", DOC_CAN_ALLOWED),
|
||||||
u"Ungültig", #RFU
|
5: ("PIN Managment", DOC_PIN_MANAGMENT),
|
||||||
u"Ungültig", #RFU
|
#Install Certificate
|
||||||
u"Ungültig", #Write DG 21
|
6: ("Zertifikat einspielen", DOC_INSTALL_CERTIFICATE),
|
||||||
u"Ungültig", #Write DG 20
|
#Install Qualified Certificate
|
||||||
u"Ungültig", #Write DG 19
|
7: ("Qualifiziertes Zertifikat einspielen", DOC_INSTALL_QC),
|
||||||
u"Gemeindeschlüssel schreiben", #Write DG 18
|
#Read DG 1
|
||||||
u"Adresse schreiben", #Write DG 17"
|
8: ("Dokumenttyp", DOC_DOCUMENT_TYPE),
|
||||||
]
|
#Read DG 2
|
||||||
|
9: ("Ausstellender Staat", DOC_STATE),
|
||||||
|
10: ("Ablaufdatum", DOC_EXPIRY_DATE), #Read DG 3
|
||||||
|
11: ("Vorname", None), #Read DG 4
|
||||||
|
12: ("Nachname", None), #Read DG 5
|
||||||
|
13: (u"Künstlername", None), #Read DG 6
|
||||||
|
14: ("Doktorgrad", None), #Read DG 7
|
||||||
|
15: ("Geburtsdatum", None), #Read DG 8
|
||||||
|
16: ("Geburtsort", None), #Read DG 9
|
||||||
|
17: (u"Ungültig", None), #Read DG 10
|
||||||
|
18: (u"Ungültig", None), #Read DG 11
|
||||||
|
19: (u"Ungültig", None),#Read DG 12
|
||||||
|
20: (u"Ungültig", None),#Read DG 13
|
||||||
|
21: (u"Ungültig", None),#Read DG 14
|
||||||
|
22: (u"Ungültig", None),#Read DG 15
|
||||||
|
23: (u"Ungültig", None),#Read DG 16
|
||||||
|
24: ("Adresse", None), #Read DG 17
|
||||||
|
25: (u"Gemeindeschlüssel lesen", None),#Read DG 18
|
||||||
|
26: (u"Ungültig", None),#Read DG 19
|
||||||
|
27: (u"Ungültig", None),#Read DG 20
|
||||||
|
28: (u"Ungültig", None),#Read DG 21
|
||||||
|
29: (u"Ungültig", None),#RFU
|
||||||
|
30: (u"Ungültig", None),#RFU
|
||||||
|
31: (u"Ungültig", None),#RFU
|
||||||
|
32: (u"Ungültig", None),#RFU
|
||||||
|
33: (u"Ungültig", None),#Write DG 21
|
||||||
|
34: (u"Ungültig", None),#Write DG 20
|
||||||
|
35: (u"Ungültig", None),#Write DG 19
|
||||||
|
36: (u"Gemeindeschlüssel schreiben", None),#Write DG 18
|
||||||
|
37: (u"Adresse schreiben", None)#Write DG 17"
|
||||||
|
}
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user