diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 9a1c889e97e2ea63d05c8e182fc680b393bf8e38..89ff44291b5e6653416d0bc52fbb9ce15d31c8a0 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -33,3 +33,6 @@ install(FILES ${PROJECT_BINARY_DIR}/data/kiran-authentication-daemon.service DESTINATION ${SYSTEM_UNIT_DIR}) install(FILES kad.ini DESTINATION ${KAS_INSTALL_SYSCONFDIR}) + +install(FILES kiran-authentication-service + DESTINATION /${CMAKE_INSTALL_SYSCONFDIR}/pam.d/) \ No newline at end of file diff --git a/data/kad.ini b/data/kad.ini index c589381af32a3e776b1e9082504aa7741e7929da..eaaa05ac0f6c8f9e0ef80885634900bf6fdf9ea8 100644 --- a/data/kad.ini +++ b/data/kad.ini @@ -1,23 +1,40 @@ [General] -SupportedPAMServices=lightdm, login -EnabledPAMServices=login -# 每个用户认证允许的失败尝试次数 +#多因子认证,需多个认证方式认证通过,And +#多路认证,多个认证方式选择一个通过即可,Or +AuthMode=Or +AuthOrder=fingerprint,fingervein,face,iris,ukey +#内置最大错误次数判断,错误超过该次数后,该用户将无法使用生物认证(认证服务提供的认证方式) +#只针对与多路认证,多因子认证错误次数不由认证服务接管 MaxFailures=3 +EnabledPAMServices=login +SupportedPAMServices=lightdm, login + +[Face] +EmpowermentEnable=true +Enable=true +LoginEnable=true +UnlockEnable=true -[Fingerprint] +[FingerPrint] +EmpowermentEnable=true Enable=true -SupportLogin=true -SupportUnlock=true -SupportPolkit=true +LoginEnable=true +UnlockEnable=true -[Face] +[FingerVein] +EmpowermentEnable=true +Enable=true +LoginEnable=true +UnlockEnable=true + +[Iris] +EmpowermentEnable=true Enable=true -SupportLogin=true -SupportUnlock=true -SupportPolkit=true +LoginEnable=true +UnlockEnable=true -[UKey] +[Ukey] +EmpowermentEnable=true Enable=true -SupportLogin=true -SupportUnlock=true -SupportPolkit=true \ No newline at end of file +LoginEnable=true +UnlockEnable=true \ No newline at end of file diff --git a/data/kiran-authentication-service b/data/kiran-authentication-service new file mode 100644 index 0000000000000000000000000000000000000000..e5d0f984272f85d428fde29ec7a7acc2803848a3 --- /dev/null +++ b/data/kiran-authentication-service @@ -0,0 +1,11 @@ +# 多路认证模式,成/功则认证通过,失败/切换到密码 跳过多因子认证模式 +auth [success=done ignore=ignore default=die] pam_kiran_authentication.so doauth + +# 多因子认证模式, 成功继续执行PAM流程栈,失败或默认值都为失败 +#auth requisite pam_faillock.so preauth audit deny=3 even_deny_root unlock_time=60 +#auth [success=2 default=bad] pam_kiran_authentication.so doauth +#auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root unlock_time=60 +#auth required pam_debug + +# 认证成功,清理内部记录错误次数 +account required pam_kiran_authentication.so authsucc \ No newline at end of file diff --git a/include/kas-authentication-i.h b/include/kas-authentication-i.h index caa4c240dfa2eb66e9d3b1d769939d37b474f337..314d62fb76776c9343522e31832ac6ee7dc8764e 100644 --- a/include/kas-authentication-i.h +++ b/include/kas-authentication-i.h @@ -57,15 +57,17 @@ extern "C" #define AUTH_TYPE_STR_PASSWORD "password" #define AUTH_TYPE_STR_FINGERPRINT "fingerprint" -#define AUTH_TYPE_STR_FACE "face" -#define AUTH_TYPE_STR_UKEY "uKey" #define AUTH_TYPE_STR_FINGERVEIN "fingervein" +#define AUTH_TYPE_STR_FACE "face" +#define AUTH_TYPE_STR_IRIS "iris" +#define AUTH_TYPE_STR_UKEY "ukey" // 认证类型 enum KADAuthType { // 无/默认方式 KAD_AUTH_TYPE_NONE = 0, + // 密码认证,认证服务不参与密码认证 KAD_AUTH_TYPE_PASSWORD = (1 << 0), // 指纹认证 @@ -76,7 +78,10 @@ extern "C" KAD_AUTH_TYPE_UKEY = (1 << 3), // 指静脉认证 KAD_AUTH_TYPE_FINGERVEIN = (1 << 4), - KAD_AUTH_TYPE_LAST = (1 << 5), + // 虹膜 + KAD_AUTH_TYPE_IRIS = (1 << 5), + + KAD_AUTH_TYPE_LAST = (1 << 6), }; // 认证提示消息类型,接收方需要响应消息 @@ -97,7 +102,7 @@ extern "C" KAD_MESSAGE_TYPE_INFO, }; - /* ------------ 认证场景定义 ----------------- */ +/* ------------ 认证场景定义 ----------------- */ #define AUTH_APPLICATION_STR_LOGIN "login" #define AUTH_APPLICATION_STR_UNLOCK "unlock" #define AUTH_APPLICATION_STR_EMPOWERMENT "empowerment" @@ -113,7 +118,7 @@ extern "C" KAD_AUTH_APPLICATION_EMPOWERMENT, KAD_AUTH_APPLICATION_LAST }; - /* ------------ PAM相关的定义 ----------------- */ +/* ------------ PAM相关的定义 ----------------- */ enum KAPProtoID { @@ -130,7 +135,8 @@ extern "C" // 告知应用程序最终使用的认证类型 KAP_REQ_CMD_NOTIFY_AUTH_TYPE = 0x60, }; - + +// PAM框架内通信协议 // PJK: proto json key // json消息的提示头 #define KAP_PROTO_JSON_PREFIX "kiran_authentication:" diff --git a/src/daemon/auth-config.cpp b/src/daemon/auth-config.cpp index 63e16ea443fa59f2d77b5ad679df4cdb7787b9cf..42e4614b935927e565e11a08672ef28c8b51662a 100644 --- a/src/daemon/auth-config.cpp +++ b/src/daemon/auth-config.cpp @@ -39,6 +39,7 @@ using namespace Kiran; #define INIFILE_AUHTTYPE_KEY_UNLOCK_ENABLE "UnlockEnable" #define INIFILE_AUTHTYPE_KEY_EMPOWERMENT "EmpowermentEnable" +//FIXME:去除该项,group name从utils中取,新增认证类型只需要在utils中做修改 static const QMap AuthTypeGroupMap = { { KAD_AUTH_TYPE_FINGERPRINT, @@ -55,6 +56,10 @@ static const QMap AuthTypeGroupMap = { { KAD_AUTH_TYPE_FINGERVEIN, "FingerVein" + }, + { + KAD_AUTH_TYPE_IRIS, + "Iris" } }; @@ -97,16 +102,16 @@ bool AuthConfig::init() bool AuthConfig::load() { - m_settings->beginGroup(INIFILE_GENERAL_GROUP_NAME); + //NOTE: General组不需要beginGroup auto autoMode = m_settings->value(INIFILE_GENERAL_KEY_AUTH_MODE, KAD_AUTH_MODE_STR_OR).toString(); m_authMode = Utils::authModeStr2Enum(autoMode); auto authOrder = m_settings->value(INIFILE_GENERAL_KEY_AUTH_ORDER, QStringList{AUTH_TYPE_STR_FINGERPRINT,AUTH_TYPE_STR_UKEY}).toStringList(); + KLOG_DEBUG() << "auth order" << authOrder; this->m_authOrder = Utils::authOrderStr2Enum(authOrder); auto maxFailures = m_settings->value(INIFILE_GENERAL_KEY_MAX_FAILURES, 3).toInt(); this->m_maxFailures = maxFailures; - m_settings->endGroup(); // 读取认证类型下设置项,认证类型开关默认都为关闭 const bool authTypeDefaultEnable = false; diff --git a/src/daemon/auth-manager.cpp b/src/daemon/auth-manager.cpp index 227393524fef6cf3535925e14f9794626ac1c639..0a74682248d2daca8d8a83a393ddfba9451df1cf 100644 --- a/src/daemon/auth-manager.cpp +++ b/src/daemon/auth-manager.cpp @@ -75,6 +75,7 @@ QDBusObjectPath AuthManager::CreateSession(const QString &username, int timeout, } this->m_serviceWatcher->addWatchedService(this->message().service()); + auto session = new Session(sessionID, this->message().service(), username, (KADAuthApplication)authApp, this); this->m_sessions.insert(sessionID, session); @@ -84,6 +85,7 @@ QDBusObjectPath AuthManager::CreateSession(const QString &username, int timeout, .arg(authApp) .arg(this->message().service()) .arg(sessionID); + return QDBusObjectPath(session->getObjectPath()); } @@ -185,37 +187,32 @@ QList AuthManager::GetAuthTypeByApp(int32_t authApp) auto enabledAuthTypes = m_authConfig->getAuthTypeByApp(authApp); auto authOrder = m_authConfig->getAuthOrder(); - // 通过默认认证类型顺序,过滤部分未开启的认证类型 - auto iter = authOrder.begin(); - while (iter != authOrder.end()) + // 在认证顺序指定的认证类型中过滤掉未开启的认证类型 + auto autoOrderIter = authOrder.begin(); + while (autoOrderIter != authOrder.end()) { - if (!enabledAuthTypes.contains(*iter)) + if (!enabledAuthTypes.contains(*autoOrderIter)) { - iter = authOrder.erase(iter); + autoOrderIter = authOrder.erase(autoOrderIter); } else - iter++; + autoOrderIter++; } - if (getAuthMode() == KAD_AUTH_MODE_AND) - { - // 与模式下,不加入未在默认顺序里的认证类型,只采用默认顺序里的配置 - } - else + auto sortedAuthTypes = authOrder; + + auto enabledAuthTypeIter = enabledAuthTypes.begin(); + while(enabledAuthTypeIter != enabledAuthTypes.end()) { - // 或模式下可选认证类型,加入未在默认顺序里且打开支持该认证应用的认证类型 - auto iter = enabledAuthTypes.begin(); - while (iter != enabledAuthTypes.end()) + if(!sortedAuthTypes.contains(*enabledAuthTypeIter)) { - if (!authOrder.contains(*iter)) - { - authOrder << *iter; - } - iter++; + sortedAuthTypes << *enabledAuthTypeIter; } + enabledAuthTypeIter++; } - KLOG_DEBUG() << "get auth types by app:" << authApp << "result:" << authOrder; - return authOrder; + + KLOG_DEBUG() << "get auth types by app:" << authApp << "result:" << sortedAuthTypes; + return sortedAuthTypes; } int AuthManager::QueryAuthApp(const QString &pamServiceName) diff --git a/src/daemon/device/device-adaptor-factory.cpp b/src/daemon/device/device-adaptor-factory.cpp index 2edaeef4ceab5a381289beb94e4a5428b4013645..d3ffe19e6f2f8ae5f5374002067aedb5cd502164 100644 --- a/src/daemon/device/device-adaptor-factory.cpp +++ b/src/daemon/device/device-adaptor-factory.cpp @@ -45,9 +45,12 @@ QSharedPointer DeviceAdaptorFactory::getDeviceAdaptor(int32_t aut { auto device = this->m_devices.value(authType); RETURN_VAL_IF_TRUE(device, device); + device = this->createDeviceAdaptor(authType); RETURN_VAL_IF_FALSE(device, QSharedPointer()); + KLOG_DEBUG() << "authtype:" << authType << "create device adaptor:" << device->getDeviceID(); + this->m_devices.insert(authType, device); return device; } @@ -163,7 +166,7 @@ QSharedPointer DeviceAdaptorFactory::getDBusDeviceProxy(int aut } else { - KLOG_DEBUG() << "Not found available fingerprint device."; + KLOG_DEBUG("Not found available %s device.",Utils::authTypeEnum2Str(authType).toStdString().c_str()); } } @@ -176,7 +179,7 @@ QSharedPointer DeviceAdaptorFactory::getDBusDeviceProxy(int aut } else { - KLOG_WARNING("Not found fingerprint device."); + KLOG_DEBUG("Not found %s device.",Utils::authTypeEnum2Str(authType).toStdString().c_str()); } return dbusDeviceProxy; diff --git a/src/daemon/device/device-adaptor-factory.h b/src/daemon/device/device-adaptor-factory.h index 6abc2bee9988684ef73e9f5601186d16a7b12e23..7fb935a30de1c3c7b707aa812682751a8ed521d0 100644 --- a/src/daemon/device/device-adaptor-factory.h +++ b/src/daemon/device/device-adaptor-factory.h @@ -22,6 +22,7 @@ namespace Kiran { class AuthManager; +// 设备适配器工厂 class DeviceAdaptorFactory : public QObject { Q_OBJECT @@ -35,8 +36,13 @@ public: static void globalInit(AuthManager *authManager); static void globalDeinit() { delete m_instance; }; + // 获取设备适配器,可通过设备适配器接口进行录入以及认证 QSharedPointer getDeviceAdaptor(int32_t authType); + + // 获取认证类型下当前的设备信息,从认证设备服务中获取,以JSON格式提供,转发出去 QString getDeivcesForType(int32_t authType); + + // 获取当前认证类型下所支持的所有驱动信息,从认证服务之中拿到,以JSON格式提供,转发出去 QString getDriversForType(int32_t authType); bool deleteFeature(const QString& dataID); bool setDrivereEanbled(const QString& driverName,bool enabled); diff --git a/src/daemon/device/device-adaptor.cpp b/src/daemon/device/device-adaptor.cpp index d3c0435668b6d28c529b5ace9737337f5e819e02..32c768fc9474c4fb47b54e4836deee7d96a0d58b 100644 --- a/src/daemon/device/device-adaptor.cpp +++ b/src/daemon/device/device-adaptor.cpp @@ -26,15 +26,20 @@ #include "src/daemon/proxy/login1-session-proxy.h" +#define ENROLL_TIMEOUT_MS 300000 +#define IDENTIFY_TIMEOUT_MS 60000 + #define DEVICE_DEBUG() KLOG_DEBUG() << this->m_deviceID namespace Kiran { -// TOOD:处理设备断开事件 DeviceAdaptor::DeviceAdaptor(QSharedPointer dbusDeviceProxy) : m_dbusDeviceProxy(nullptr), m_requestIDCount(-1) { + m_deviceOccupyTimer.setSingleShot(true); + connect(&m_deviceOccupyTimer,&QTimer::timeout,this,&DeviceAdaptor::onDeviceOccupyTimeout); + auto defaultSeat = Login1SeatProxy::getDefault(); connect(defaultSeat.get(), SIGNAL(activeSessionChanged(const Login1SessionItem &)), this, SLOT(onActiveSessionChanged(const Login1SessionItem &))); @@ -110,9 +115,11 @@ void DeviceAdaptor::updateDBusDeviceProxy(QSharedPointer dbusDe void DeviceAdaptor::pushRequest(QSharedPointer request) { this->m_requests.insert(request->reqID, request); - request->source->start(request); + request->source->queued(request); + // 如果当前插入的请求优先级比正在执行请求的优先级高,则进行抢占 auto pushPriority = request->source->getPriority(); + if (!this->m_currentRequest || (pushPriority > this->m_currentRequest->source->getPriority())) { @@ -167,10 +174,12 @@ void DeviceAdaptor::finishRequest() { if (this->m_currentRequest) { + stopDeviceOccupyTimer(); this->m_currentRequest->source->end(); this->m_requests.remove(this->m_currentRequest->reqID); this->m_currentRequest = nullptr; } + this->schedule(); } @@ -232,12 +241,13 @@ void DeviceAdaptor::enrollStart(const QString &extraInfo) { if (this->m_dbusDeviceProxy) { + startDeviceOccupyTimer(ENROLL_TIMEOUT_MS); this->m_dbusDeviceProxy->EnrollStart(extraInfo); } else { DEVICE_DEBUG() << "Not found fingerprint device, enroll failed."; - this->onEnrollStatus(QString(), EnrollResult::ENROLL_RESULT_FAIL, 0, ""); + this->onEnrollStatus(QString(), EnrollStatus::ENROLL_STATUS_FAIL, 0, ""); } } @@ -245,6 +255,7 @@ void DeviceAdaptor::enrollStop() { if (this->m_dbusDeviceProxy) { + stopDeviceOccupyTimer(); this->m_dbusDeviceProxy->EnrollStop(); } } @@ -254,12 +265,13 @@ void DeviceAdaptor::identifyStart(const QString &extraInfo) if (this->m_dbusDeviceProxy) { DEVICE_DEBUG() << "device proxy identify start"; + startDeviceOccupyTimer(IDENTIFY_TIMEOUT_MS); this->m_dbusDeviceProxy->IdentifyStart(extraInfo); } else { DEVICE_DEBUG() << "Not found fingerprint device, identify failed."; - this->onIdentifyStatus(QString(), IdentifyResult::IDENTIFY_RESULT_NOT_MATCH, ""); + this->onIdentifyStatus(QString(), IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH, ""); } } @@ -267,6 +279,7 @@ void DeviceAdaptor::identifyStop() { if (this->m_dbusDeviceProxy) { + stopDeviceOccupyTimer(); this->m_dbusDeviceProxy->IdentifyStop(); DEVICE_DEBUG() << "device proxy identify stop"; } @@ -280,6 +293,18 @@ bool DeviceAdaptor::isActiveSession(uint32_t pid) return session->activate(); } +void DeviceAdaptor::startDeviceOccupyTimer(int ms) +{ + DEVICE_DEBUG() << "start device occupy timer" << ms << "ms" << "for request:" << this->m_currentRequest->reqID; + m_deviceOccupyTimer.start(ms); +} + +void DeviceAdaptor::stopDeviceOccupyTimer() +{ + DEVICE_DEBUG() << "stop device occupy timer for request:" << this->m_currentRequest->reqID; + m_deviceOccupyTimer.stop(); +} + void DeviceAdaptor::onEnrollStatus(const QString &featureID, int progress, int result, const QString &message) { DEVICE_DEBUG() << "enroll status:" << featureID << result << progress << message; @@ -293,8 +318,8 @@ void DeviceAdaptor::onEnrollStatus(const QString &featureID, int progress, int r KLOG_WARNING("Not found current request."); } - if (result == EnrollResult::ENROLL_RESULT_COMPLETE || - result == EnrollResult::ENROLL_RESULT_FAIL) + if (result == EnrollStatus::ENROLL_STATUS_COMPLETE || + result == EnrollStatus::ENROLL_STATUS_FAIL) { this->finishRequest(); } @@ -313,8 +338,8 @@ void DeviceAdaptor::onIdentifyStatus(const QString &featureID, int result, const KLOG_WARNING("Not found current request."); } - if (result == IdentifyResult::IDENTIFY_RESULT_NOT_MATCH || - result == IdentifyResult::IDENTIFY_RESULT_MATCH) + if (result == IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH || + result == IdentifyStatus::IDENTIFY_STATUS_MATCH) { this->finishRequest(); } @@ -337,4 +362,11 @@ void DeviceAdaptor::onActiveSessionChanged(const Login1SessionItem &sessionItem) // 重新调度设备认证请求 this->schedule(); } + +void DeviceAdaptor::onDeviceOccupyTimeout() +{ + DEVICE_DEBUG() << QString("request: %1 occupy timeout,cancel!").arg(m_currentRequest->reqID); + this->removeRequest(m_currentRequest->reqID); +} + } // namespace Kiran diff --git a/src/daemon/device/device-adaptor.h b/src/daemon/device/device-adaptor.h index 75785f1ed17373e34f1c22a9ea3d180dd5b2106f..e6bcf6dc0664f95c61c8a84f64cdd79490432f3c 100644 --- a/src/daemon/device/device-adaptor.h +++ b/src/daemon/device/device-adaptor.h @@ -71,11 +71,14 @@ private: // 判断进程是否是活跃会话 bool isActiveSession(uint32_t pid); + void startDeviceOccupyTimer(int ms); + void stopDeviceOccupyTimer(); private Q_SLOTS: void onEnrollStatus(const QString &featureID, int result, int progress,const QString& message); void onIdentifyStatus(const QString &featureID, int result,const QString& message); void onActiveSessionChanged(const Login1SessionItem &sessionItem); + void onDeviceOccupyTimeout(); private: QSharedPointer m_dbusDeviceProxy; @@ -83,6 +86,7 @@ private: QSharedPointer m_currentRequest; int64_t m_requestIDCount; QString m_deviceID; + QTimer m_deviceOccupyTimer; }; } // namespace Kiran diff --git a/src/daemon/device/device-protocol.h b/src/daemon/device/device-protocol.h index 2c84c5d5d7d126792390b38e51c2cf4d2d2b10f4..3b732d2a5d534ea6127b639d7c0c562b49066079 100644 --- a/src/daemon/device/device-protocol.h +++ b/src/daemon/device/device-protocol.h @@ -65,7 +65,7 @@ public: virtual QString getSpecifiedUser() = 0; // 已经加入请求队列 - virtual void start(QSharedPointer request) = 0; + virtual void queued(QSharedPointer request) = 0; // 操作被中断,可能是有更高优先级的请求或者设备不可用等原因导致。任务还在处理队列中 virtual void interrupt() = 0; // 操作被取消, 可能是切换会话或其他原因导致,操作被取消应返回错误,但不应记录失败,任务将会被删除 diff --git a/src/daemon/error.cpp b/src/daemon/error.cpp index fcc1c19a8ae1e3d260fe8e48ed472aa6c8dfd4c3..8601e0ca496990cfd23770972de958d01ea2feea 100644 --- a/src/daemon/error.cpp +++ b/src/daemon/error.cpp @@ -32,6 +32,9 @@ QString KADError::getErrorDesc(KADErrorCode errorCode) case KADErrorCode::ERROR_USER_ENROLLING: errorDesc = QObject::tr("The user is enrolling."); break; + case ERROR_USER_FEATURE_LIMITS_EXCEEDED: + errorDesc = QObject::tr("User Feature limits exceeded"); + break; case KADErrorCode::ERROR_SESSION_EXCEED_MAX_SESSION_NUM: errorDesc = QObject::tr("Too many sessions."); break; diff --git a/src/daemon/error.h b/src/daemon/error.h index ea9ba5498153d82cf1becff3a157fe65a350c9aa..1539abaeb518cbedce89a72021a5402908caf437 100644 --- a/src/daemon/error.h +++ b/src/daemon/error.h @@ -59,6 +59,8 @@ enum KADErrorCode ERROR_USER_IID_ALREADY_EXISTS = 0x10000, // 正在录入中 ERROR_USER_ENROLLING, + // 达到特征绑定上限 + ERROR_USER_FEATURE_LIMITS_EXCEEDED, // 不存在该类型设备 ERROR_NO_DEVICE, diff --git a/src/daemon/session.cpp b/src/daemon/session.cpp index 149cba81fc70cff5467a56b6e00e053e8ba2410e..f24a69780073620d2eae9386fd1dcbda0ec11cec 100644 --- a/src/daemon/session.cpp +++ b/src/daemon/session.cpp @@ -194,10 +194,12 @@ QString Session::getSpecifiedUser() return this->m_userName; } -void Session::start(QSharedPointer request) +void Session::queued(QSharedPointer request) { this->m_verifyInfo.m_requestID = request->reqID; - KLOG_DEBUG() << m_sessionID << "session (request id:" << request->reqID << ") start"; + KLOG_DEBUG() << m_sessionID << "session (request id:" << request->reqID << ") queued"; + auto tips = QString(tr("Please wait while the %1 request is processed")).arg(Utils::authTypeEnum2LocaleStr(m_authType)); + Q_EMIT this->AuthMessage(tips, KAD_MESSAGE_TYPE_INFO); } void Session::interrupt() @@ -221,33 +223,39 @@ void Session::end() void Session::onIdentifyStatus(const QString &bid, int result, const QString &message) { KLOG_DEBUG() << m_sessionID << "verify identify status:" << bid << result << message; - + if (!this->matchUser(this->m_verifyInfo.authType, bid) && - result == IdentifyResult::IDENTIFY_RESULT_MATCH) + result == IdentifyStatus::IDENTIFY_STATUS_MATCH) { KLOG_DEBUG() << m_sessionID << "feature match successfully, but it isn't a legal user."; - result = IdentifyResult::IDENTIFY_RESULT_NOT_MATCH; + result = IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH; } auto verifyResultStr = Utils::identifyResultEnum2Str(result); - if (result == IdentifyResult::IDENTIFY_RESULT_MATCH) + if (result == IdentifyStatus::IDENTIFY_STATUS_MATCH) { Q_EMIT this->AuthMessage(verifyResultStr, KADMessageType::KAD_MESSAGE_TYPE_INFO); } - else + else if(result == IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH) { Q_EMIT this->AuthMessage(verifyResultStr, KADMessageType::KAD_MESSAGE_TYPE_ERROR); } + else + { + Q_EMIT this->AuthMessage(message, KADMessageType::KAD_MESSAGE_TYPE_INFO); + } - if (result == IdentifyResult::IDENTIFY_RESULT_MATCH || - result == IdentifyResult::IDENTIFY_RESULT_NOT_MATCH) + if (result == IdentifyStatus::IDENTIFY_STATUS_MATCH || + result == IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH) { - this->finishPhaseAuth(result == IdentifyResult::IDENTIFY_RESULT_MATCH); + this->finishPhaseAuth(result == IdentifyStatus::IDENTIFY_STATUS_MATCH, m_authMode == KAD_AUTH_MODE_OR); } } void Session::startPhaseAuth() { + m_waitForResponseFunc = nullptr; + // 开始阶段认证前,通知认证类型状态变更 emit this->m_dbusAdaptor->AuthTypeChanged(this->m_authType); switch (this->m_authType) @@ -268,6 +276,10 @@ void Session::startUkeyAuth() QJsonDocument jsonDoc(QJsonObject{QJsonObject{{"ukey", QJsonObject{{"pin", response}}}}}); startGeneralAuth(jsonDoc.toJson()); }; + + KLOG_DEBUG() << "auth prompt: input ukey code"; + Q_EMIT this->AuthMessage(tr("Insert the UKey and enter the PIN code"), KADMessageType::KAD_MESSAGE_TYPE_INFO); + Q_EMIT this->AuthPrompt(tr("please input ukey code."), KADPromptType::KAD_PROMPT_TYPE_SECRET); } void Session::startGeneralAuth(const QString &extraInfo) @@ -278,7 +290,7 @@ void Session::startGeneralAuth(const QString &extraInfo) auto authTypeStr = Utils::authTypeEnum2Str(this->m_authType); KLOG_WARNING() << m_sessionID << "start phase auth failed,invalid auth type:" << m_authType; Q_EMIT this->AuthMessage(tr(QString("Auth type %1 invalid").arg(authTypeStr).toStdString().c_str()), KADMessageType::KAD_MESSAGE_TYPE_ERROR); - this->finishPhaseAuth(false, m_authMode == KAD_AUTH_MODE_AND); + this->finishPhaseAuth(false, false); return; } @@ -288,7 +300,7 @@ void Session::startGeneralAuth(const QString &extraInfo) auto authTypeStr = Utils::authTypeEnum2Str(this->m_authType); KLOG_WARNING() << m_sessionID << "start phase auth failed,can not find device,auth type:" << m_authType; Q_EMIT this->AuthMessage(tr(QString("can not find %1 device").arg(authTypeStr).toStdString().c_str()), KADMessageType::KAD_MESSAGE_TYPE_ERROR); - this->finishPhaseAuth(false, m_authMode == KAD_AUTH_MODE_AND); + this->finishPhaseAuth(false, false); return; } diff --git a/src/daemon/session.h b/src/daemon/session.h index 32d635b51cdde9c3ef2747c73dbe3109ba5af1f1..2998f73118e5b265001d8fde2ecf083a9ba19955 100644 --- a/src/daemon/session.h +++ b/src/daemon/session.h @@ -88,7 +88,7 @@ private: virtual int32_t getPriority(); virtual int64_t getPID(); virtual QString getSpecifiedUser(); - virtual void start(QSharedPointer request); + virtual void queued(QSharedPointer request); virtual void interrupt(); virtual void cancel(); virtual void end(); diff --git a/src/daemon/user-config.cpp b/src/daemon/user-config.cpp index 36bb2832b787df5c0d01f1d1062220bb0749ba32..01faf1f76ca3da818b256c9e113f94f6c646275d 100644 --- a/src/daemon/user-config.cpp +++ b/src/daemon/user-config.cpp @@ -8,7 +8,6 @@ #include #include -#define INIFILE_GENERAL_GROUP_NAME "General" #define INIFILE_GENERAL_GROUP_KEY_IIDS "IIDs" // 连续认证失败次数计数 #define INIFILE_GENERAL_GROUP_KEY_FAILURES "Failures" @@ -20,7 +19,8 @@ using namespace Kiran; UserConfig::UserConfig(const QString& name, QObject* parent) - : QObject(parent) + : QObject(parent), + m_userName(name) { this->m_settings = new QSettings(QString(KDA_UESR_DATA_DIR "/").append(name), QSettings::IniFormat, this); init(); @@ -49,9 +49,7 @@ bool UserConfig::deleteIID(const QString& iid) this->m_iids.removeOne(iid); this->m_IIDAuthInfoMap.remove(iid); - this->m_settings->beginGroup(INIFILE_GENERAL_GROUP_NAME); m_settings->setValue(INIFILE_GENERAL_GROUP_KEY_IIDS, this->m_iids); - this->m_settings->endGroup(); this->m_settings->beginGroup(iid); this->m_settings->remove(""); @@ -153,10 +151,15 @@ int UserConfig::getFailures() void UserConfig::init() { - m_settings->beginGroup(INIFILE_GENERAL_GROUP_NAME); + KLOG_DEBUG() << "user config:" << m_userName; + auto iids = m_settings->value(INIFILE_GENERAL_GROUP_KEY_IIDS, QStringList()).toStringList(); + KLOG_DEBUG() << "iids:" << iids; + + // NOTE:错误次数记录只针对与多路认证模式 + // FIXME: 若多路认证模式错误次数过多,切换到多因子认证是否清理掉错误次数? this->m_failures = m_settings->value(INIFILE_GENERAL_GROUP_KEY_FAILURES, 0).toInt(); - m_settings->endGroup(); + KLOG_DEBUG() << "failures:" << this->m_failures; for (auto iid : iids) { @@ -170,6 +173,7 @@ void UserConfig::init() { KLOG_WARNING() << "user config:" << m_settings->fileName() << "iid:" << iid << " value is invalid!"; this->m_settings->remove(QString()); + m_settings->endGroup(); continue; } IIDInfo iidInfo{ @@ -177,6 +181,12 @@ void UserConfig::init() .authType = authType, .bid = bid}; + KLOG_DEBUG("feature name(%s) auth type(%s) iid(%s) bid(%s)", + name.toStdString().c_str(), + Utils::authTypeEnum2Str(authType).toStdString().c_str(), + iid.toStdString().c_str(), + bid.toStdString().c_str()); + m_IIDAuthInfoMap[iid] = iidInfo; m_iids << iid; @@ -193,9 +203,7 @@ bool UserConfig::addIID(int authType, const QString& iid, const QString& name, c m_iids << iid; m_IIDAuthInfoMap[iid] = {.name = name, .authType = authType, .bid = bid}; - m_settings->beginGroup(INIFILE_GENERAL_GROUP_NAME); m_settings->setValue(INIFILE_GENERAL_GROUP_KEY_IIDS, m_iids); - m_settings->endGroup(); m_settings->beginGroup(iid); m_settings->setValue(INIFILE_IID_GROUP_KEY_AUTH_TYPE, authTypeStr); @@ -224,10 +232,6 @@ void UserConfig::changeIIDName(const QString& iid, const QString& name) void UserConfig::setFailures(int failures) { RETURN_IF_TRUE(failures == m_failures); - - m_settings->beginGroup(INIFILE_GENERAL_GROUP_NAME); m_settings->setValue(INIFILE_GENERAL_GROUP_KEY_FAILURES, failures); - m_settings->endGroup(); - m_failures = failures; } \ No newline at end of file diff --git a/src/daemon/user-config.h b/src/daemon/user-config.h index 615d2ae2dcad974f9ca01765468f946fd3a9c3c9..e572a50f4f2bc71975fa0fd5baed925f7fd19bb7 100644 --- a/src/daemon/user-config.h +++ b/src/daemon/user-config.h @@ -34,6 +34,7 @@ private: void setFailures(int failures); private: + QString m_userName; struct IIDInfo { // iid名称 diff --git a/src/daemon/user.cpp b/src/daemon/user.cpp index b6ed12ec12a103e08bdcd3affeda7e5abbbd0068..1b77bf0ffeef50b645fa0f09cc0f374ff9174095 100644 --- a/src/daemon/user.cpp +++ b/src/daemon/user.cpp @@ -32,6 +32,7 @@ #define USER_DEBUG() KLOG_DEBUG() << this->m_pwent.pw_uid #define USER_WARNING() KLOG_WARNING() << this->m_pwent.pw_uid +#define FEATURE_COUNT_MAXIMUN 10 namespace Kiran { @@ -154,9 +155,11 @@ int64_t User::getPID() return DBusDaemonProxy::getDefault()->getConnectionUnixProcessID(this->m_enrollInfo.m_dbusMessage); } -void User::start(QSharedPointer request) +void User::queued(QSharedPointer request) { + KLOG_DEBUG() << getUserName() << "enroll (request id:" << request->reqID << ") queued"; this->m_enrollInfo.m_requestID = request->reqID; + Q_EMIT this->EnrollStatus(tr("Please wait while the request is processed"),false,0,""); } void User::interrupt() @@ -193,7 +196,7 @@ void User::onEnrollStatus(const QString &dataID, int progress, switch (result) { - case ENROLL_RESULT_COMPLETE: + case ENROLL_STATUS_COMPLETE: { auto authType = this->m_enrollInfo.m_authTpe; auto iidName = this->m_enrollInfo.m_feautreName; @@ -208,14 +211,14 @@ void User::onEnrollStatus(const QString &dataID, int progress, emit this->EnrollStatus(iid, true, progress, message); break; } - case ENROLL_RESULT_FAIL: + case ENROLL_STATUS_FAIL: emit this->EnrollStatus(QString(), true, progress, message); break; default: emit this->EnrollStatus(QString(), false, progress, message); break; } -} + } QString User::calcAction(const QString &originAction) { @@ -231,7 +234,7 @@ QString User::calcAction(const QString &originAction) void User::onEnrollStart(const QDBusMessage &message, int authType, const QString &name, const QString &extraInfo) { - if (this->m_enrollInfo.m_requestID > 0) + if (this->m_enrollInfo.m_requestID >= 0) { USER_DEBUG() << "start enroll failed,user is enrolling!"; DBUS_ERROR_REPLY_ASYNC_AND_RET(message, QDBusError::AccessDenied, KADErrorCode::ERROR_USER_ENROLLING); @@ -243,7 +246,13 @@ void User::onEnrollStart(const QDBusMessage &message, int authType, USER_WARNING() << "start enroll failed,no such device!"; DBUS_ERROR_REPLY_ASYNC_AND_RET(message, QDBusError::AddressInUse, KADErrorCode::ERROR_NO_DEVICE); } - + + if( m_userConfig->getIIDs(authType).count() >= FEATURE_COUNT_MAXIMUN) + { + USER_WARNING() << "the number of features has reached its maximum:" << FEATURE_COUNT_MAXIMUN; + DBUS_ERROR_REPLY_ASYNC_AND_RET(message, QDBusError::LimitsExceeded, KADErrorCode::ERROR_USER_FEATURE_LIMITS_EXCEEDED); + } + USER_DEBUG() << "enroll start" << authType << name << extraInfo; this->m_enrollInfo.m_dbusMessage = message; this->m_enrollInfo.deviceAdaptor = deviceAdaptor; @@ -257,7 +266,7 @@ void User::onEnrollStart(const QDBusMessage &message, int authType, void User::onEnrollStop(const QDBusMessage &message) { - if (this->m_enrollInfo.m_requestID > 0 && + if (this->m_enrollInfo.m_requestID >= 0 && this->m_enrollInfo.deviceAdaptor) { USER_DEBUG() << "enroll stop,stop request" << this->m_enrollInfo.m_requestID; diff --git a/src/daemon/user.h b/src/daemon/user.h index df5ed5d36075e35511fd50e85f9f35368378101f..55afe20d72caee46c1bb4c90278e43594bd16dfa 100644 --- a/src/daemon/user.h +++ b/src/daemon/user.h @@ -98,7 +98,7 @@ private: virtual int32_t getPriority(); virtual int64_t getPID(); virtual QString getSpecifiedUser() { return QString(); }; - virtual void start(QSharedPointer request); + virtual void queued(QSharedPointer request); virtual void interrupt(); virtual void cancel(); virtual void end(); diff --git a/src/pam/authentication-terminal.cpp b/src/pam/authentication-terminal.cpp index 5715a9736492df433febb93d83eeeceb21691ae4..c6df098d787e2df858c59cddda38c2cb83696eaf 100644 --- a/src/pam/authentication-terminal.cpp +++ b/src/pam/authentication-terminal.cpp @@ -47,12 +47,6 @@ void AuthenticationTerminal::notifySupportAuthType() int32_t AuthenticationTerminal::requestAuthType() { - QMap authTypeTranslator = { - {KAD_AUTH_TYPE_PASSWORD, tr("passwd")}, - {KAD_AUTH_TYPE_FINGERPRINT, tr("fingerprint")}, - {KAD_AUTH_TYPE_FACE, tr("face")}, - {KAD_AUTH_TYPE_UKEY, tr("ukey")}, - {KAD_AUTH_TYPE_FINGERVEIN, tr("fingervein")}}; do { // 从1开始生成认证类型以及序号,例如:"1 指纹认证","2 指静脉认证" @@ -62,13 +56,11 @@ int32_t AuthenticationTerminal::requestAuthType() auto authType = m_supportAuthTypes.at(i); QString authTypeStr = Utils::authTypeEnum2Str(authType); - if (authTypeTranslator.contains(authType)) - { - authTypeStr = authTypeTranslator[authType]; - } - else + authTypeStr = Utils::authTypeEnum2LocaleStr(authType); + if (authTypeStr.isEmpty()) { KLOG_WARNING() << "cann't find auth type translator:" << authType; + authTypeStr = QString("AuthType%1").arg(authType); } authTypeStringList << QString("%1 %2").arg(i + 1).arg(authTypeStr); @@ -89,7 +81,7 @@ int32_t AuthenticationTerminal::requestAuthType() // 校验输入正确 bool toIntOk = false; int selectedIdx = response.toInt(&toIntOk); - if( !toIntOk || selectedIdx<=0 || selectedIdx>m_supportAuthTypes.count() ) + if (!toIntOk || selectedIdx <= 0 || selectedIdx > m_supportAuthTypes.count()) { this->m_pamHandle->sendErrorMessage(tr("The authentication type is invalid. Please select a new one")); continue; @@ -110,5 +102,11 @@ int32_t AuthenticationTerminal::requestAuthType() return KADAuthType::KAD_AUTH_TYPE_PASSWORD; } - +#if 0 +void AuthenticationTerminal::notifyAuthType(int authType) +{ + QString tips = QString("%1 authentication is being performed").arg(Utils::authTypeEnum2Str(authType)); + this->m_pamHandle->sendTextMessage(tips); +} +#endif } // namespace Kiran diff --git a/src/pam/authentication-terminal.h b/src/pam/authentication-terminal.h index 1cd51037d6bfd1f28cd7ebf2f765e2fc36cd8f49..d1580e15c9978e562d7d61ba5dd24094fb3ee796 100644 --- a/src/pam/authentication-terminal.h +++ b/src/pam/authentication-terminal.h @@ -16,6 +16,7 @@ #include "src/pam/authentication.h" #include "kas-authentication-i.h" +#include namespace Kiran { @@ -31,10 +32,11 @@ private: virtual bool requestLoginUserSwitchable() { return false; }; virtual void notifySupportAuthType(); virtual int32_t requestAuthType(); - virtual void notifyAuthType(int authType) {} + virtual void notifyAuthType(int authType){}; private: QList m_supportAuthTypes; + QMap m_authTypeTranslator; }; } // namespace Kiran diff --git a/src/pam/authentication.cpp b/src/pam/authentication.cpp index 904be3fb3dded6a9557ee4a1eae4dc5686c76c5a..192a1b1909f8c07945a95989d4ca45435c2a42a5 100644 --- a/src/pam/authentication.cpp +++ b/src/pam/authentication.cpp @@ -113,14 +113,20 @@ int Authentication::checkFailures() { if (this->m_authUserProxy->failures() >= this->m_authManagerProxy->maxFailures()) { + KLOG_DEBUG() << "current failures:" << this->m_authUserProxy->failures(); + KLOG_DEBUG() << "max failures: " << this->m_authManagerProxy->maxFailures(); + this->m_pamHandle->syslog(LOG_DEBUG, QString("user:%1,failures:%2,max filures:%3") .arg(m_userName) .arg(this->m_authUserProxy->failures()) .arg(this->m_authManagerProxy->maxFailures())); this->m_pamHandle->sendErrorMessage(tr("Too many authentication failures, so the authentication mode is locked.")); const int authMode = this->m_authManagerProxy->authMode(); - return authMode == KAD_AUTH_MODE_AND ? PAM_SYSTEM_ERR : PAM_IGNORE; + auto ret = authMode == KAD_AUTH_MODE_AND ? PAM_SYSTEM_ERR : PAM_IGNORE; + KLOG_DEBUG() << "ret" << ret; + return ret; } + return PAM_SUCCESS; } @@ -218,6 +224,7 @@ int Authentication::startAuthPre() return PAM_SYSTEM_ERR; } } + this->notifyAuthType(this->m_authSessionProxy->authType()); auto connected = connect(m_authSessionProxy, &AuthSessionProxy::AuthTypeChanged, this, &Authentication::onAuthTypeChanged); return PAM_SUCCESS; @@ -341,6 +348,13 @@ void Authentication::onAuthSuccessed(const QString &userName) { this->m_pamHandle->setItem(PAM_USER, userName); } + + auto authMode = this->m_authManagerProxy->authMode(); + if( authMode == KAD_AUTH_MODE_AND ) + { + this->notifyAuthType(KAD_AUTH_TYPE_PASSWORD); + } + this->m_pamHandle->syslog(LOG_DEBUG, QString("Authentication successed,session ID:%1").arg(m_sessionID)); this->finishAuth(PAM_SUCCESS); } diff --git a/src/pam/main.cpp b/src/pam/main.cpp index 34380f18123a0e9b615c724984efdb95c35bd0f4..139c552563b6b001a39c4396a6636d9270692529 100644 --- a/src/pam/main.cpp +++ b/src/pam/main.cpp @@ -87,7 +87,9 @@ extern "C" int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, { arguments.push_back(argv[i]); } - + + pam_syslog(pamh,LOG_DEBUG,"arg:%s.",arguments.count()?arguments.first().toStdString().c_str():"null"); + auto controller = QSharedPointer::create(pamh, arguments); auto retval = controller->run(); @@ -152,7 +154,6 @@ extern "C" int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int, const char * { delete app; } - return retval; } diff --git a/src/pam/pam-args-parser.h b/src/pam/pam-args-parser.h index 41a64f1787ec30164c3b072f810d450f3fc99ce4..d50d5812b27d359768ef68999fbe76b1eb390d47 100644 --- a/src/pam/pam-args-parser.h +++ b/src/pam/pam-args-parser.h @@ -22,7 +22,6 @@ namespace Kiran #define KAP_ARG_ACTION_DO_AUTH "doauth" // 表示认证已经通过,这里会清理失败次数 #define KAP_ARG_ACTION_AUTH_SUCC "authsucc" - struct PAMArgsInfo { QString action; diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 9d54d41c38ac3ac97e724bac649a1215ba0997ba..648c5cefe131f9b3b3c2af84ef3ce1b5ead644ef 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace Kiran { @@ -97,6 +98,8 @@ QString Utils::authTypeEnum2Str(int authType) return QStringLiteral(AUTH_TYPE_STR_UKEY); case KADAuthType::KAD_AUTH_TYPE_FINGERVEIN: return QStringLiteral(AUTH_TYPE_STR_FINGERVEIN); + case KADAuthType::KAD_AUTH_TYPE_IRIS: + return QStringLiteral(AUTH_TYPE_STR_IRIS); default: KLOG_WARNING() << "Unknown authType: " << authType; } @@ -117,6 +120,8 @@ int Utils::authTypeStr2Enum(const QString& authType) return KADAuthType::KAD_AUTH_TYPE_UKEY; case CONNECT(AUTH_TYPE_STR_FINGERVEIN, _hash): return KADAuthType::KAD_AUTH_TYPE_FINGERVEIN; + case CONNECT(AUTH_TYPE_STR_IRIS, _hash): + return KADAuthType::KAD_AUTH_TYPE_IRIS; default: KLOG_WARNING() << "Unknown authType: " << authType; } @@ -133,6 +138,10 @@ int32_t Utils::authType2DeviceType(int32_t authType) return DeviceType::DEVICE_TYPE_Face; case KADAuthType::KAD_AUTH_TYPE_FINGERVEIN: return DeviceType::DEVICE_TYPE_FingerVein; + case KADAuthType::KAD_AUTH_TYPE_UKEY: + return DeviceType::DEVICE_TYPE_UKey; + case KAD_AUTH_TYPE_IRIS: + return DeviceType::DEVICE_TYPE_Iris; default: KLOG_WARNING() << "Unsupported authType: " << authType; } @@ -149,6 +158,10 @@ int32_t Utils::deviceType2AuthType(int32_t deviceType) return KADAuthType::KAD_AUTH_TYPE_FACE; case DeviceType::DEVICE_TYPE_FingerVein: return KADAuthType::KAD_AUTH_TYPE_FINGERVEIN; + case DeviceType::DEVICE_TYPE_UKey: + return KADAuthType::KAD_AUTH_TYPE_UKEY; + case DeviceType::DEVICE_TYPE_Iris: + return KADAuthType::KAD_AUTH_TYPE_IRIS; default: KLOG_WARNING() << "Unsupported deviceType: " << deviceType; } @@ -175,17 +188,40 @@ QList Utils::authOrderStr2Enum(const QStringList& authOrder) return retval; } +QString Utils::authTypeEnum2LocaleStr(int authType) +{ + QMap localeAuthTypeMap = { + {KAD_AUTH_TYPE_PASSWORD,QCoreApplication::tr("password")}, + {KAD_AUTH_TYPE_FINGERPRINT,QCoreApplication::tr("fingerprint")}, + {KAD_AUTH_TYPE_FACE,QCoreApplication::tr("face")}, + {KAD_AUTH_TYPE_FINGERVEIN,QCoreApplication::tr("fingervein")}, + {KAD_AUTH_TYPE_IRIS,QCoreApplication::tr("iris")}, + {KAD_AUTH_TYPE_UKEY,QCoreApplication::tr("ukey")} + }; + + auto iter = localeAuthTypeMap.find(authType); + if( iter == localeAuthTypeMap.end() ) + { + KLOG_WARNING("convert %d to locale string faield!",authType); + return ""; + } + + return iter.value(); +} + QString Utils::identifyResultEnum2Str(int32_t identifyResult) { switch (identifyResult) { - case IdentifyResult::IDENTIFY_RESULT_NOT_MATCH: + case IdentifyStatus::IDENTIFY_STATUS_NOT_MATCH: return QObject::tr("Feature not match."); - case IdentifyResult::IDENTIFY_RESULT_MATCH: + case IdentifyStatus::IDENTIFY_STATUS_MATCH: return QObject::tr("Feature matching successed."); - case IdentifyResult::IDENTIFY_RESULT_RETRY: + case IdentifyStatus::IDENTIFY_STATUS_RETRY: return QObject::tr("Feature not match, please retry it."); break; + case IdentifyStatus::IDENTIFY_STATUS_NORMAL: + return ""; default: return QObject::tr("Unknown verfication error."); } diff --git a/src/utils/utils.h b/src/utils/utils.h index f9b421148db5e958c32be9cd351f69630132672d..7de6701607527cb6b57482329a59f6796a7675df 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -34,6 +34,7 @@ public: static int authModeStr2Enum(const QString &authMode); static QString authTypeEnum2Str(int authType); + static QString authTypeEnum2LocaleStr(int authType); static int authTypeStr2Enum(const QString &authType); static int32_t authType2DeviceType(int32_t authType); diff --git a/translations/kiran-authentication-daemon.zh_CN.ts b/translations/kiran-authentication-daemon.zh_CN.ts index 4224d99fc716ecd50f0a4eccec733e30d29b4aaf..4292ee75f687bfcb7c8c541507484adcb70f9a10 100644 --- a/translations/kiran-authentication-daemon.zh_CN.ts +++ b/translations/kiran-authentication-daemon.zh_CN.ts @@ -9,19 +9,75 @@ 认证失败。 + + Kiran::Session + + + Please wait while the %1 request is processed + %1认证请求正在等待处理 + + + + Insert the UKey and enter the PIN code + 请插入UKey并输入PIN码 + + + + please input ukey code. + 请输入PIN码。 + + Kiran::User - + + Please wait while the request is processed + 请等待,录入请求正在处理 + + + Enroll has been interrupted. Please wait 录入中断请稍等 - + Enroll has been cancelled 录入已被取消 + + QCoreApplication + + + password + 密码 + + + + fingerprint + 指纹 + + + + face + 人脸 + + + + fingervein + 指静脉 + + + + iris + 虹膜 + + + + ukey + UKey + + QObject @@ -36,51 +92,56 @@ + User Feature limits exceeded + 用户特征已到上限 + + + Too many sessions. 过多认证会话。 - + The session is in authentication. 该会话正在认证中。 - + Internel error. 内部错误。 - + No Such Device. 不存在该类型设备。 - + Unknown error. 未知错误。 - + (error code: 0x%x) (错误码:0x%x) - + Feature not match. 特征不匹配。 - + Feature matching successed. 特征匹配成功。 - + Feature not match, please retry it. 特征不匹配,请重试。 - + Unknown verfication error. 未知认证错误。 diff --git a/translations/pam_kiran_authentication.zh_CN.ts b/translations/pam_kiran_authentication.zh_CN.ts index ae6a9e807e405ce6378905763cb5185c20041480..c73ab84921308832c00fbec793d925570da64984 100644 --- a/translations/pam_kiran_authentication.zh_CN.ts +++ b/translations/pam_kiran_authentication.zh_CN.ts @@ -4,7 +4,7 @@ Kiran::Authentication - + Too many authentication failures, so the authentication mode is locked. 错误次数过多,认证模式已被禁用。 @@ -12,60 +12,68 @@ Kiran::AuthenticationTerminal - - passwd - 密码认证 + + Select Authentication type (%1): + 请选择认证类型(%1): - - fingerprint - 指纹认证 + + The authentication type is invalid. Please select a new one + 该认证类型无效,请重新选择 + + + QCoreApplication - - face - 人脸认证 + + password + 密码 - - ukey - UKey认证 + + fingerprint + 指纹 - + + face + 人脸 + + + fingervein - 指静脉认证 + 指静脉 - - Select Authentication type (%1): - 请选择认证类型(%1): + + iris + 虹膜 - - The authentication type is invalid. Please select a new one - 该认证类型无效,请重新选择 + + ukey + UKey QObject - + Feature not match. 特征不匹配。 - + Feature matching successed. 特征匹配成功。 - + Feature not match, please retry it. 特征不匹配,请重试。 - + Unknown verfication error. 未知认证错误。