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
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
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" }))
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)
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()
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
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" }))
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" }))
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
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')
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
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)