예제 #1
0
    def get_slots(self, filter=[]):
        slots = None
        try:
            if self.lib is None:
                self.lib = pkcs11.lib(self.get_module_lib())

            slots = self.lib.get_slots()
            if filter:
                slots = [slot for slot in slots if slot.slot_id in filter]
            self.error_show_message = 0
        except Exception as e:
            if self.error_show_message < self.settings.number_requests_before_fail:
                signals.send(
                    'notify',
                    signals.SignalObject(
                        signals.NOTIFTY_ERROR, {
                            'message':
                            "La biblioteca instalada no funciona para leer "
                            "las tarjetas, porque no ha instalado las "
                            "bibliotecas necesarias o porque el sistema "
                            "operativo no está soportado"
                        }))
                self.error_show_message += 1
            logger.error("Error abriendo dispositivos PKCS11 %r" % (e, ))

        if not slots:
            raise SlotNotFound("PKCS11: Slot not found")

        return slots
예제 #2
0
    def get_module_lib(self):
        """Obtiene la biblioteca de comunicación con la tarjeta """

        if hasattr(self.settings, 'module_path') and self.settings.module_path:
            return self.settings.module_path

        if 'PKCS11_MODULE' in os.environ:
            return os.environ['PKCS11_MODULE']

        if os.path.exists('/usr/lib/libASEP11.so'):  # Linux
            return '/usr/lib/libASEP11.so'

        if os.path.exists("/usr/local/lib/libASEP11.dylib"):  # macOS
            return "/usr/local/lib/libASEP11.dylib"

        # FIXME: Hacer la construcción del path por defecto para windows,
        # sugerencia
        """
        public static String ObtenerDirectorioDeWindows()
          {
            String direccionDeWindows = System.getenv("SystemRoot");
            if ((direccionDeWindows == null) || (direccionDeWindows.equalsIgnoreCase(""))) {
              direccionDeWindows = System.getenv("WINDIR");
            }
            String directorioDeWindows = direccionDeWindows + File.separator + "system32";
            return directorioDeWindows;
          }
        """

        _os = platform.system().lower()
        _os_arch = platform.machine()
        BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        if _os == 'linux':
            path = os.path.join(BASE_DIR,
                                'os_libs/%s/%s/libASEP11.so' % (_os, _os_arch))
        elif _os == "darwin":
            path = os.path.join(BASE_DIR, 'os_libs/macos/libASEP11.dylib')
        elif _os == "windows":
            path = os.path.join(BASE_DIR, 'os_libs/windows/asepkcs.dll')

        if os.path.exists(path):
            return path

        signals.send(
            'notify',
            signals.SignalObject(
                signals.NOTIFTY_ERROR, {
                    'message':
                    "No existe una biblioteca instalada para leer las \
              tarjetas, esto puede ser porque no ha instalado las bibliotecas \
              necesarias o porque el sistema operativo no está soportado"
                }))
예제 #3
0
    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("Installation path: " +
                     str(self.settings.installation_path))
        logger.debug("Monitor: detect device")
        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)
예제 #4
0
    def run(self):
        data = self.data
        mid = self.mysign.add_mysign(data["identification"],
                                     data["file_path"],
                                     data["file_name"],
                                     signed_document_path=data["save_path"])
        ok = False
        counttry = 0
        while not ok and counttry < self.settings.number_requests_before_fail:
            try:
                self.result = self.person.sign(data["identification"],
                                               data["document"],
                                               data["resume"],
                                               _format=data["_format"],
                                               file_path=data["file_path"],
                                               algorithm=data["algorithm"],
                                               is_base64=data["is_base64"],
                                               wait=data["wait"],
                                               extras=data["extras"])
                ok = True
            except requests.exceptions.ConnectionError:
                logger.warning("Error de comunicación intentando firmar")
                ok = False
                counttry += 1
        if not ok:
            signals.send(
                'notify',
                signals.SignalObject(
                    signals.NOTIFTY_ERROR, {
                        'message':
                        "Error de comunicación, verifique su conexión de internet"
                    }))
            self.result = {
                'status': 1,
                'status_text':
                'Error de comunicación, no se puedo conectar con el servidor',
                'signed_document': None
            }
        self.mysign.update_mysign(mid,
                                  transaction_status=self.result["status"],
                                  transaction_text=self.result["status_text"])

        if self.result.get('signed_document'):
            with open(data["save_path"], "wb") as arch:
                arch.write(b64decode(self.result["signed_document"]))
                self.end_success.emit()

        self.has_result.emit(self.tid)
예제 #5
0
    def get_pin(self, pin=None, slot=None):
        """Obtiene el pin de la tarjeta para iniciar sesión"""

        if isinstance(pin, Secret):
            return str(pin)

        if pin:
            return pin

        if 'PKCS11_PIN' in os.environ:
            pin = os.environ['PKCS11_PIN']
        else:
            try:
                serial = self.get_slot(
                    slot=slot).get_token().serial.decode('utf-8')
            except:
                serial = 'N/D'
                # Fixme: aqui debería manejarse mejor

            sobj = signals.SignalObject(signals.PIN_REQUEST,
                                        {'serial': serial})
            respobj = signals.receive(signals.send('pin', sobj))
            if 'pin' in respobj.response and respobj.response['pin']:
                pin = str(Secret(respobj.response['pin'], decode=True))
            if respobj.response['rejected']:
                raise UserRejectPin()
        if pin is None:
            raise PinNotProvided(
                'Sorry PIN is needed, we will remove this, but for now use export PKCS11_PIN=<pin> '
                'before call python.')
        return pin
예제 #6
0
파일: login.py 프로젝트: luisza/dfva_client
 def run(self):
     self.start_process_bar()
     self.timer = EjecutionTimer(self)
     self.threadpool.start(self.timer)
     ok = False
     counttry = 0
     while not ok and counttry < self.settings.number_requests_before_fail:
         try:
             self.session_storage.session_info[
                 self.serial]['personclient'].register(slot=self.slot)
             ok = True
         except requests.exceptions.ConnectionError:
             ok = False
             counttry += 1
     if not ok:
         signals.send(
             'notify',
             signals.SignalObject(
                 signals.NOTIFTY_ERROR, {
                     'message':
                     "Error en la red, no se puede autenticar al usuario, por favor verifique su conexión a internet"
                 }))
     self.end_process_bar()
예제 #7
0
 def get_slots(self):
     """Obtiene el primer slot (tarjeta) disponible
     .. warning:: Solo usar en pruebas y mejorar la forma como se capta
     """
     if self.slots is not None and self.cached:
         return self.slots
     try:
         self.pkcs11.load(self.get_module_lib())
         self.slots = self.pkcs11.getSlotList()
     except Exception as e:
         signals.send(
             'notify',
             signals.SignalObject(
                 signals.NOTIFTY_ERROR, {
                     'message':
                     "La biblioteca instalada no funciona para leer \
                 las tarjetas, esto puede ser porque no ha instalado \
                 las bibliotecas necesarias o porque el sistema operativo \
                 no está soportado"
                 }))
         logger.error("Error abriendo dispositivos PKCS11 %r" % (e, ))
         return []
     return self.slots
예제 #8
0
 def process_messages(self, response):
     """
     Mientras existan mensajes por leer intenta procesar todo mensaje que 
     venga del BCCR.
     """
     self.status_signal.emit(self.CONNECTED)
     for message in self.read_messages(response):
         try:
             data = json.loads(message)
         except:
             logger.info(message)
             continue
         if 'M' in data and data['M']:
             if "M" in data['M'][0] and data['M'][0]['M'] == "Firme":
                 signed = bool(self.sign(data))
                 if not signed:
                     signals.send(
                         'notify',
                         signals.SignalObject(
                             signals.NOTIFTY_ERROR, {
                                 'message':
                                 "Error al firmar, lo lamentamos \
                         por favor vuelva a intentarlo"
                             }))
예제 #9
0
 def run(self):
     settings = UserSettings.getInstance()
     ok = False
     counttry = 0
     while not ok and counttry < settings.number_requests_before_fail:
         try:
             self.result = self.person.validate(self.data["document"],
                                                self.data["file_path"],
                                                self.data["algorithm"],
                                                self.data["is_base64"],
                                                self.data["_format"])
             self.has_result.emit(self.tid)
             ok = True
         except requests.exceptions.ConnectionError:
             ok = False
             counttry += 1
     if not ok:
         signals.send(
             'notify',
             signals.SignalObject(
                 signals.NOTIFTY_ERROR, {
                     'message':
                     "Error en la red, por favor verifique su conexión a internet"
                 }))
예제 #10
0
    def get_identification(self):
        if self.identification is not None and self.cached:
            return self.identification

        info = None
        try:
            info = self.get_certificate_info()
            if info is None:
                raise Exception()
        except Exception as e:
            # FIXME: set a correct type of exception
            signals.send(
                'notify',
                signals.SignalObject(
                    signals.NOTIFTY_ERROR, {
                        'message':
                        "No se puede obtener la identificación de la persona\
                , posiblemente porque la tarjeta está mal conectada"
                    }))
            logger.error("Tarjeta no detectada %r" % (e, ))
            raise
        if info:
            self.identification = info['authentication']['identification']
        return self.identification
예제 #11
0
    def get_pin(self, pin=None):
        """Obtiene el pin de la tarjeta para iniciar sessión"""

        if pin:
            return pin

        if 'PKCS11_PIN' in os.environ:
            return os.environ['PKCS11_PIN']
        else:
            try:
                serial = self.get_slot().get_tokens()[0].serial.decode('utf-8')
            except:
                serial = 'N/D'
                # Fixme: aqui debería manejarse mejor
            respobj = signals.receive(
                signals.send(
                    'pin',
                    signals.SignalObject(signals.PIN_REQUEST,
                                         {'serial': serial})))
            return respobj.response['pin']

        raise Exception(
            'Sorry PIN is Needed, we will remove this, but for now use export \
            PKCS11_PIN=<pin> before call python')
예제 #12
0
    def wrapper(*args, **kwargs):
        instance = args[0]
        count = 0
        try_again = True
        dev = None
        slot = kwargs['slot'] if 'slot' in kwargs else None
        while try_again and count < 3:
            try:
                dev = func(*args, **kwargs)
                try_again = False
            except pkcs11.exceptions.PinLocked as e:
                signals.send(
                    'notify',
                    signals.SignalObject(
                        signals.NOTIFTY_ERROR, {
                            'message':
                            "Tarjeta bloqueada, por favor contacte con su proveedor para desbloquearla"
                        }))
                logger.error(
                    "Tarjeta bloqueada, por favor contacte con su proveedor para desbloquearla "
                    + str(instance.serial))
                try_again = False
            except pkcs11.exceptions.TokenNotRecognised as e:
                signals.send(
                    'notify',
                    signals.SignalObject(
                        signals.NOTIFTY_ERROR, {
                            'message':
                            "No se puede obtener la identificación de la "
                            "persona, posiblemente porque la tarjeta está "
                            "mal conectada"
                        }))
                logger.error("Tarjeta no detectada %r" % (e, ))
                try_again = False
            except pkcs11.exceptions.PinIncorrect as e:
                count += 1
                logger.info("Pin incorrecto para el slot %s  intento %d" %
                            (str(slot), count))
                obj = signals.SignalObject(
                    signals.NOTIFTY_ERROR, {
                        'message':
                        "Pin incorrecto, recuerde después de 3 intentos su tarjeta puede bloquearse, este es el intento %d"
                        % (count)
                    })
                signals.send('notify', obj)
                signals.receive(obj)
                try_again = True
            except PinNotProvided as e:
                signals.send(
                    'notify',
                    signals.SignalObject(
                        signals.NOTIFTY_ERROR, {
                            'message':
                            "No se ha logrado identificar el PIN correcto con ninguno de los mecanismos establecidos"
                        }))
                logger.error(
                    "Pin no provisto, el sistema no identificó un pin adecuado"
                )
                try_again = True
                count += 1
            except pkcs11.exceptions.DataInvalid as e:
                signals.send(
                    'notify',
                    signals.SignalObject(
                        signals.NOTIFTY_ERROR, {
                            'message':
                            "No se ha logrado firmar, posiblemente porque el mecanismo usado en la aplicación no está disponible en su tarjeta"
                        }))
                logger.error("Error al firmar documento %r" % (e, ))
                try_again = False

        if count == 3:
            signals.send(
                'notify',
                signals.SignalObject(
                    signals.NOTIFTY_ERROR, {
                        'message':
                        "Se ha excedido el número de intentos, puede que su tarjeta haya sido bloqueada"
                    }))

        return dev
예제 #13
0
 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)