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()
Beispiel #2
0
class ReaderManager( ReaderObserver ):
    """A simple reader observer that is notified
    when readers are added/removed from the system and
    prints the list of readers
    """
    
    def __init__(self):
        self.readermonitor = ReaderMonitor()
        self.enable = False
        self.readermonitor.addObserver( self )
        
    def update( self, observable, (addedreaders, removedreaders) ):
        r = ""
        if addedreaders != None and len(addedreaders) > 0:
            r += "Added readers" + str(addedreaders) 
        
        if removedreaders != None and len(removedreaders) > 0:
            
            if len(r) > 0:
                r += "\n"
            
            r += "Removed readers" + str(removedreaders)
            
            if "connectedReader" in Executer.envi:
                for reader in removedreaders:
                    if reader == Executer.envi["connectedReader"]:
                        disconnectReaderFromCardFun(Executer.envi)
                        Executer.printAsynchronousOnShell("WARNING : the reader has been removed, the connection is broken")

        if self.enable and len(r) > 0:
            Executer.printAsynchronousOnShell(r)
class ReaderManager(ReaderObserver):
    """A simple reader observer that is notified
    when readers are added/removed from the system and
    prints the list of readers
    """
    def __init__(self):
        self.readermonitor = ReaderMonitor()
        self.enable = False
        self.readermonitor.addObserver(self)

    def update(self, observable, (addedreaders, removedreaders)):
        r = ""
        if addedreaders != None and len(addedreaders) > 0:
            r += "Added readers" + str(addedreaders)

        if removedreaders != None and len(removedreaders) > 0:

            if len(r) > 0:
                r += "\n"

            r += "Removed readers" + str(removedreaders)

            if "connectedReader" in Executer.envi:
                for reader in removedreaders:
                    if reader == Executer.envi["connectedReader"]:
                        disconnectReaderFromCardFun(Executer.envi)
                        Executer.printAsynchronousOnShell(
                            "WARNING : the reader has been removed, the connection is broken"
                        )

        if self.enable and len(r) > 0:
            Executer.printAsynchronousOnShell(r)
Beispiel #4
0
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, (addedreaders, removedreaders)):
        """Toolbar ReaderObserver callback that is notified when
        readers are added or removed."""
        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()
    def testcase_readermonitorthread(self):

        # create thread that simulates reader insertion
        insertionthread = readerInsertionThread()

        # create thread that simulates reader removal
        removalthread = readerRemovalThread()

        readermonitor = ReaderMonitor(readerProc=getReaders, period=period)
        observers = []
        for i in range(0, OBS_COUNT):
            observer = countobserver(i)
            readermonitor.addObserver(observer)
            observers.append(observer)

        # signal threads to start
        insertionthread.start()
        removalthread.start()

        # let reader insertion/removal threads run for a while
        # then signal threads to end
        time.sleep(RUNNING_TIME)
        exitEvent.set()

        # wait until all threads ended
        removalthread.join()
        insertionthread.join()
        time.sleep(2 * period)

        for observer in observers:
            self.assertEqual(
                observer.insertedreaderstats, insertedreaderstats)
            self.assertEqual(
                observer.removedreaderstats, removedreaderstats)
    def testcase_readermonitorthread(self):

        # create thread that simulates reader insertion
        insertionthread = readerInsertionThread()

        # create thread that simulates reader removal
        removalthread = readerRemovalThread()

        readermonitor = ReaderMonitor(readerProc=getReaders, period=period)
        observers = []
        for i in range(0, OBS_COUNT):
            observer = countobserver(i)
            readermonitor.addObserver(observer)
            observers.append(observer)

        # signal threads to start
        insertionthread.start()
        removalthread.start()

        # let reader insertion/removal threads run for a while
        # then signal threads to end
        time.sleep(RUNNING_TIME)
        exitEvent.set()

        # wait until all threads ended
        removalthread.join()
        insertionthread.join()
        time.sleep(2 * period)

        for observer in observers:
            self.assertEquals(observer.insertedreaderstats,
                              insertedreaderstats)
            self.assertEquals(observer.removedreaderstats, removedreaderstats)
    class testthread(Thread):
        def __init__(self, obsindex):
            Thread.__init__(self)
            self.readermonitor = ReaderMonitor()
            self.obsindex = obsindex
            self.observer = None

        def run(self):
            # create and register observer
            self.observer = printobserver(self.obsindex)
            self.readermonitor.addObserver(self.observer)
            sleep(20)
            self.readermonitor.deleteObserver(self.observer)
    class testthread(Thread):
        def __init__(self, obsindex):
            Thread.__init__(self)
            self.readermonitor = ReaderMonitor()
            self.obsindex = obsindex
            self.observer = None

        def run(self):
            # create and register observer
            self.observer = printobserver(self.obsindex)
            self.readermonitor.addObserver(self.observer)
            sleep(20)
            self.readermonitor.deleteObserver(self.observer)
Beispiel #9
0
class _CcidReaderObserver(ReaderObserver):
    def __init__(self, controller):
        self._controller = weakref.ref(controller)
        self._monitor = ReaderMonitor()
        self._monitor.addObserver(self)

    def update(self, observable, tup):
        (added, removed) = tup
        c = self._controller()
        if c:
            c._update(added, removed)

    def delete(self):
        self._monitor.deleteObservers()
Beispiel #10
0
class testthread(threading.Thread):
    def __init__(self, obsindex, testcase):
        threading.Thread.__init__(self)
        self.obsindex = obsindex
        self.testcase = testcase
        self.readermonitor = ReaderMonitor()
        self.observer = None

    def run(self):
        # create and register observer
        self.observer = printobserver(self.obsindex, self.testcase)
        self.readermonitor.addObserver(self.observer)
        time.sleep(1)
        self.readermonitor.deleteObserver(self.observer)
Beispiel #11
0
class _CcidReaderObserver(ReaderObserver):

    def __init__(self, controller):
        self._controller = weakref.ref(controller)
        self._monitor = ReaderMonitor()
        self._monitor.addObserver(self)

    def update(self, observable, tup):
        (added, removed) = tup
        c = self._controller()
        if c:
            c._update(added, removed)

    def delete(self):
        self._monitor.deleteObservers()
Beispiel #12
0
class testthread(threading.Thread):

    def __init__(self, obsindex, testcase):
        threading.Thread.__init__(self)
        self.obsindex = obsindex
        self.testcase = testcase
        self.readermonitor = ReaderMonitor()
        self.observer = None

    def run(self):
        # create and register observer
        self.observer = printobserver(self.obsindex, self.testcase)
        self.readermonitor.addObserver(self.observer)
        time.sleep(1)
        self.readermonitor.deleteObserver(self.observer)
Beispiel #13
0
def entry_point():        
    print u"Smartcard monitor applet by Lauri Võsandi <*****@*****.**>"
    if not os.path.exists(PCSCD):
        print "Unable to find", PCSCD, "are you sure it is installed"
        
    applet = SmartcardApplet()
    reader_monitor = ReaderMonitor()
    reader_monitor.addObserver(applet.reader_observer)
    card_monitor = CardMonitor()
    card_monitor.addObserver(applet.card_observer)
    try:
        gtk.main()
    except KeyboardInterrupt:
        pass
    card_monitor.deleteObserver(applet.card_observer)
    reader_monitor.deleteObserver(applet.reader_observer)
Beispiel #14
0
class ireadyou(object,CardObserver,ReaderObserver):
    GLADE_FILE = "gui/ireadyou/ireadyou.glade"
    
    def __init__(self, ticket = None):
        "Create and show main window."
        self.main_window_xml = gtk.glade.XML(self.GLADE_FILE, "main")
        self.main_window = self.main_window_xml.get_widget("main")
        
        self.card_tabs = self.main_window_xml.get_widget("card_tabs")
        while self.card_tabs.get_n_pages() > 0:
            self.card_tabs.remove_page(0)
        for t in self.CARD_TYPES:
            a, b, l = gtk.Alignment(yscale=1,xscale=1,xalign=0.5,yalign=0.5), gtk.VBox(), gtk.Label(t[1])
            a.add(b)
            a.show()
            b.show()
            l.show()
            
            self.card_tabs.append_page(a, tab_label=l)
        
        self.ticket_button_group = gtk.RadioButton()
        self.ticket_button_group._ticket = None
        
        self.status_area = self.main_window_xml.get_widget("status_area")
        self.known_readers = []
        self.known_cards = {} # Note stupid: the keys to this dict are not objects from the known_readers list but rather reader name strings
        self.connected_cards = {} # Again: the keys are not cards but repr(card)
        self.tickets = {} # ditto
        self.ticket_displayed = None # This is either None or a tuple (card object, ticket object)
        
        self._update_status()
        
        self.logbuf = FileLikeTextBuffer()
        sys.stdout = self.logbuf.for_stream(sys.stdout)
        sys.stderr = self.logbuf.for_stream(sys.stderr)
        self.logview = self.main_window_xml.get_widget("logview")
        self.logview.set_buffer(self.logbuf.buffer)
        self.logbuf.add_view(self.logview)
        
        signals = {
            "on_exit_clicked": self.exit_clicked,
            "on_main_delete_event": self.exit_clicked,
            "on_main_destroy": gtk.main_quit,
        }
        self.main_window_xml.signal_autoconnect(signals)
        
        self._clear_display()
        
        self.rmon = ReaderMonitor()
        self.cmon = CardMonitor()
        
        self.rmon.addObserver(self)
        self.cmon.addObserver(self)
    
    def _clear_display(self):
        self.card_tabs.set_current_page(0)
        
        for i in range(self.card_tabs.get_n_pages()):
            a = self.card_tabs.get_nth_page(i)
            vbox = a.get_child()
            for c in vbox.get_children():
                vbox.remove(c)
            label = self.card_tabs.get_tab_label(a)
            label.set_property("sensitive", False)
    
    def _update_status(self):
        for c in self.status_area.get_children():
            self.status_area.remove(c)
        
        if len(self.known_readers) == 0:
            self.status_area.add( gtk.Label(u"Keine Lesegeräte angeschlossen.") )
        else:
            for reader in self.known_readers:
                frame = gtk.Frame(label=str(reader))
                
                if len(self.known_cards[ reader.name ]) == 0:
                    frame.add( gtk.Label(u"Keine Karten verbunden.") )
                else:
                    vbox = gtk.VBox()
                    for card in self.known_cards[ reader.name ]:
                        if self.connected_cards.has_key(repr(card)):
                            card_ = self.connected_cards[ repr(card) ]
                            cardname = card_.get_driver_name()
                        else:
                            cardname = str(card)
                        
                        hbox = gtk.HBox()
                        cardlabel = gtk.Label( "<b>%s</b>: " % cardname )
                        cardlabel.set_use_markup(True)
                        hbox.pack_start(cardlabel, expand=False)
                        
                        vbox2 = gtk.VBox()
                        hbox.pack_start(vbox2, expand=True)
                        for ticket in self.tickets[ repr(card) ]:
                            button = gtk.RadioButton(group=self.ticket_button_group, label=str(ticket), use_underline=False)
                            vbox2.pack_start(button, expand=False)
                            
                            button.connect("toggled", self._ticket_button_toggled)
                            button._ticket = (card, ticket)
                            
                            if self.ticket_displayed is not None and ticket == self.ticket_displayed[1]:
                                button.set_active(True)
                        
                        vbox.add(hbox)
                    frame.add(vbox)
                
                self.status_area.add(frame)
        
        self.status_area.show_all()
    
    def _format_datum(d):
        return d.strftime("%x")
    
    CARD_TYPES = [
        (("SCHUL_T",),  
            "Schulticket", (
                ("Name", "name_klar", None),
                ("Alter", "alter", None),
                ("Geburtsdatum", "geburtsdatum", _format_datum),
                ("Schule", "schule", None),
                (u"Kartengültigkeit", "gueltigkeit", None),
            ),
        ),
        (("JOBT_ERW",), 
            "Jobticket",  (
                ("Name", "name_klar", None),
                ("Geburtsdatum", "geburtsdatum", _format_datum),
                (u"Kartengültigkeit", "gueltigkeit", None),
            ),
        ),
        (("MT_ABO",),   
            "Monatsabo", (
                ("Abo-Nummer", "abonr", None),
                (u"Kartengültigkeit", "gueltigkeit", None),
            ),
        ),
        (None,          
            "Anderes", (
            ),
        ),
    ]
    
    def _ticket_button_toggled(self, togglebutton):
        self.ticket_displayed = None
        for b in togglebutton.get_group():
            if b.get_active():
                if hasattr(b, "_ticket"):
                    self.ticket_displayed = b._ticket
        self._update_ticket_display()
    
    def _update_ticket_display(self):
        self._clear_display()
        if self.ticket_displayed is None:
            return
        
        todisplay = self.ticket_displayed[1]
        
        for i,t in enumerate(self.CARD_TYPES):
            if todisplay.tickettyp in t[0]:
                break
            # Note: implicit selection of the last card type when no match is found
        
        self.card_tabs.set_current_page(i)
        a = self.card_tabs.get_nth_page(i)
        vbox = a.get_child()
        label = self.card_tabs.get_tab_label(a)
        label.set_property("sensitive", True)
        
        for labeltext, propertyname, transformation in t[2]:
            frame = gtk.Frame(label=labeltext)
            content = getattr(todisplay, propertyname, None)
            contenttext = str( transformation is not None and transformation(content) or content )
            contentlabel = gtk.Label("<b><tt><big>%s</big></tt></b>" % contenttext)
            contentlabel.set_use_markup(True)
            contentlabel.show()
            frame.add( contentlabel )
            frame.show()
            
            vbox.add(frame)
    
    def exit_clicked(self, widget, event=None, data=None):
        gtk.main_quit()
        return True
    
    def run(self):
        gtk.main()
    
    # From the CardObserver and ReaderObserver classes
    def update( self, observable, (added, removed) ):
        try:
            gtk.gdk.threads_enter()
            #print observable, added, removed
            if observable is self.rmon.instance:
                self.reader_update(observable, (added, removed) )
            elif observable is self.cmon.instance:
                self.card_update(observable, (added, removed) )
            self._update_status()
            self._update_ticket_display()
        finally:
            gtk.gdk.threads_leave()
Beispiel #15
0
class Monitor(QRunnable):
    """
    Monitoriza los dispositivos pkcs11 conectados a la computadora.
    Lanza 2 eventos:

    * Dispositivo conectado (signals.USB_CONNECTED)
    * Dispositivo desconectado (signals.USB_DISCONNECTED)

    Un ejemplo de uso puede ser:

    .. code:: python 

        from client_fva.monitor import Monitor
        from client_fva import signals
        class OSDummyClient:
            def __init__(self):
                self.client = Monitor()
                self.client.start()
                self.client.signal.connect(self.token_information_event)

            def token_information_event(self, sender, **kw):

                obj = kw['obj']
                if obj._type == signals.USB_CONNECTED:
                    print("Conectando ", obj._type)
                elif obj._type == signals.USB_DISCONNECTED:
                    print("Desconectando ", obj._type)
                print(obj.data)
                return obj

    No se requiere devolver nada, pero es bueno para seguir con el formato, de otras señales
    """
    connected_device = {}
    lib = None

    def __init__(self, *args, **kwargs):
        self.settings = kwargs.get('settings', UserSettings.getInstance())
        kwargs['settings'] = self.settings
        kwargs['cached'] = False
        self.session_storage = SessionStorage.getInstance()
        self.pkcs11client = PKCS11Client(*args, **kwargs)
        self.session_storage.pkcs11_client = self.pkcs11client
        QRunnable.__init__(self)
        self.setAutoDelete(True)
        self.cardmonitor = None
        self.cardobserver = None
        self.mutex = QMutex()
        self.run_mutex = QMutex()

    @pyqtSlot()
    def run(self):
        logger.info("Iniciando monitor")
        self.readermonitor = ReaderMonitor()
        self.cardmonitor = CardMonitor()
        self.cardobserver = DfvaCardObserver(eventmanager=self)
        self.readerobserver = DFVAReaderObserver(eventmanager=self)
        self.cardmonitor.addObserver(self.cardobserver)
        self.readermonitor.addObserver(self.readerobserver)
        self.run_mutex.lock()
        self.run_mutex.lock()

    def detect_device(self, notify_exception=False):
        """
        Identifica cambios en las tarjetas conectadas, es utilizado 
        normalmente de forma automática con el monitor, pero se puede llamar 
        usando detect_device( notify_exception=True) para que envíe notificaciones 
        de los errores presentados al detectar las tarjetas.
        """
        logger.debug("Monitor: detect device")
        self.mutex.lock()
        tmp_device = []
        added_device = {}
        try:
            for tokeninfo in self.pkcs11client.get_tokens_information():
                slot = tokeninfo['slot']
                serial = tokeninfo['serial']
                if serial in self.connected_device:
                    tmp_device.append(serial)
                else:
                    tmp_device.append(serial)
                    person = self.pkcs11client.get_identification(slot=slot)
                    data = {'slot': slot, 'person': person, 'serial': serial}
                    added_device[serial] = data
                    self.send_add_signal(data)
        except SlotNotFound as notoken:
            pass
        except Exception as noToken:
            if notify_exception:
                signals.send(
                    'notify', {
                        'message':
                        "Un dispositivo ha sido encontrado, pero ninguna tarjeta pudo ser "
                        "leída, por favor verifique que la tarjeta esté correctamente "
                        "insertada"
                    })
            logger.error("%r" % (noToken, ))
            # except Exception as e:
            #     if notify_exception:
            #         signals.result.emit('notify',  {
            #             'message': "Ha ocurrido un error inesperado leyendo alguno de los dispositivos"
            #         })

        self.connected_device.update(added_device)

        for connected_serial in tuple(self.connected_device.keys()):
            if connected_serial not in tmp_device:
                self.send_removed_signal(
                    self.connected_device[connected_serial])
                self.connected_device.pop(connected_serial)
        self.mutex.unlock()

    def send_add_signal(self, data):
        sobj = signals.SignalObject(signals.USB_CONNECTED, data)
        logger.info("Tarjeta conectada %s" % (data['person'], ))
        signals.send('monitor_usb', sobj)

    def send_removed_signal(self, data):
        sobj = signals.SignalObject(signals.USB_DISCONNECTED, data)
        logger.info("Tarjeta desconectada %s" % (data['person'], ))
        signals.send('monitor_usb', sobj)

    def close(self):
        logger.info("Terminando monitor")

        if self.cardmonitor and self.cardobserver:
            self.cardmonitor.deleteObserver(self.cardobserver)

        if self.cardmonitor and self.readermonitor:
            self.readermonitor.deleteObserver(self.readerobserver)

        if self.cardmonitor:
            self.cardmonitor.rmthread.stop()

        self.run_mutex.unlock()
        del self.cardobserver
        del self.readerobserver
        del self.cardmonitor
Beispiel #16
0
class ThaiIDCard:

    status = None

    smart_card_reader_monitor = None
    smart_card_reader_observer = None

    smart_card_monitor = None
    smart_card_observer = None

    #
    # Thailand National ID Card Address
    #

    # Select & Thai MOI
    SELECT = [0x00, 0xA4, 0x04, 0x00, 0x08]

    AID_MOI = [0xA0, 0x00, 0x00, 0x00, 0x54, 0x48, 0x00, 0x01]

    # APDU Type
    APDU_THAILAND_IDCARD_TYPE_01 = [0x00, 0xc0, 0x00, 0x01]
    APDU_THAILAND_IDCARD_TYPE_02 = [0x00, 0xc0, 0x00, 0x00]

    # TH Citizen ID
    CMD_CITIZEN = [0x80, 0xb0, 0x00, 0x04, 0x02, 0x00, 0x0d]
    # TH Full Name
    CMD_THFULLNAME = [0x80, 0xb0, 0x00, 0x11, 0x02, 0x00, 0x64]
    # EN Full Name
    CMD_ENFULLNAME = [0x80, 0xb0, 0x00, 0x75, 0x02, 0x00, 0x64]
    # Date of birth
    CMD_BIRTH = [0x80, 0xb0, 0x00, 0xD9, 0x02, 0x00, 0x08]
    # Gender
    CMD_GENDER = [0x80, 0xb0, 0x00, 0xE1, 0x02, 0x00, 0x01]
    # Card Issuer
    CMD_ISSUER = [0x80, 0xb0, 0x00, 0xF6, 0x02, 0x00, 0x64]
    # Issue Date
    CMD_ISSUE = [0x80, 0xb0, 0x01, 0x67, 0x02, 0x00, 0x08]
    # Expire Date
    CMD_EXPIRE = [0x80, 0xb0, 0x01, 0x6F, 0x02, 0x00, 0x08]
    # Address
    CMD_ADDRESS = [0x80, 0xb0, 0x15, 0x79, 0x02, 0x00, 0x64]

    # Photo_Part1/20
    CMD_PHOTO01 = [0x80, 0xb0, 0x01, 0x7B, 0x02, 0x00, 0xFF]
    # Photo_Part2/20
    CMD_PHOTO02 = [0x80, 0xb0, 0x02, 0x7A, 0x02, 0x00, 0xFF]
    # Photo_Part3/20
    CMD_PHOTO03 = [0x80, 0xb0, 0x03, 0x79, 0x02, 0x00, 0xFF]
    # Photo_Part4/20
    CMD_PHOTO04 = [0x80, 0xb0, 0x04, 0x78, 0x02, 0x00, 0xFF]
    # Photo_Part5/20
    CMD_PHOTO05 = [0x80, 0xb0, 0x05, 0x77, 0x02, 0x00, 0xFF]
    # Photo_Part6/20
    CMD_PHOTO06 = [0x80, 0xb0, 0x06, 0x76, 0x02, 0x00, 0xFF]
    # Photo_Part7/20
    CMD_PHOTO07 = [0x80, 0xb0, 0x07, 0x75, 0x02, 0x00, 0xFF]
    # Photo_Part8/20
    CMD_PHOTO08 = [0x80, 0xb0, 0x08, 0x74, 0x02, 0x00, 0xFF]
    # Photo_Part9/20
    CMD_PHOTO09 = [0x80, 0xb0, 0x09, 0x73, 0x02, 0x00, 0xFF]
    # Photo_Part10/20
    CMD_PHOTO10 = [0x80, 0xb0, 0x0A, 0x72, 0x02, 0x00, 0xFF]
    # Photo_Part11/20
    CMD_PHOTO11 = [0x80, 0xb0, 0x0B, 0x71, 0x02, 0x00, 0xFF]
    # Photo_Part12/20
    CMD_PHOTO12 = [0x80, 0xb0, 0x0C, 0x70, 0x02, 0x00, 0xFF]
    # Photo_Part13/20
    CMD_PHOTO13 = [0x80, 0xb0, 0x0D, 0x6F, 0x02, 0x00, 0xFF]
    # Photo_Part14/20
    CMD_PHOTO14 = [0x80, 0xb0, 0x0E, 0x6E, 0x02, 0x00, 0xFF]
    # Photo_Part15/20
    CMD_PHOTO15 = [0x80, 0xb0, 0x0F, 0x6D, 0x02, 0x00, 0xFF]
    # Photo_Part16/20
    CMD_PHOTO16 = [0x80, 0xb0, 0x10, 0x6C, 0x02, 0x00, 0xFF]
    # Photo_Part17/20
    CMD_PHOTO17 = [0x80, 0xb0, 0x11, 0x6B, 0x02, 0x00, 0xFF]
    # Photo_Part18/20
    CMD_PHOTO18 = [0x80, 0xb0, 0x12, 0x6A, 0x02, 0x00, 0xFF]
    # Photo_Part19/20
    CMD_PHOTO19 = [0x80, 0xb0, 0x13, 0x69, 0x02, 0x00, 0xFF]
    # Photo_Part20/20
    CMD_PHOTO20 = [0x80, 0xb0, 0x14, 0x68, 0x02, 0x00, 0xFF]

    # Expire time of data -- seconds
    _read_expire_time = 5  #

    # Thai Citizen ID
    _citizen = None
    _citizen_t = 0
    # Thai Full Name
    _full_name_th = None
    _full_name_th_t = 0
    # English Full Name
    _full_name_en = None
    _full_name_en_th = 0
    # Date of birth
    _birth = None
    _birth_t = 0
    # Gender
    _gender = None
    _gender_t = 0
    # Card Issuer
    _issuer = None
    _issuer_t = 0
    # Issue Date
    _issue = None
    _issue_t = 0
    # Expire Date
    _expire = None
    _expire_t = 0
    # Address
    _address = None
    _address_t = 0
    # Photo
    _photo = None
    _photo_t = 0

    def __init__(self):
        self.readerList = []

        if (len(self.getReaders()) > 0):
            self.connect(0)

    def readerMonitor(self, reader_added_cb, reader_removed_cb):
        self.reader_added_cb = reader_added_cb
        self.reader_removed_cb = reader_removed_cb
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: Add SmartCard reader observer")
        self.smart_card_reader_monitor = ReaderMonitor()
        self.smart_card_reader_observer = SmartCardReaderObserver(
            reader_added_callback=self.reader_removed_cb,
            reader_removed_callback=self.reader_removed_cb)
        self.smart_card_reader_monitor.addObserver(
            self.smart_card_reader_observer)

    def readerUnmonitor(self):
        try:
            if THAI_ID_CARD_DEBUG:
                print("ThaiIDCard: Remove SmartCard reader observer")
            self.smart_card_reader_monitor.deleteObserver(
                self.smart_card_reader_observer)
        except:
            pass

    def cardMonitor(self, smart_card_insert_cb, smart_card_remove_cb):
        self.smart_card_insert_cb = smart_card_insert_cb
        self.smart_card_remove_cb = smart_card_remove_cb
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: Add SmartCard observer")
        self.smart_card_monitor = CardMonitor()
        self.smart_card_observer = SmartCardObserver(
            card_insert_callback=self.smart_card_insert_cb,
            card_remove_callback=self.smart_card_remove_cb)
        self.smart_card_monitor.addObserver(self.smart_card_observer)

    def cardUnmonitor(self):
        try:
            if THAI_ID_CARD_DEBUG:
                print("ThaiIDCard: Remove SmartCard observer")
            self.smart_card_monitor.deleteObserver(self.smart_card_observer)
        except:
            pass

    # Get SmartCard reader list
    def getReaders(self):
        # Get all the available readers
        self.readerList = smartcard.System.readers()
        #if len(self.readerList) > 0:
        #    print ("Found SmartCard readers:")
        #    for readerIndex,readerItem in enumerate(self.readerList):
        #        print(" - %d, '%s'"%(readerIndex, readerItem))
        #else:
        #    print ("No SmartCard reader")
        self.readerIndex = 0
        return self.readerList

    # Connect to SmartCard reader
    def connect(self, index=0):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: Connecting to SmartCard")
        if len(self.readerList) == 0:
            if len(self.getReaders()) == 0:
                return None

        if index < 0 or index >= len(self.readerList):
            return None

        # Select reader
        self.readerIndex = index
        self.reader = self.readerList[self.readerIndex]
        if THAI_ID_CARD_DEBUG:
            print("Using SmartCard reader:", self.reader)

        try:
            self.connection = self.reader.createConnection()
            self.connection.connect()

            atr = self.connection.getATR()
            if THAI_ID_CARD_DEBUG:
                print(" - Card type: " + toHexString(atr))
            if (atr[0] == 0x3B & atr[1] == 0x67):
                # Corruption Card
                self._apdu = self.APDU_THAILAND_IDCARD_TYPE_01
            else:
                self._apdu = self.APDU_THAILAND_IDCARD_TYPE_02
            if THAI_ID_CARD_DEBUG:
                print(" - Connect to SmartCard success")
            self.status = True
            response, sw1, sw2 = self.selectApplet()
            # [], 61, 0A
            time.sleep(0.1)
            if sw1 == 0x61 and sw2 == 0x0A:
                return True
            self.status = None
            return None
        except:
            if THAI_ID_CARD_DEBUG:
                print(" - Failed to connect to SmartCard")
            self.status = None
            return None

    def disconnect(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: Closing connection from SmartCard")
        try:
            self.connection.disconnect()
        except:
            pass

    # Select MOI Applet
    def selectApplet(self):
        if self.status == None:
            if self.connect(self.readerIndex) == None:
                return [None, None, None]

        response, sw1, sw2 = self.connection.transmit(self.SELECT +
                                                      self.AID_MOI)
        #print ("Select Applet: %02X %02X" % (sw1, sw2))
        return [response, sw1, sw2]

    # Read data from SmartCard
    def read(self, cmd, apdu=None):
        if self.status == None:
            if self.connect(self.readerIndex) == None:
                return [None, None, None]

        if apdu == None:
            apdu = self._apdu

        try:
            response, sw1, sw2 = self.connection.transmit(cmd)
            response, sw1, sw2 = self.connection.transmit(apdu + [cmd[-1]])
            return [response, sw1, sw2]
        except Exception as w:
            return [None, None, None]

    # Read photo from SmartCard
    def readPhoto(self):
        if self.status == None:
            if self.connect(self.readerIndex) == None:
                return None

        photo = self.read(self.CMD_PHOTO01)[0]
        photo += self.read(self.CMD_PHOTO02)[0]
        photo += self.read(self.CMD_PHOTO03)[0]
        photo += self.read(self.CMD_PHOTO04)[0]
        photo += self.read(self.CMD_PHOTO05)[0]
        photo += self.read(self.CMD_PHOTO06)[0]
        photo += self.read(self.CMD_PHOTO07)[0]
        photo += self.read(self.CMD_PHOTO08)[0]
        photo += self.read(self.CMD_PHOTO09)[0]
        photo += self.read(self.CMD_PHOTO10)[0]
        photo += self.read(self.CMD_PHOTO11)[0]
        photo += self.read(self.CMD_PHOTO12)[0]
        photo += self.read(self.CMD_PHOTO13)[0]
        photo += self.read(self.CMD_PHOTO14)[0]
        photo += self.read(self.CMD_PHOTO15)[0]
        photo += self.read(self.CMD_PHOTO16)[0]
        photo += self.read(self.CMD_PHOTO17)[0]
        photo += self.read(self.CMD_PHOTO18)[0]
        photo += self.read(self.CMD_PHOTO19)[0]
        photo += self.read(self.CMD_PHOTO20)[0]
        response = HexListToBinString(photo)
        return response

    def thai2unicode(self, data):
        result = ''
        result = bytes(data).decode('tis-620')
        return result.strip()

    # Citizen ID
    @property
    def citizen(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: citizen=", end=' ')
        if (self._citizen != None):
            if ((time.time() - self._citizen_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._citizen)
                return self._citizen
        response, sw1, sw2 = self.read(self.CMD_CITIZEN)
        if (response != None):
            self._citizen = self.thai2unicode(response)
            self._citizen_t = time.time()
        else:
            self._citizen = None
        if THAI_ID_CARD_DEBUG:
            print(self._citizen)
        return self._citizen

    # Thai Name
    @property
    def full_name_th(self):
        #if THAI_ID_CARD_DEBUG:
        #    print("ThaiIDCard: full_name_th")
        if (self._full_name_th != None):
            if ((time.time() - self._full_name_th_t) < self._read_expire_time):
                return self._full_name_th
        response, sw1, sw2 = self.read(self.CMD_THFULLNAME)
        if (response != None):
            self._full_name_th = self.thai2unicode(response)
            self._full_name_th_t = time.time()
            self._first_name_th, self._last_name_th = self._full_name_th.split(
                '##')
            self._prefix_th, self._first_name_th = self._first_name_th.split(
                '#')
        else:
            self._full_name_th = None
        return self._full_name_th

    @property
    def prefix_th(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: prefix_th=", end=' ')
        if (self._full_name_th != None):
            if ((time.time() - self._full_name_th_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._prefix_th)
                return self._prefix_th
        if (self.full_name_th != None):
            if THAI_ID_CARD_DEBUG:
                print(self._prefix_th)
            return self._prefix_th
        return None

    @property
    def first_name_th(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: first_name_th=", end=' ')
        if (self._full_name_th != None):
            if ((time.time() - self._full_name_th_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._first_name_th)
                return self._first_name_th
        if (self.full_name_th != None):
            if THAI_ID_CARD_DEBUG:
                print(self._first_name_th)
            return self._first_name_th
        return None

    @property
    def last_name_th(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: last_name_th=", end=' ')
        if (self._full_name_th != None):
            if ((time.time() - self._full_name_th_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._last_name_th)
                return self._last_name_th
        if (self.full_name_th != None):
            if THAI_ID_CARD_DEBUG:
                print(self._last_name_th)
            return self._last_name_th
        return None

    # English Name
    @property
    def full_name_en(self):
        #if THAI_ID_CARD_DEBUG:
        #    print("ThaiIDCard: full_name_en")
        if (self._full_name_en != None):
            if ((time.time() - self._full_name_en_t) < self._read_expire_time):
                return self._full_name_en
        response, sw1, sw2 = self.read(self.CMD_ENFULLNAME)
        if (response != None):
            self._full_name_en = self.thai2unicode(response)
            self._full_name_en_t = time.time()
            self._first_name_en, self._last_name_en = self._full_name_en.split(
                '##')
            self._prefix_en, self._first_name_en = self._first_name_en.split(
                '#')
        else:
            self._full_name_en = None
        return self._full_name_en

    @property
    def prefix_en(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: prefix_en=", end=' ')
        if (self._full_name_en != None):
            if ((time.time() - self._full_name_en_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._prefix_en)
                return self._prefix_en
        if (self.full_name_en != None):
            if THAI_ID_CARD_DEBUG:
                print(self._prefix_en)
            return self._prefix_en
        return None

    @property
    def first_name_en(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: first_name_en=", end=' ')
        if (self._full_name_en != None):
            if ((time.time() - self._full_name_en_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._first_name_en)
                return self._first_name_en
        if (self.full_name_en != None):
            if THAI_ID_CARD_DEBUG:
                print(self._first_name_en)
            return self._first_name_en
        return None

    @property
    def last_name_en(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: last_name_en=", end=' ')
        if (self._full_name_en != None):
            if ((time.time() - self._full_name_en_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._last_name_en)
                return self._last_name_en
        if (self.full_name_en != None):
            if THAI_ID_CARD_DEBUG:
                print(self._last_name_en)
            return self._last_name_en
        return None

    # Date of birth
    @property
    def birth(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: birth=", end=' ')
        if (self._birth != None):
            if ((time.time() - self._birth_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._birth)
                return self._birth
        response, sw1, sw2 = self.read(self.CMD_BIRTH)
        if (response != None):
            self._birth = self.thai2unicode(response)
            self._birth_t = time.time()
            self._birth = self._birth[0:4] + '-' + self._birth[
                4:6] + '-' + self._birth[6:8]
        else:
            self._birth = None
        if THAI_ID_CARD_DEBUG:
            print(self._birth)
        return self._birth

    # Gender
    @property
    def gender(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: gender=", end=' ')
        if (self._gender != None):
            if ((time.time() - self._gender_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._gender)
                return self._gender
        response, sw1, sw2 = self.read(self.CMD_GENDER)
        if (response != None):
            self._gender = self.thai2unicode(response)
            self._gender_t = time.time()
        else:
            self._gender = None
        if THAI_ID_CARD_DEBUG:
            print(self._gender)
        return self._gender

    # Issue date
    @property
    def issue(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: issue=", end=' ')
        if (self._issue != None):
            if ((time.time() - self._issue_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._issue)
                return self._issue
        response, sw1, sw2 = self.read(self.CMD_ISSUE)
        if (response != None):
            self._issue = self.thai2unicode(response)
            self._issue_t = time.time()
            self._issue = self._issue[0:4] + '-' + self._issue[
                4:6] + '-' + self._issue[6:8]
        else:
            self._issue = None
        if THAI_ID_CARD_DEBUG:
            print(self._issue)
        return self._issue

    # Expire date
    @property
    def expire(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: expire=", end=' ')
        if (self._expire != None):
            if ((time.time() - self._expire_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._expire)
                return self._expire
        response, sw1, sw2 = self.read(self.CMD_EXPIRE)
        if (response != None):
            self._expire = self.thai2unicode(response)
            self._expire_t = time.time()
            self._expire = self._expire[0:4] + '-' + self._expire[
                4:6] + '-' + self._expire[6:8]
        else:
            self._expire = None
        if THAI_ID_CARD_DEBUG:
            print(self._expire)
        return self._expire

    # Address
    @property
    def address(self):
        #if THAI_ID_CARD_DEBUG:
        #    print("ThaiIDCard: address")
        if (self._address != None):
            if ((time.time() - self._address_t) < self._read_expire_time):
                return self._address
        response, sw1, sw2 = self.read(self.CMD_ADDRESS)
        if (response != None):
            self._address = self.thai2unicode(response)
            self._address_t = time.time()
            #self._address = self._address[0:4]+'-'+self._address[4:6]+'-'+self._address[6:8]
            self._address = re.sub(r'#', ' ', self._address)
            self._address = re.sub(r'  ', ' ', self._address)
            self._address = re.sub(r'  ', ' ', self._address)
            x = self._address.rsplit()
            self._city = x[len(x) - 2]
            self._province = x[len(x) - 1]
        else:
            self._address = None
        return self._address

    @property
    def city(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: city=", end=' ')
        if (self._address != None):
            if ((time.time() - self._address_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._city)
                return self._city
        if (self.address != None):
            if THAI_ID_CARD_DEBUG:
                print(self._city)
            return self._city
        return None

    @property
    def province(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: province=", end=' ')
        if (self._address != None):
            if ((time.time() - self._address_t) < self._read_expire_time):
                if THAI_ID_CARD_DEBUG:
                    print(self._province)
                return self._province
        if (self.address != None):
            if THAI_ID_CARD_DEBUG:
                print(self._province)
            return self._province
        return None

    # Photo
    @property
    def photo(self):
        if THAI_ID_CARD_DEBUG:
            print("ThaiIDCard: photo")
        if (self._photo != None):
            if ((time.time() - self._photo_t) < self._read_expire_time):
                return self._photo
        self._photo = self.readPhoto()
        return self._photo

    # Example code, read all attributes
    def example(self):
        if (len(self.readerList) < 0):
            return None

        # Reader list
        print(self.getReaders())

        print(f'Citizen ID:', self.citizen)
        print(f'Thai Full Name: ' + self.full_name_th)
        print(f'Thai Prefix: ' + self.prefix_th)
        print(f'Thai First Name: ' + self.first_name_th)
        print(f'Thai Last Name: ' + self.last_name_th)
        print(f'English Full Name: ' + self.full_name_en)
        print(f'English Prefix: ' + self.prefix_en)
        print(f'English First Name: ' + self.first_name_en)
        print(f'English Last Name: ' + self.last_name_en)
        print(f'Date of birth: ' + self.birth)
        print(f'Gender: ' + self.gender)
        print(f'Issue date: ' + self.issue)
        print(f'Expire date: ' + self.expire)
        print(f'Address: ' + self.address)
        print(f'City: ' + self.city)
        print(f'Province: ' + self.province)
        #print(f'Photo file size: ' + self.photo)
        return
Beispiel #17
0
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."""
            addedcards, removedcards = 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()
    """A simple reader observer that is notified
    when readers are added/removed from the system and
    prints the list of readers
    """

    def update(self, observable, (addedreaders, removedreaders)):
        print "Added readers", addedreaders
        print "Removed readers", removedreaders

try:
    print "Add or remove a smartcard reader to the system."
    print "This program will exit in 10 seconds"
    print ""
    readermonitor = ReaderMonitor()
    readerobserver = printobserver()
    readermonitor.addObserver(readerobserver)

    sleep(10)

    # don't forget to remove observer, or the
    # monitor will poll forever...
    readermonitor.deleteObserver(readerobserver)

    import sys
    if 'win32' == sys.platform:
        print 'press Enter to continue'
        sys.stdin.read(1)

except:
    print exc_info()[0], ':', exc_info()[1]