From 953fb420e534aa7b24caeb58881507b4d124e020 Mon Sep 17 00:00:00 2001 From: yangmin Date: Wed, 15 Nov 2023 10:24:48 +0800 Subject: [PATCH] feat(global config & single login): global config & single login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: 全局配置与单点登录 Log: 无 --- bioauth-bin/src/keywatcher.cpp | 10 +- bioauth-bin/src/main.cpp | 52 ++- bioauth/i18n_ts/mn.ts | 184 ++++++++ bioauth/i18n_ts/zh_CN.ts | 4 +- bioauth/i18n_ts/zh_HK.ts | 184 ++++++++ bioauth/include/bioauth.h | 1 + bioauth/include/biodevices.h | 3 + bioauth/include/biotypes.h | 3 + bioauth/include/loginoptionswidget.h | 1 + bioauth/include/uniauthservice.h | 6 +- bioauth/src/bioauth.cpp | 13 + bioauth/src/biodevices.cpp | 71 ++- bioauth/src/loginoptionswidget.cpp | 19 +- bioauth/src/uniauthservice.cpp | 39 ++ debian/control | 5 +- images/ukui-loginopt-finger.svg | 2 +- ...op.plicykit.pkexec.bioctl-helper.policy.in | 2 + ...esktop.plicykit.pkexec.biodrvctl.policy.in | 4 +- ...sktop.plicykit.pkexec.biorestart.policy.in | 4 +- pam-biometric/data/ukui-biometric.conf | 1 + polkit-agent/CMakeLists.txt | 3 +- polkit-agent/i18n_ts/mn.ts | 441 ++++++++++++++++++ polkit-agent/i18n_ts/zh_HK.ts | 441 ++++++++++++++++++ polkit-agent/src/PolkitListener.cpp | 1 + polkit-agent/src/mainwindow.cpp | 89 ++-- polkit-agent/src/mainwindow.ui | 24 +- polkit-agent/src/modeButton.cpp | 2 +- uniauth-backend/CMakeLists.txt | 10 +- uniauth-backend/src/CSingleton.h | 46 ++ uniauth-backend/src/biodeviceinfo.h | 5 + uniauth-backend/src/main.cpp | 3 + uniauth-backend/src/personalizeddata.cpp | 345 ++++++++++++++ uniauth-backend/src/personalizeddata.h | 140 ++++++ uniauth-backend/src/rsac.cpp | 199 ++++++++ uniauth-backend/src/rsac.h | 26 ++ uniauth-backend/src/serviceinterface.cpp | 331 ++++++++++++- uniauth-backend/src/serviceinterface.h | 62 ++- uniauth-backend/src/servicemanager.cpp | 2 + uniauth-backend/src/servicemanager.h | 1 + 39 files changed, 2667 insertions(+), 112 deletions(-) create mode 100644 bioauth/i18n_ts/mn.ts create mode 100644 bioauth/i18n_ts/zh_HK.ts create mode 100644 polkit-agent/i18n_ts/mn.ts create mode 100644 polkit-agent/i18n_ts/zh_HK.ts create mode 100644 uniauth-backend/src/CSingleton.h create mode 100644 uniauth-backend/src/personalizeddata.cpp create mode 100644 uniauth-backend/src/personalizeddata.h create mode 100644 uniauth-backend/src/rsac.cpp create mode 100644 uniauth-backend/src/rsac.h diff --git a/bioauth-bin/src/keywatcher.cpp b/bioauth-bin/src/keywatcher.cpp index 706f250..aaa4398 100644 --- a/bioauth-bin/src/keywatcher.cpp +++ b/bioauth-bin/src/keywatcher.cpp @@ -35,6 +35,7 @@ void KeyWatcher::run() current.c_cc[VMIN] = 1; current.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, ¤t); + bool isInputEnd = false; while(!isInterruptionRequested()){ @@ -52,11 +53,18 @@ void KeyWatcher::run() break; default: // 'q' | 'Q' or Esc - if((ch = getchar()) == 'q' || ch == 'Q' || ch == 27){ + if((ch = getchar()) == 'q' || ch == 'Q' || ch == 27 || ch == EOF){ tcsetattr(0, TCSANOW, &save); emit exit(); + if (ch == EOF) { + isInputEnd = true; + break; + } } } + if (isInputEnd) { + break; + } } tcsetattr(0, TCSANOW, &save); // 恢复原来的终端属性,以免干扰shall和之后的程序运行 diff --git a/bioauth-bin/src/main.cpp b/bioauth-bin/src/main.cpp index ed29e03..ae13ec6 100644 --- a/bioauth-bin/src/main.cpp +++ b/bioauth-bin/src/main.cpp @@ -93,6 +93,22 @@ void showMessage(const QString &message, int type) fprintf(stdout, RESET_COLOR); } +static bool isQuickInput() { + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(0, &readfds); // stdin + struct timeval timeout = {0, 10*1000}; + switch (select(32, &readfds, NULL, NULL, &timeout)) { + case 0: // time out + break; + case -1: // error + break; + default: + return true; + } + return false; +} + QString inputPinCode() { struct termios current; @@ -241,7 +257,7 @@ int main(int argc, char *argv[]) a.installTranslator(&translator_bin); QCommandLineParser parser; - QCommandLineOption serviceOption({"s", "service"}, QObject::tr("Sevice Name")); + QCommandLineOption serviceOption({"s", "service"}, QObject::tr("Sevice Name"), "service", ""); QCommandLineOption displayOption({"x", "display"}, QObject::tr("DISPLAY env"), "display", ":0"); QCommandLineOption usernameOption({"u", "user"}, QObject::tr("User"), "user", ""); QCommandLineOption debugOption({"d", "debug"}, QObject::tr("Display debug information")); @@ -258,6 +274,11 @@ int main(int argc, char *argv[]) logPrefix = "[pam-diaglog]:"; qInstallMessageHandler(outputMessage); + QString serverName = parser.value(serviceOption); + if (serverName == "sudo" && isQuickInput()) { + exit(BIO_ERROR); + } + QString userName = parser.value(usernameOption); if(userName.isEmpty()) exit(BIO_ERROR); @@ -298,12 +319,13 @@ int main(int argc, char *argv[]) }); QObject::connect(&bioAuth, &BioAuth::authComplete, &a, [&](uid_t uid_, int result, int retErrNo){ Q_UNUSED(retErrNo); + watcher.stop(); bool isBioEnable = bioDevices.GetBioAuthEnable(uid_); - bool isUkeyDevice = false; - if(deviceInfo && deviceInfo->biotype == 6){ - isUkeyDevice = true; - } + bool isUkeyDevice = false; + if(deviceInfo && deviceInfo->biotype == 6){ + isUkeyDevice = true; + } if(!isBioEnable && !isUkeyDevice){ showMessage(QObject::tr("BIOMETRIC AUTHENTICATION IS CLOSED"), RESULT); exit(BIO_IGNORE); @@ -328,11 +350,11 @@ int main(int argc, char *argv[]) showMessage(QObject::tr("Unable to verify %1, please enter password.").arg(bioDevices.bioTypeToString_tr(curDeviceInfo->biotype)),RESULT); exit(BIO_IGNORE); } - Option option = showOption(bioDevices.count() > 1); + Option option = showOption(bioDevices.getAllDevices().count() > 1); switch(option) { case OPTION_TRY_AGAIN: - if(deviceInfo->biotype == 6){ + if(deviceInfo->biotype == 6){ QString code = inputPinCode(); bioAuth.SetExtraInfo("pincode",code); } @@ -346,7 +368,7 @@ int main(int argc, char *argv[]) *deviceInfo = showDevices(bioDevices.getAllDevices()); bioAuth.setDevice(deviceInfo); - if(deviceInfo->biotype == 6){ + if(deviceInfo->biotype == 6){ QString code = inputPinCode(); bioAuth.SetExtraInfo("pincode",code); } @@ -360,12 +382,12 @@ int main(int argc, char *argv[]) { exit(BIO_ERROR); }else{ - if(deviceInfo->biotype == 6){ - showMessage(QObject::tr("AUTHENTICATION END"), START); + if(deviceInfo->biotype == 6){ + showMessage(QObject::tr("AUTHENTICATION END"), START); }else{ - showMessage(QObject::tr("BIOMETRIC AUTHENTICATION END"), START); - } - exit(BIO_IGNORE); + showMessage(QObject::tr("BIOMETRIC AUTHENTICATION END"), START); + } + exit(BIO_IGNORE); break; } default: @@ -375,8 +397,8 @@ int main(int argc, char *argv[]) }); if(deviceInfo->biotype == 6){ - QString code = inputPinCode(); - bioAuth.SetExtraInfo("pincode",code); + QString code = inputPinCode(); + bioAuth.SetExtraInfo("pincode",code); } bioAuth.startAuth(); diff --git a/bioauth/i18n_ts/mn.ts b/bioauth/i18n_ts/mn.ts new file mode 100644 index 0000000..b96b503 --- /dev/null +++ b/bioauth/i18n_ts/mn.ts @@ -0,0 +1,184 @@ + + + + + BioAuthWidget + + + Form + + + + More + 更多 + + + + + Retry + ᠳᠠᠬᠢᠨ ᠲᠤᠷᠰᠢᠬᠤ + + + Too many unsuccessful attempts,please enter password. + 验证失败达最大次数,请使用密码解锁 + + + Bioauth authentication failed, you still have %1 verification opportunities + 生物认证失败,您还有%1次尝试机会 + + + Password + ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋ + + + Current Device: + 当前设备: + + + + + %1 too many unsuccessful attempts,please enter password. + %1 ᠢᠯᠠᠭᠳᠠᠭᠰᠠᠨ ᠲᠤᠷᠰᠢᠬᠤ ᠤᠳᠠᠭ᠎ᠠ ᠲᠣᠭ᠎ᠠ ᠬᠡᠳᠦ ᠣᠯᠠᠨ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋ ᠣᠷᠣᠭᠤᠯᠤᠭᠠᠷᠠᠢ ᠃ + + + + %1 authentication failure,there are still %2 remaining opportunities + %1 ᠪᠡᠶ᠎ᠡ᠎ᠶ᠋ᠢᠨ ᠬᠢᠷᠢ᠎ᠶ᠋ᠢᠨ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠲᠤᠯᠠᠯᠲᠠ ᠢᠯᠠᠭᠳᠠᠪᠠ ᠂ ᠮᠥᠨ %2 ᠦᠯᠡᠳᠡᠬᠦ ᠲᠣᠬᠢᠶᠠᠯ ᠪᠣᠢ + + + + Please use wechat to scan the code + ᠸᠢᠴᠠᠲ᠎ᠢ᠋ᠶ᠋ᠠᠷ ᠦᠰᠦᠭ ᠰᠢᠷᠪᠢᠬᠦ ᠪᠣᠯᠪᠠᠤ + + + + BioDevices + + + Unplugging of %1 device detected + %1 ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ᠎ᠶ᠋ᠢ ᠰᠤᠭᠤᠯᠵᠤ ᠭᠠᠷᠭᠠᠨ ᠠ + + + + %1 device insertion detected + %1 ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠬᠠᠪᠴᠢᠭᠤᠯᠤᠭᠰᠠᠨ᠎ᠢ᠋ ᠪᠠᠢᠴᠠᠭᠠᠨ ᠣᠯᠪᠠ + + + + ukui-biometric-manager + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ᠎ᠤ᠋ᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠬᠠᠮᠢᠶᠠᠷᠤᠯᠲᠠ᠎ᠶ᠋ᠢᠨ ᠪᠠᠭᠠᠵᠢ + + + + biometric + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ᠎ᠤ᠋ᠨ ᠣᠨᠴᠠᠯᠢᠭ + + + + FingerPrint + ᠬᠤᠷᠤᠭᠤᠨ ᠬᠡ + + + + FingerVein + ᠬᠤᠷᠤᠭᠤᠨ ᠨᠠᠮᠵᠢᠭᠤᠨ ᠰᠤᠳᠠᠰᠤ + + + + Iris + ᠰᠣᠯᠣᠩᠭ᠎ᠠ ᠪᠦᠷᠬᠦᠭᠦᠯ + + + + Face + ᠬᠥᠮᠦᠨ᠎ᠦ᠌ ᠨᠢᠭᠤᠷ ᠲᠠᠨᠢᠬᠤ + + + + VoicePrint + ᠳᠠᠭᠤᠨ ᠡᠷᠢᠶᠡᠨ + + + + ukey + ᠠᠶᠤᠯᠭᠦᠢ ᠨᠢᠭᠤᠴᠠ ᠲᠦᠯᠬᠢᠭᠦᠷ + + + + QRCode + ᠬᠣᠶᠠᠷ ᠬᠡᠮᠵᠢᠯᠲᠦ ᠺᠣᠳ᠋ + + + Wechat + 微信 + + + + BioDevicesWidget + + + Form + + + + Device types: + 设备类型: + + + Back + 返回 + + + OK + 确定 + + + FingerPrint + 指纹 + + + + LoginOptionsWidget + + + Login Options + ᠲᠡᠮᠳᠡᠭᠯᠡᠬᠦ ᠰᠤᠩᠭᠤᠭᠳᠠᠬᠤᠨ + + + + Password + ᠨᠢᠭᠤᠴᠠ ᠺᠣᠳ᠋ + + + Wechat + 微信 + + + Biometric + 生物识别 + + + + QObject + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + diff --git a/bioauth/i18n_ts/zh_CN.ts b/bioauth/i18n_ts/zh_CN.ts index d009954..c2c6329 100644 --- a/bioauth/i18n_ts/zh_CN.ts +++ b/bioauth/i18n_ts/zh_CN.ts @@ -100,8 +100,8 @@ - ukey - + Ukey + 安全密钥 diff --git a/bioauth/i18n_ts/zh_HK.ts b/bioauth/i18n_ts/zh_HK.ts new file mode 100644 index 0000000..d71eed9 --- /dev/null +++ b/bioauth/i18n_ts/zh_HK.ts @@ -0,0 +1,184 @@ + + + + + BioAuthWidget + + + Form + + + + More + 更多 + + + + + Retry + 重試 + + + Too many unsuccessful attempts,please enter password. + 验证失败达最大次数,请使用密码解锁 + + + Bioauth authentication failed, you still have %1 verification opportunities + 生物认证失败,您还有%1次尝试机会 + + + Password + 密碼 + + + Current Device: + 当前设备: + + + + + %1 too many unsuccessful attempts,please enter password. + %1失敗的嘗試次數太多,請輸入密碼 + + + + %1 authentication failure,there are still %2 remaining opportunities + %1 身份驗證失敗,仍有 %2 個剩餘機會 + + + + Please use wechat to scan the code + 請使用微信掃碼 + + + + BioDevices + + + Unplugging of %1 device detected + 檢測到 %1 設備的拔出 + + + + %1 device insertion detected + 檢測到 %1 個設備插入 + + + + ukui-biometric-manager + 生物特徵管理工具 + + + + biometric + 生物特徵管理工具 + + + + FingerPrint + 指紋 + + + + FingerVein + 指靜脈 + + + + Iris + 虹膜 + + + + Face + 人臉 + + + + VoicePrint + 聲紋 + + + + ukey + 安全金鑰 + + + + QRCode + 微信掃碼 + + + Wechat + 微信 + + + + BioDevicesWidget + + + Form + + + + Device types: + 设备类型: + + + Back + 返回 + + + OK + 确定 + + + FingerPrint + 指纹 + + + + LoginOptionsWidget + + + Login Options + 登錄選項 + + + + Password + 密碼 + + + Wechat + 微信 + + + Biometric + 生物识别 + + + + QObject + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + diff --git a/bioauth/include/bioauth.h b/bioauth/include/bioauth.h index ee9d55b..56588f7 100644 --- a/bioauth/include/bioauth.h +++ b/bioauth/include/bioauth.h @@ -62,6 +62,7 @@ public: signals: void authComplete(int uid, bool result, int retErrNo); + void authFinished(); void notify(const QString &message); void notifyDetail(int deviceId, const QString &message); void frameWritten(int deviceId); diff --git a/bioauth/include/biodevices.h b/bioauth/include/biodevices.h index 2308138..630f25f 100644 --- a/bioauth/include/biodevices.h +++ b/bioauth/include/biodevices.h @@ -57,6 +57,7 @@ public: void setIsShowHotPlug(bool isShow); int GetUserDevFeatureCount(int uid,int drvid); int GetUserDevCount(int uid); + FeatureMap GetUserFeatures(int uid); bool getUseFirstDevice(); int getFailedTimes(); bool GetHiddenSwitchButton(); @@ -71,6 +72,8 @@ public: */ StatusReslut UpdateStatus(int drvid); bool GetBioAuthEnable(uid_t uid); + bool GetDirveIsIdle(int drvid); + void recordAuthDrive(QString appName,int drvid,bool insert); private: void connectToService(); diff --git a/bioauth/include/biotypes.h b/bioauth/include/biotypes.h index 07a940f..b286edb 100644 --- a/bioauth/include/biotypes.h +++ b/bioauth/include/biotypes.h @@ -225,6 +225,9 @@ Q_DECLARE_METATYPE(DeviceInfo) typedef std::shared_ptr DeviceInfoPtr; typedef QList DeviceList; typedef QMap DeviceMap; +typedef std::shared_ptr FeatureInfoPtr; +typedef QList FeatureList; +typedef QMap FeatureMap; QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo); const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo); diff --git a/bioauth/include/loginoptionswidget.h b/bioauth/include/loginoptionswidget.h index 31c69e2..7ef3db9 100644 --- a/bioauth/include/loginoptionswidget.h +++ b/bioauth/include/loginoptionswidget.h @@ -100,6 +100,7 @@ public: public slots: void readDevicesInfo(); void onIdentifyComplete(int uid, bool ret, int retErrNo); + void onAuthFinished(); void onStatusChanged(int drvid, const QString &message); void onFrameWritten(int drvid); void onUSBDeviceCountChange(int newNum); diff --git a/bioauth/include/uniauthservice.h b/bioauth/include/uniauthservice.h index 9bbe5b4..3ed8707 100644 --- a/bioauth/include/uniauthservice.h +++ b/bioauth/include/uniauthservice.h @@ -61,9 +61,13 @@ public Q_SLOTS: bool getUseFirstDevice(); // 获取是否隐藏切换按钮 bool getHiddenSwitchButton(); - + // 获取正在认证的应用 + QStringList getAuthingApp(); + // 获取应用认证的驱动 + int getAuthingAppDrivd(QString appName); public: bool isActivatable(); + void recordAuthDrive(QString appName,int drvid,bool insert); Q_SIGNALS: //默认设备改变 diff --git a/bioauth/src/bioauth.cpp b/bioauth/src/bioauth.cpp index df66f19..bf725dc 100644 --- a/bioauth/src/bioauth.cpp +++ b/bioauth/src/bioauth.cpp @@ -17,6 +17,7 @@ **/ #include "bioauth.h" #include +#include BioAuth::BioAuth(qint32 uid, const DeviceInfoPtr deviceInfo, QObject *parent) : QObject(parent), @@ -110,6 +111,11 @@ void BioAuth::startAuth() QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, &BioAuth::onIdentityComplete); }else{ + //使用sudo等命令时,不停止设备,当存在其他可认证设备时,使用其他可认证设备,否则使用密码 + if(qAppName() != "bioauth"){ + //stopops在identify之前使用时,不要调用getFeaturelist,否则会出现identify被停止的现象,应该时框架的bug。 + serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000)); + } QDBusPendingCall call = serviceInterface->asyncCallWithArgumentList("Identify", args); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, &BioAuth::onIdentityComplete); @@ -175,6 +181,7 @@ void BioAuth::stopAuth() QDBusReply reply = serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000)); + emit authFinished(); if(!reply.isValid()) qWarning() << "StopOps error: " << reply.error(); @@ -188,6 +195,7 @@ bool BioAuth::isAuthenticating() void BioAuth::onIdentityComplete(QDBusPendingCallWatcher *watcher) { + emit authFinished(); QDBusPendingReply reply = *watcher; if(reply.isError()){ isInAuthentication = false; @@ -227,6 +235,11 @@ void BioAuth::onStatusChanged(int deviceId, int statusType) LOG() << msg.errorMessage(); return; } + + if(deviceInfo && deviceInfo->device_id != deviceId){ + return ; + } + QString message = msg.arguments().at(0).toString(); LOG() << message; Q_EMIT notify(message); diff --git a/bioauth/src/biodevices.cpp b/bioauth/src/biodevices.cpp index 556ed1c..2f6a366 100644 --- a/bioauth/src/biodevices.cpp +++ b/bioauth/src/biodevices.cpp @@ -94,7 +94,7 @@ void BioDevices::onUSBDeviceHotPlug(int deviceId, int action, int devNumNow) "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QList args; - args<<(tr("ukui-biometric-manager")) + args<<(tr("Biometric Manager")) <<((unsigned int) 0) <<"biometric-manager" < qlist; + int listsize; + QDBusMessage result = serviceInterface->call(QStringLiteral("GetAllFeatureList"), uid, 0, -1); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return featureMap; + } + + QList variantList = result.arguments(); + listsize = variantList[0].value(); + variantList[1].value() >> qlist; + for (int i = 0; i < listsize; i++) { + FeatureInfoPtr pFeatureInfo = std::make_shared(); + qlist[i].variant().value() >> *pFeatureInfo; + featureMap[pFeatureInfo->device_shortname].append(pFeatureInfo); + } + + return featureMap; +} + int BioDevices::GetUserDevFeatureCount(int uid,int drvid) { - // stop last option - serviceInterface->call("StopOps", QVariant(drvid), QVariant(3000)); QDBusMessage FeatureResult = serviceInterface->call(QStringLiteral("GetFeatureList"),drvid,uid,0,-1); if(FeatureResult.type() == QDBusMessage::ErrorMessage) { @@ -218,7 +240,6 @@ int BioDevices::getFeatureCount(int uid, int indexStart, int indexEnd) int res = 0; for(int i = 0; i < deviceInfos.count(); i++) { DeviceInfoPtr deviceInfo = deviceInfos.at(i); - QDBusReply reply = serviceInterface->call("StopOps", QVariant(deviceInfo->device_id), QVariant(3000)); QDBusMessage featurecount = serviceInterface->call("GetFeatureList",deviceInfo->device_id,uid,indexStart,indexEnd); if(featurecount.type() == QDBusMessage::ErrorMessage) { @@ -237,6 +258,10 @@ QMap> BioDevices::getAllDevices() for(auto deviceInfo : deviceInfos) { if (deviceInfo->biotype == REMOTE_QRCODE_TYPE) // 终端不使用扫码 continue; + + if(!GetDirveIsIdle(deviceInfo->device_id)) + continue; + devices[deviceInfo->biotype].push_back(*deviceInfo); } @@ -406,6 +431,7 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType) if(deviceInfos.size() <= 0) return nullptr; + FeatureMap mapFeatures = GetUserFeatures(uid); if (m_uniAuthService && m_uniAuthService->isActivatable()) { QString defaultDeviceName = ""; struct passwd *pwdInfo = getpwuid(uid); @@ -416,7 +442,8 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType) if(!strDeviceName.isEmpty()) { ptrDevInfo = findDevice(strDeviceName); if (ptrDevInfo) { - if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) { + int isIdle = GetDirveIsIdle(ptrDevInfo->device_id); + if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){ defaultDeviceName = strDeviceName; } } @@ -454,9 +481,11 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType) bool defValid = false; DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName); if (ptrDevInfo) { - if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) { + int isIdle = GetDirveIsIdle(ptrDevInfo->device_id); + if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){ defValid = true; } + } if (!defValid) { @@ -467,11 +496,34 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid,int bioType) } } +void BioDevices::recordAuthDrive(QString appName, int drvid, bool insert) +{ + if(m_uniAuthService && m_uniAuthService->isActivatable()){ + m_uniAuthService->recordAuthDrive(appName,drvid,insert); + } +} + +bool BioDevices::GetDirveIsIdle(int drvid) +{ + if(m_uniAuthService && m_uniAuthService->isActivatable()){ + QStringList appList = m_uniAuthService->getAuthingApp(); + for(QString appName : appList){ + int id = m_uniAuthService->getAuthingAppDrivd(appName); + if(id == drvid){ + return false; + } + } + } + + return true; +} + DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid) { if(deviceInfos.size() <= 0) return nullptr; + FeatureMap mapFeatures = GetUserFeatures(uid); if (m_uniAuthService && m_uniAuthService->isActivatable()) { QString defaultDeviceName = ""; struct passwd *pwdInfo = getpwuid(uid); @@ -483,7 +535,8 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid) if(!strDeviceName.isEmpty()) { ptrDevInfo = findDevice(strDeviceName); if (ptrDevInfo) { - if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) { + int isIdle = GetDirveIsIdle(ptrDevInfo->device_id); + if(isIdle && mapFeatures.contains(ptrDevInfo->device_shortname)){ defaultDeviceName = strDeviceName; break; } @@ -525,7 +578,7 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid) bool defValid = false; DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName); if (ptrDevInfo) { - if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) { + if (mapFeatures.contains(ptrDevInfo->device_shortname)) { defValid = true; } } @@ -654,7 +707,7 @@ QString BioDevices::bioTypeToString_tr(int type) case BIOTYPE_VOICEPRINT: return tr("VoicePrint"); case LOGINOPT_TYPE_GENERAL_UKEY: - return tr("ukey"); + return tr("Ukey"); case REMOTE_QRCODE_TYPE: return tr("QRCode"); } diff --git a/bioauth/src/loginoptionswidget.cpp b/bioauth/src/loginoptionswidget.cpp index 955270c..b089b33 100644 --- a/bioauth/src/loginoptionswidget.cpp +++ b/bioauth/src/loginoptionswidget.cpp @@ -48,6 +48,7 @@ LoginOptionsWidget::LoginOptionsWidget(QWidget *parent) , m_bioDevices(new BioDevices()) , w_timer(nullptr) { + m_bioDevices->recordAuthDrive("polkit",0,false); initUI(); initConnections(); m_mapDisableDev.clear(); @@ -161,6 +162,9 @@ void LoginOptionsWidget::initConnections() connect(m_biomericProxy, &BioAuth::authComplete, this, &LoginOptionsWidget::onIdentifyComplete); + + connect(m_biomericProxy, &BioAuth::authFinished, + this, &LoginOptionsWidget::onAuthFinished); } if (m_bioDevices) { connect(m_bioDevices, &BioDevices::deviceCountChanged, @@ -399,6 +403,9 @@ void LoginOptionsWidget::readDevicesInfo() bool isQRCodeEnable = m_bioDevices->GetQRCodeEnable(); DeviceList deviceList = m_bioDevices->GetDevList(); QStringList listDefDevices = m_bioDevices->getAllDefDevices(); + FeatureMap mapFeatures = m_bioDevices->GetUserFeatures(m_uid); + qDebug() << m_uid <<",count:"<GetUserDevFeatureCount(m_uid, pDeviceInfo->device_id); + } else if(mapFeatures.contains(pDeviceInfo->device_shortname)){ + nDevFeatureCount = mapFeatures[pDeviceInfo->device_shortname].size(); } } qDebug() << *pDeviceInfo << ",FeatureCount:"<show(); } w_timer->start(); + m_bioDevices->recordAuthDrive("polkit",m_curDevInfo->device_id,true); m_biomericProxy->startAuth(m_uid, m_curDevInfo); } @@ -530,6 +538,13 @@ void LoginOptionsWidget::updatePixmap() } } +void LoginOptionsWidget::onAuthFinished() +{ + if(m_bioDevices){ + m_bioDevices->recordAuthDrive("polkit",0,false); + } +} + void LoginOptionsWidget::onIdentifyComplete(int uid, bool ret, int retErrNo) { if(m_isStopped == true) diff --git a/bioauth/src/uniauthservice.cpp b/bioauth/src/uniauthservice.cpp index 4f327af..8032cea 100644 --- a/bioauth/src/uniauthservice.cpp +++ b/bioauth/src/uniauthservice.cpp @@ -245,6 +245,45 @@ bool UniAuthService::getHiddenSwitchButton() } } +// 获取正在认证的应用 +QStringList UniAuthService::getAuthingApp() +{ + QDBusMessage result = call(QStringLiteral("getAllAuthApp")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getAuthingApp error:" << result.errorMessage(); + return QStringList(); + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toStringList(); + } else { + return QStringList(); + } +} + +// 获取应用认证的驱动 +int UniAuthService::getAuthingAppDrivd(QString appName) +{ + QDBusMessage result = call(QStringLiteral("getAppAuthDrive"),appName); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getAuthingAppDrivd error:" << result.errorMessage(); + return -1; + } + QList varResult = result.arguments(); + if (varResult.size() > 0) { + return varResult.takeFirst().toInt(); + } else { + return -1; + } +} + +void UniAuthService::recordAuthDrive(QString appName,int drvid,bool insert) +{ + call(QStringLiteral("recordAuthDrive"),appName,drvid,insert); +} + bool UniAuthService::isActivatable() { return m_isActivatable; diff --git a/debian/control b/debian/control index ef1f89e..0524ec2 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,10 @@ Build-Depends: cmake (>= 2.6), qttools5-dev, qttools5-dev-tools, libkysdk-sysinfo-dev, - libukui-log4qt-dev + libukui-log4qt-dev, + libssl-dev, + libkf5windowsystem-dev, + liblightdm-qt5-3-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://github.com/ukui/ukui-biometric-auth diff --git a/images/ukui-loginopt-finger.svg b/images/ukui-loginopt-finger.svg index ed0d828..c3d3762 100644 --- a/images/ukui-loginopt-finger.svg +++ b/images/ukui-loginopt-finger.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/pam-biometric/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in b/pam-biometric/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in index 62c21b6..917979d 100644 --- a/pam-biometric/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in +++ b/pam-biometric/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy.in @@ -8,9 +8,11 @@ Run the biometric authentication control tool 运行生物识别认证控制工具 འཁོར་སྐྱོད་སྐྱེ་དངོས་ཀྱི་ངོས་འཛིན་ཁས་ལེན་ཚོད་འཛིན་ཡོ་བྱད།། + ᠠᠵᠢᠯᠯᠠᠭᠠᠨ ᠤ ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠵᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ ᠃ Authentication is required to enable or disable biometric authentication 开启或关闭生物识别认证需要进行身份验证 སྒོ་རྒྱག་པའམ་ཡང་ན་སྒོ་རྒྱག་པའི་སྐྱེ་དངོས་ངོས་འཛིན་བདེན་དཔངར་སྤྲོད་བྱེད་པར་ཐོབ་ཐང་གི་ཚོད་ལྟསར་སྤྲོད་བྱ་དགོས། + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠨᠡᠭᠡᠭᠡᠬᠦ ᠪᠤᠶᠤ ᠬᠠᠭᠠᠬᠤ ᠳᠤ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨ᠎ᠠ᠃ stock_person no diff --git a/pam-biometric/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in b/pam-biometric/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in index aed20c3..708011b 100644 --- a/pam-biometric/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in +++ b/pam-biometric/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy.in @@ -8,9 +8,11 @@ Run the biometric device driver control tool 运行生物识别设备驱动控制工具 སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་ཚོད་འཛིན་ཡོ་བྱད་ + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠪᠡᠷ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠤᠨ᠎ᠠ ᠃ Authentication is required to change the status of biometric device's driver 改变生物识别设备驱动状态需要进行身份验证 - སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་གནས་ཚུལ་ལ་འགྱུར་ལྡོག་གཏོང་བར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས། + སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་གནས་ཚུལ་ལ་འགྱུར་ལྡོག་གཏོང་བར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས། + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢᠨ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠪᠠᠶᠢᠳᠠᠯ ᠢ ᠬᠤᠪᠢᠷᠠᠭᠤᠯᠬᠤ ᠳᠤ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ᠃ stock_person auth_admin diff --git a/pam-biometric/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in b/pam-biometric/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in index cbad164..0c5cf79 100644 --- a/pam-biometric/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in +++ b/pam-biometric/data/org.freedesktop.plicykit.pkexec.biorestart.policy.in @@ -8,9 +8,11 @@ Restart Service 重启生物特征服务 བསྐྱར་དུ་ཞབས་འདེགས་ཞུ་བ + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠤᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠡᠭᠢᠯᠡᠭᠦᠯᠪᠡ᠃ Authentication is required to restart biometric service 重启生物特征服务需要身份验证 - སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས། + སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས། + ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠰᠢᠨᠵᠢ ᠲᠡᠮᠳᠡᠭ ᠦᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠰᠡᠩᠬᠡᠷᠡᠭᠦᠯᠬᠦ ᠳᠦ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠢ ᠰᠢᠯᠭᠠᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨ᠎ᠠ ᠃ stock_person auth_admin diff --git a/pam-biometric/data/ukui-biometric.conf b/pam-biometric/data/ukui-biometric.conf index e96090b..0d1c89c 100644 --- a/pam-biometric/data/ukui-biometric.conf +++ b/pam-biometric/data/ukui-biometric.conf @@ -8,6 +8,7 @@ isShownInControlCenter=false UseFirstDevice=true MaxFailedTimes=5 HiddenSwitchButton=false +FaceTimeoutTimes=1 [Functions] EnableQRCode=true diff --git a/polkit-agent/CMakeLists.txt b/polkit-agent/CMakeLists.txt index fa7768e..c5065d1 100644 --- a/polkit-agent/CMakeLists.txt +++ b/polkit-agent/CMakeLists.txt @@ -6,6 +6,7 @@ pkg_check_modules(KDKINFO REQUIRED kysdk-sysinfo) find_package(PolkitQt5-1 REQUIRED 0.103.0) find_package(Qt5 COMPONENTS Core Widgets DBus X11Extras Xml Network Svg) +find_package(KF5WindowSystem) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) @@ -59,7 +60,7 @@ set(polkit_SRCS add_executable(polkit-ukui-authentication-agent-1 ${polkit_SRCS}) target_link_libraries(polkit-ukui-authentication-agent-1 - Qt5::Core Qt5::Widgets Qt5::DBus ${EXTRA_LIBS} + Qt5::Core Qt5::Widgets Qt5::DBus ${EXTRA_LIBS} KF5::WindowSystem ${POLKITQT-1_LIBRARIES} BioAuthWidgets -lrt diff --git a/polkit-agent/i18n_ts/mn.ts b/polkit-agent/i18n_ts/mn.ts new file mode 100644 index 0000000..ddf8371 --- /dev/null +++ b/polkit-agent/i18n_ts/mn.ts @@ -0,0 +1,441 @@ + + + + + BioAuthWidget + + Retry + 重试 + + + %1 too many unsuccessful attempts,please enter password. + %1验证失败达最大次数,请使用密码登录 + + + %1 authentication failure,there are still %2 remaining opportunities + %1认证失败,还剩%2次尝试机会 + + + Please use wechat to scan the code + 请使用微信扫码 + + + + BioDevices + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + Wechat + 微信 + + + QRCode + 二维码 + + + + LoginOptionsWidget + + Login Options + 登录选项 + + + Wechat + 微信 + + + + MainWindow + + + Authentication + ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ + + + Fingerprint authentication failed, you still have %1 verification opportunities + 指纹验证失败,您还有%1次尝试机会 + + + + Form + + + + More + 更多 + + + Restart + 重新开始 + + + Password + 密码 + + + + + + Biometric + ᠠᠮᠢᠳᠤ ᠪᠤᠳᠠᠰ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠵᠤ ᠢᠯᠭᠠᠨ ᠳᠠᠨᠢᠬᠤ + + + + use password + ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠭᠰᠠᠨ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ + + + DeviceType: + 设备类型: + + + Back + 返回 + + + Details + 详细 + + + Action Id: + 动作: + + + Description: + 描述: + + + Polkit.subject-pid: + Polkit.subject-pid: + + + Retry + 重试 + + + Device types: + 设备类型: + + + Vendor: + 发行商: + + + Action: + 动作: + + + Polkit.caller-pid: + Polkit.caller-pid: + + + + + Cancel + ᠦᠬᠡᠢᠰᠭᠡᠬᠦ᠌ + + + + + Authenticate + ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ + + + + + Use password + ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠭᠰᠠᠨ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ + + + Auth + 授权 + + + Too many unsuccessful attempts,please enter password. + 指纹验证失败达最大次数,请使用密码解锁 + + + %1 authentication failure,there are still %2 remaining opportunities + %1认证失败,还剩%2次尝试机会 + + + %1 too many unsuccessful attempts,please enter password. + %1验证失败达最大次数,请使用密码登录 + + + in authentication, please wait... + 认证中,请稍等... + + + + + + Please try again in %1 minutes. + %1 ᠮᠢᠨᠦ᠋ᠲ᠎ᠦᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠱᠢᠭᠠᠷᠠᠢ. + + + + + + Please try again in %1 seconds. + %1 ᠮᠢᠨᠦ᠋ᠲ᠎ᠦᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠱᠢᠭᠠᠷᠠᠢ. + + + + + + + Account locked permanently. + ᠳᠠᠩᠰᠠ ᠨᠢᠭᠡᠨᠳᠡ ᠦᠨᠢᠳᠡ ᠤᠨᠢᠰᠤᠯᠠᠭᠳᠠᠪᠠ. + + + + + Password cannot be empty + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠬᠤᠭᠤᠰᠤᠨ ᠪᠠᠢᠵᠤ ᠪᠤᠯᠬᠤ ᠦᠬᠡᠢ + + + Failed to verify %1, please enter password. + 验证%1失败,请输入密码. + + + Unable to verify %1, please enter password. + 无法验证%1,请输入密码. + + + + + Failed to verify %1, you still have %2 verification opportunities + %1᠎ᠶᠢᠨ/᠎ᠦᠨ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠢᠴᠠᠭᠠᠯᠳᠠ ᠢᠯᠠᠭᠳᠠᠪᠠ ᠂ ᠲᠠ ᠪᠠᠰᠠ%2 ᠤᠳᠠᠭᠠᠨ᠎ᠤ ᠳᠤᠷᠱᠢᠬᠤ ᠵᠠᠪᠱᠢᠶᠠᠨ ᠲᠠᠢ + + + An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. + 一个程序正试图执行一个需要特权的动作。要求授权以执行该动作。 + + + + Password: + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋᠄ + + + + Please enter your password or enroll your fingerprint + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠪᠤᠶᠤ ᠬᠤᠷᠤᠭᠤᠨ ᠤ᠋ ᠤᠷᠤᠮ ᠵᠢᠨᠨ ᠤᠷᠤᠭᠤᠯᠤᠭᠠᠷᠠᠢ + + + + Abnormal network + ᠲᠤᠷ ᠰᠦᠯᠵᠢᠶ᠎ᠡ ᠬᠡᠪ ᠤ᠋ᠨ ᠪᠤᠰᠤ + + + + This operation requires the administrator's authorization. Please enter your password to allow this operation. + ᠳᠤᠰ ᠤᠳᠠᠭᠠᠨ ᠤ᠋ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢᠨ ᠬᠠᠮᠢᠶᠠᠷᠤᠭᠴᠢ ᠵᠢᠨ ᠡᠷᠬᠡ ᠤᠯᠭᠤᠯᠳᠠ ᠪᠡᠷ ᠰᠠᠶᠢ ᠦᠷᠬᠦᠯᠵᠢᠯᠡᠨ ᠬᠡᠷᠡᠭᠵᠢᠬᠦᠯᠦᠨ᠎ᠡ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠵᠢᠨᠨ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠳᠤᠰ ᠠᠵᠢᠯᠯᠠᠬᠤᠢ ᠵᠢ ᠵᠦᠪᠰᠢᠶᠡᠷᠡᠭᠡᠷᠡᠢ. + + + + _Password: + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋: + + + + _Password: + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋: + + + + Authentication failed, please try again. + ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠵᠤ ᠴᠢᠳᠠᠭᠰᠠᠨ ᠦᠬᠡᠢ᠂ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ. + + + + days left + ᠡᠳᠦᠷ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨ᠎ᠠ + + + Biometric/code scan authentication failed too many times, please enter the password. + 生物/扫码验证失败达最大次数,请使用密码解锁. + + + Bioauth/code scan authentication failed, you still have %1 verification opportunities + 生物/扫码验证失败,您还有%1次尝试机会 + + + + + + Failed to verify %1, please enter password to unlock + %1᠎ᠶᠢ/᠎ᠢ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠠᠷᠭ᠎ᠠ ᠦᠬᠡᠢ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + + + Unable to verify %1, please enter password to unlock + %1᠎ᠶᠢ/᠎ᠢ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠠᠷᠭ᠎ᠠ ᠦᠬᠡᠢ ᠂ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + NET Exception + 网络异常 + + + + A program is attempting to perform an action that requires privileges.It requires authorization to perform the action. + ᠨᠢᠭᠡ ᠫᠡᠷᠦᠭᠷᠡᠮ ᠶᠠᠭ ᠨᠢᠭᠡ ᠤᠨᠠᠴᠠ ᠡᠷᠬᠡ ᠬᠡᠷᠡᠭᠰᠡᠬᠦ ᠬᠦᠳᠡᠯᠬᠡᠬᠡᠨ ᠢ᠋ ᠬᠡᠷᠡᠭᠵᠢᠬᠦᠯᠬᠦ ᠪᠡᠷ ᠳᠤᠷᠰᠢᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠂ ᠳᠤᠰ ᠬᠦᠳᠡᠯᠬᠡᠬᠡᠨ ᠢ᠋ ᠬᠦᠢᠴᠡᠳᠬᠡᠬᠦ ᠡᠷᠬᠡ ᠤᠯᠭᠤᠬᠤ ᠵᠢ ᠱᠠᠭᠠᠷᠳᠠᠵᠤ ᠪᠠᠢᠨ᠎ᠠ. + + + + + Input Password + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠬᠤ + + + + Insert the ukey into the USB port + ᠠᠮᠤᠷ ᠲᠦᠪᠰᠢᠨ ᠦ ᠨᠢᠭᠤᠴᠠ ᠶᠢ USB ᠦᠵᠦᠭᠦᠷ ᠲᠦ ᠬᠠᠳᠬᠤᠵᠤ ᠣᠷᠣᠭᠠᠷᠠᠢ ᠃ + + + + Enter the ukey password + ᠠᠮᠤᠷ ᠲᠦᠪᠰᠢᠨ ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠢ ᠣᠷᠣᠭᠤᠯᠤᠨ᠎ᠠ ᠃ + + + + hours left + ᠨᠢᠭᠡ ᠴᠠᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨ᠎ᠠ + + + + minutes left + ᠮᠢᠨᠦ᠋ᠲ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨ᠎ᠠ + + + + seconds left + ᠰᠸᠺᠦᠨ᠋ᠲ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠤᠨᠢᠰᠤ ᠳᠠᠢᠯᠤᠨ᠎ᠠ + + + + + Input your password to authentication + ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠣᠷᠣᠭᠤᠯᠬᠤ ᠳᠤ ᠡᠷᠬᠡ ᠣᠯᠭᠣᠨ᠎ᠠ ᠃ + + + + Verify face recognition or enter password to unlock + ᠨᠢᠭᠤᠷ ᠱᠢᠷᠪᠢᠵᠤ ᠪᠠᠳᠤᠯᠭᠠᠵᠢᠭᠤᠯᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + Press fingerprint or enter password to unlock + ᠬᠤᠷᠤᠭᠤᠨ᠎ᠤ ᠤᠷᠤᠮ ᠳᠠᠷᠤᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + Verify voiceprint or enter password to unlock + ᠳᠠᠭᠤ᠎ᠪᠠᠷ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + Verify finger vein or enter password to unlock + ᠬᠤᠷᠤᠭᠤᠨ᠎ᠤ ᠨᠠᠮᠵᠢᠭᠤᠨ ᠰᠤᠳᠠᠯ᠎ᠢᠶᠠᠷ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + Verify iris or enter password to unlock + ᠰᠤᠯᠤᠩᠭ᠎ᠠ ᠪᠦᠷᠬᠦᠪᠴᠢ᠎ᠶᠢ ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠬᠤ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + + Use the bound wechat scanning code or enter the password to unlock + ᠤᠶᠠᠭᠰᠠᠨ ᠸᠢᠴᠠᠲ᠎ᠢᠶᠠᠷ ᠺᠤᠳ᠋ ᠱᠢᠷᠪᠢᠬᠦ᠌ ᠪᠤᠶᠤ ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠤᠷᠤᠭᠤᠯᠵᠤ ᠤᠨᠢᠰᠤ᠎ᠶᠢ ᠳᠠᠢᠯᠤᠭᠠᠷᠠᠢ + + + Use the bound wechat scanning code or enter the password to log in + 使用绑定的微信扫码或输入密码登录 + + + + + + + Account locked, + ᠳᠠᠨᠭᠰᠠ ᠵᠢ ᠨᠢᠬᠡᠨᠳᠡ ᠤᠨᠢᠰᠤᠯᠠᠪᠠ + + + Authentication failed, please try again + 认证失败,请重试 + + + + PolkitListener + + + Another client is already authenticating, please try again later. + ᠦᠬᠡᠷ᠎ᠡ ᠨᠢᠭᠡ ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ ᠵᠢᠨ ᠦᠵᠦᠬᠦᠷᠯᠢᠭ ᠢ᠋ ᠶᠠᠭ ᠨᠤᠳᠠᠯᠠᠵᠤ ᠪᠠᠢᠨ᠎ᠠ᠂ ᠤᠳᠠᠰᠬᠢᠭᠠᠳ ᠳᠠᠬᠢᠨ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ. + + + + Authentication failure, please try again. + ᠰᠢᠯᠭᠠᠨ ᠪᠠᠳᠤᠯᠠᠵᠤ ᠴᠢᠳᠠᠭᠰᠠᠨ ᠦᠬᠡᠢ᠂ ᠳᠠᠬᠢᠵᠤ ᠳᠤᠷᠰᠢᠭᠠᠷᠠᠢ. + + + + Password input error! + ᠨᠢᠭᠤᠴᠠ ᠺᠤᠳ᠋ ᠢ᠋ ᠪᠤᠷᠤᠭᠤ ᠤᠷᠤᠭᠤᠯᠪᠠ! + + + Account locked %1 minutes due to %2 fail attempts + 账户锁定%1分钟由于%2次错误尝试 + + + Authentication failure,there are still %1 remaining opportunities + 认证失败,还剩余%1次尝试机会 + + + + QObject + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + Cancel + 取消 + + + diff --git a/polkit-agent/i18n_ts/zh_HK.ts b/polkit-agent/i18n_ts/zh_HK.ts new file mode 100644 index 0000000..93978c7 --- /dev/null +++ b/polkit-agent/i18n_ts/zh_HK.ts @@ -0,0 +1,441 @@ + + + + + BioAuthWidget + + Retry + 重试 + + + %1 too many unsuccessful attempts,please enter password. + %1验证失败达最大次数,请使用密码登录 + + + %1 authentication failure,there are still %2 remaining opportunities + %1认证失败,还剩%2次尝试机会 + + + Please use wechat to scan the code + 请使用微信扫码 + + + + BioDevices + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + Wechat + 微信 + + + QRCode + 二维码 + + + + LoginOptionsWidget + + Login Options + 登录选项 + + + Wechat + 微信 + + + + MainWindow + + + Authentication + 授權 + + + Fingerprint authentication failed, you still have %1 verification opportunities + 指纹验证失败,您还有%1次尝试机会 + + + + Form + + + + More + 更多 + + + Restart + 重新开始 + + + Password + 密码 + + + + + + Biometric + 使用生物識別 + + + + use password + 使用密碼驗證 + + + DeviceType: + 设备类型: + + + Back + 返回 + + + Details + 详细 + + + Action Id: + 动作: + + + Description: + 描述: + + + Polkit.subject-pid: + Polkit.subject-pid: + + + Retry + 重试 + + + Device types: + 设备类型: + + + Vendor: + 发行商: + + + Action: + 动作: + + + Polkit.caller-pid: + Polkit.caller-pid: + + + + + Cancel + 取消 + + + + + Authenticate + 授權 + + + + + Use password + 使用密碼驗證 + + + Auth + 授权 + + + Too many unsuccessful attempts,please enter password. + 指纹验证失败达最大次数,请使用密码解锁 + + + %1 authentication failure,there are still %2 remaining opportunities + %1认证失败,还剩%2次尝试机会 + + + %1 too many unsuccessful attempts,please enter password. + %1验证失败达最大次数,请使用密码登录 + + + in authentication, please wait... + 认证中,请稍等... + + + + + + Please try again in %1 minutes. + 請%1分鐘后再試 + + + + + + Please try again in %1 seconds. + 請%1秒後再試 + + + + + + + Account locked permanently. + 帳號已被永久鎖定 + + + + + Password cannot be empty + 密碼不能為空 + + + Failed to verify %1, please enter password. + 验证%1失败,请输入密码. + + + Unable to verify %1, please enter password. + 无法验证%1,请输入密码. + + + + + Failed to verify %1, you still have %2 verification opportunities + 驗證%1失敗,您還有%2次嘗試機會 + + + An application is attempting to perform an action that requires privileges. Authentication is required to perform this action. + 一个程序正试图执行一个需要特权的动作。要求授权以执行该动作。 + + + + Password: + 密碼: + + + + Please enter your password or enroll your fingerprint + 請輸入密碼或者錄入指紋 + + + + Abnormal network + 網路異常 + + + + This operation requires the administrator's authorization. Please enter your password to allow this operation. + 本次操作需要通過管理員的授權才能繼續執行,請輸入密碼以允許本次操作。 + + + + _Password: + 密碼: + + + + _Password: + 密碼: + + + + Authentication failed, please try again. + 認證失敗,請重試。 + + + + days left + 天后解鎖 + + + Biometric/code scan authentication failed too many times, please enter the password. + 生物/扫码验证失败达最大次数,请使用密码解锁. + + + Bioauth/code scan authentication failed, you still have %1 verification opportunities + 生物/扫码验证失败,您还有%1次尝试机会 + + + + + + Failed to verify %1, please enter password to unlock + 驗證%1失敗,請輸入密碼解鎖 + + + + + + Unable to verify %1, please enter password to unlock + 無法驗證%1,請輸入密碼解鎖 + + + NET Exception + 网络异常 + + + + A program is attempting to perform an action that requires privileges.It requires authorization to perform the action. + 一個程式正試圖執行一個需要特權的動作,要求授權以執行該動作。 + + + + + Input Password + 輸入密碼 + + + + Insert the ukey into the USB port + 請將安全金鑰插入USB埠 + + + + Enter the ukey password + 輸入安全金鑰密碼 + + + + hours left + 小時後解鎖 + + + + minutes left + 分鐘後解鎖 + + + + seconds left + 秒後解鎖 + + + + + Input your password to authentication + 輸入密碼以認證 + + + + Verify face recognition or enter password to unlock + 驗證人臉識別或輸入密碼解鎖 + + + + Press fingerprint or enter password to unlock + 按壓指紋或輸入密碼解鎖 + + + + Verify voiceprint or enter password to unlock + 驗證聲紋或輸入密碼解鎖 + + + + Verify finger vein or enter password to unlock + 驗證指靜脈或輸入密碼解鎖 + + + + Verify iris or enter password to unlock + 驗證虹膜或輸入密碼解鎖 + + + + Use the bound wechat scanning code or enter the password to unlock + 使用綁定的微信掃碼或輸入密碼解鎖 + + + Use the bound wechat scanning code or enter the password to log in + 使用绑定的微信扫码或输入密码登录 + + + + + + + Account locked, + 帳戶已鎖定, + + + Authentication failed, please try again + 认证失败,请重试 + + + + PolkitListener + + + Another client is already authenticating, please try again later. + 有另外一個用戶端正在認證,請稍後重試。 + + + + Authentication failure, please try again. + 認證失敗,請重試。 + + + + Password input error! + 密碼輸入錯誤! + + + Account locked %1 minutes due to %2 fail attempts + 账户锁定%1分钟由于%2次错误尝试 + + + Authentication failure,there are still %1 remaining opportunities + 认证失败,还剩余%1次尝试机会 + + + + QObject + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + Cancel + 取消 + + + diff --git a/polkit-agent/src/PolkitListener.cpp b/polkit-agent/src/PolkitListener.cpp index 88d9cdb..67fe34c 100644 --- a/polkit-agent/src/PolkitListener.cpp +++ b/polkit-agent/src/PolkitListener.cpp @@ -357,6 +357,7 @@ void PolkitListener::onShowPrompt(const QString &prompt, bool echo) mainWindow->setPrompt(prompt, echo); } + mainWindow->setFixedSize(mainWindow->width(),mainWindow->height()); mainWindow->show(); // 重新开始认证不调整窗口位置 // QPoint pos = QCursor::pos(); diff --git a/polkit-agent/src/mainwindow.cpp b/polkit-agent/src/mainwindow.cpp index e8b66c1..c72a01d 100644 --- a/polkit-agent/src/mainwindow.cpp +++ b/polkit-agent/src/mainwindow.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ MainWindow::MainWindow(QWidget *parent) : m_nCurLockMin(0), isbioSuccess(false) { + KWindowSystem::setState(this->winId(), NET::SkipTaskbar | NET::SkipPager); ui->setupUi(this); setWindowTitle(tr("Authentication")); setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint); @@ -97,6 +99,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->titleTipLayout->addWidget(m_labelTip); ui->loginOptionsLayout->setAlignment(Qt::AlignTop|Qt::AlignCenter); ui->loginOptionsLayout->addWidget(m_loginOptsWidget); + ui->loadingUkeyWidget->adjustSize(); ui->loadingUkeyWidget->hide(); ui->widgetUkeyAuth->hide(); ui->loadingUkeyBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true); @@ -105,14 +108,12 @@ MainWindow::MainWindow(QWidget *parent) : ui->loadingUkeyLbl->setAlignment(Qt::AlignTop|Qt::AlignHCenter); ui->ukeyTipLbl->setText(tr("Enter the ukey password")); ui->ukeyPassword->setPlaceholderText(tr("Input Password")); - ui->loadingUkeyWidget->adjustSize(); maxFailedTimes = bioDevices.getFailedTimes(); isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton(); connect(m_loginOptsWidget, &LoginOptionsWidget::optionSelected, this, [&](unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo){ - - isLoadingUkey = false; + isLoadingUkey = false; if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY){ stopLoadingUkey(); @@ -142,7 +143,7 @@ MainWindow::MainWindow(QWidget *parent) : if (uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && !deviceInfo){ isLoadingUkey = true; - startLoadingUkey(); + startLoadingUkey(); m_loginOptsWidget->updateUkeyUIStatus(LOGINOPT_TYPE_GENERAL_UKEY); }else if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY && deviceInfo){ stopLoadingUkey(); @@ -157,8 +158,8 @@ MainWindow::MainWindow(QWidget *parent) : return ; } - if(m_bioTimer) - m_bioTimer->stop(); + if(m_bioTimer) + m_bioTimer->stop(); m_deviceInfo = deviceInfo; switchLoginOptType(uCurLoginOptType); @@ -365,24 +366,27 @@ void MainWindow::setUkeyTypeTip(QString text) void MainWindow::startLoadingUkey() { + m_loadingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(27,27); + ui->loadingUkeyBtn->setIcon(m_loadingPixmap); + ui->loadingUkeyBtn->setIconSize(QSize(27, 27)); + + ui->loadingUkeyWidget->adjustSize(); + ui->cmbUsers->hide(); + ui->widgetUkeyAuth->hide(); + ui->lePassword->hide(); + + ui->widgetPasswdAuth->hide(); + isLoadingUkey = true; ui->loadingUkeyWidget->show(); + if(!m_loadingTimer) { m_loadingTimer = new QTimer(this); m_loadingTimer->setInterval(150); connect(m_loadingTimer, &QTimer::timeout, this, &MainWindow::updateLoadingPixmap); } - - m_loadingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(27,27); - ui->loadingUkeyBtn->setIcon(m_loadingPixmap); - ui->loadingUkeyBtn->setIconSize(QSize(27, 27)); m_loadingTimer->start(); - ui->loadingUkeyWidget->adjustSize(); - ui->cmbUsers->hide(); - ui->widgetUkeyAuth->hide(); - ui->lePassword->hide(); - ui->widgetPasswdAuth->hide(); } void MainWindow::stopLoadingUkey() @@ -391,9 +395,10 @@ void MainWindow::stopLoadingUkey() if(m_loadingTimer){ m_loadingTimer->stop(); } + ui->loadingUkeyWidget->hide(); //ui->cmbUsers->show(); - ui->widgetUkeyAuth->show(); + //ui->widgetUkeyAuth->show(); } void MainWindow::updateLoadingPixmap() @@ -874,6 +879,7 @@ void MainWindow::switchAuthMode(Mode mode) int count = m_loginOptsWidget->getLoginOptCount(); enableBioAuth = count > 0; if (count < 1) { + setLoginTypeTip(tr("Input your password to authentication")); m_loginOptsWidget->hide(); } else { m_loginOptsWidget->show(); @@ -881,6 +887,7 @@ void MainWindow::switchAuthMode(Mode mode) } if(m_loginOptsWidget->getHasUkeyOptions()){ + setLoginTypeTip(tr("Input your password to authentication")); m_loginOptsWidget->show(); } @@ -1074,6 +1081,7 @@ void MainWindow::switchWidget(Mode mode) ui->returnButton->setText(tr("Use password")); ui->btnLoading->setDisabled(true); ui->returnButton->adjustSize(); + m_labelTip->adjustSize(); if(is_Mavis){ ui->cmbUsers->setFixedHeight(48); ui->lePassword->setFixedHeight(48); @@ -1084,8 +1092,7 @@ void MainWindow::switchWidget(Mode mode) switch(mode){ case PASSWORD: { - setMinimumWidth(420); - setMaximumWidth(420); + setFixedWidth(420); if (m_deviceInfo && m_loginOptsWidget->findDeviceById(m_deviceInfo->device_id)) { switchLoginOptType(m_loginOptsWidget->convertDeviceType(m_deviceInfo->biotype)); @@ -1121,18 +1128,16 @@ void MainWindow::switchWidget(Mode mode) + ui->cmbUsers->height() + ui->lePassword->height() + ui->lblMessage->height() + ui->btnAuth->height(); } - if (m_loginOptsWidget->isHidden()) { - height -= 20 ; - } +// if (m_loginOptsWidget->isHidden()) { +// height = height - m_labelTip->height() - 10; +// } unsigned uOptsWidgetHeight = m_loginOptsWidget->height(); if (m_loginOptsWidget->isHidden()) { uOptsWidgetHeight = 0; - height -= 20 ; + height = height + m_labelTip->height() - 10; } - setMinimumHeight(height + uOptsWidgetHeight + 10); - setMaximumHeight(height + uOptsWidgetHeight + 10); - + setFixedHeight(height + uOptsWidgetHeight + 10); //m_loginOptsWidget->updateUIStatus(); ui->btnBioAuth->setStyleSheet("QPushButton{font-size:14px;}QPushButton:hover{border:none;color:#3E6CE5;}QPushButton:pressed{border:none;}"); @@ -1163,14 +1168,11 @@ void MainWindow::switchWidget(Mode mode) break; case BIOMETRIC: - setMinimumWidth(420); - setMaximumWidth(420); + setFixedWidth(420); if(m_loginOptsWidget->getLoginOptCount() <= 1){ - setMinimumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height()); - setMaximumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height()); + setFixedHeight(392+ui->cmbUsers->height()+ui->lblHeader->height()); } else { - setMinimumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height()); - setMaximumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height()); + setFixedHeight(482+ui->cmbUsers->height()+ui->lblHeader->height()); } ui->btnCancel->hide(); @@ -1484,11 +1486,15 @@ void MainWindow::setLoginTypeTip(QString strLoginTypeTip) m_labelTip->hide(); } else { QPalette pe; - if(no_changes) + if(no_changes) { pe.setColor(QPalette::WindowText,Qt::red); - else - pe.setColor(QPalette::WindowText,QColor(55, 144, 250, 255)); - m_labelTip->setPalette(pe); + m_labelTip->setPalette(pe); + } else { + QColor color = palette().color(QPalette::WindowText); + QPalette pal(this->palette()); + pal.setColor(QPalette::WindowText,QColor(color)); + m_labelTip->setPalette(pal); + } m_labelTip->setText(m_strLoginTypeTip); m_labelTip->show(); } @@ -1499,7 +1505,7 @@ void MainWindow::startBioAuthDelay() if (m_deviceInfo) { if(m_deviceInfo->biotype == LOGINOPT_TYPE_GENERAL_UKEY){ - }else{ + }else{ m_loginOptsWidget->startAuth(m_deviceInfo, getUid(userName)); } switchLoginOptType(m_loginOptsWidget->convertDeviceType(m_deviceInfo->biotype)); @@ -1589,17 +1595,14 @@ void MainWindow::onUpdateWndSize(unsigned uLoginOptType, unsigned uLoginOptSize) + ui->btnAuth->height(); } if (m_loginOptsWidget->isHidden()) { - height -= 20 ; + height = height + m_labelTip->height() - 10; } if(uLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY){ - - setMinimumHeight(height + uOptsWidgetHeight + 10); - setMaximumHeight(height + uOptsWidgetHeight + 10); + setLoginTypeTip(""); + setFixedSize(width(), height + uOptsWidgetHeight + 10); }else{ - - setMinimumHeight(height + uOptsWidgetHeight); - setMaximumHeight(height + uOptsWidgetHeight); + setFixedSize(width(), height + uOptsWidgetHeight); } } diff --git a/polkit-agent/src/mainwindow.ui b/polkit-agent/src/mainwindow.ui index e9cf404..01fc13b 100644 --- a/polkit-agent/src/mainwindow.ui +++ b/polkit-agent/src/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 459 - 547 + 646 @@ -120,6 +120,9 @@ + + 8 + 8 @@ -380,19 +383,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -410,7 +400,7 @@ - PointingHandCursor + ArrowCursor @@ -442,7 +432,7 @@ - PointingHandCursor + ArrowCursor @@ -461,7 +451,7 @@ - PointingHandCursor + ArrowCursor diff --git a/polkit-agent/src/modeButton.cpp b/polkit-agent/src/modeButton.cpp index 53d0ffc..66f712c 100644 --- a/polkit-agent/src/modeButton.cpp +++ b/polkit-agent/src/modeButton.cpp @@ -39,7 +39,7 @@ void ModeButton::initUI() setModeIcon(); setFixedSize(QSize(24, 24)); setModeIcon(); - setCursor(Qt::PointingHandCursor); + setCursor(Qt::ArrowCursor); setStyleSheet("QPushButton::pressed{border:none;background-color:transparent}" "QPushButton::hover::!pressed{border:none;background-color:transparent}"); diff --git a/uniauth-backend/CMakeLists.txt b/uniauth-backend/CMakeLists.txt index 4ba44ec..5ee3930 100644 --- a/uniauth-backend/CMakeLists.txt +++ b/uniauth-backend/CMakeLists.txt @@ -2,9 +2,12 @@ project(uniauth-backend) set(CMAKE_AUTOMOC ON) +pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) + include_directories( ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} + ${LIGHTDM-QT5-3_INCLUDE_DIRS} ) set(bin_SRCS @@ -16,10 +19,15 @@ set(bin_SRCS src/serviceinterface.cpp src/servicemanager.h src/servicemanager.cpp + src/personalizeddata.h + src/CSingleton.h + src/personalizeddata.cpp + src/rsac.h + src/rsac.cpp ) add_executable(uniauth-backend ${bin_SRCS}) -target_link_libraries(uniauth-backend Qt5::Core Qt5::DBus -lukui-log4qt) +target_link_libraries(uniauth-backend Qt5::Core Qt5::DBus -lukui-log4qt ${LIGHTDM-QT5-3_LIBRARIES} -lcrypto) install(TARGETS uniauth-backend DESTINATION bin) install(FILES org.ukui.UniauthBackend.conf DESTINATION /etc/dbus-1/system.d/) diff --git a/uniauth-backend/src/CSingleton.h b/uniauth-backend/src/CSingleton.h new file mode 100644 index 0000000..99c42d8 --- /dev/null +++ b/uniauth-backend/src/CSingleton.h @@ -0,0 +1,46 @@ +#ifndef CSINGLETON_H +#define CSINGLETON_H + + +template +class SingleTon +{ +public: + // 创建单例实例 + template + static T* instance(Args&&... args) + { + if (m_pInstance == nullptr) + { + m_pInstance = new T(std::forward(args)...); + } + + return m_pInstance; + } + + // 获取单例 + static T* getInstance() + { + return m_pInstance; + } + + // 删除单例 + static void destroyInstance() + { + delete m_pInstance; + m_pInstance = nullptr; + } + +private: + SingleTon(); + virtual ~SingleTon(); + +private: + static T* m_pInstance; +}; + +template +T* SingleTon::m_pInstance = nullptr; + + +#endif diff --git a/uniauth-backend/src/biodeviceinfo.h b/uniauth-backend/src/biodeviceinfo.h index 3ec5c81..87c5f87 100644 --- a/uniauth-backend/src/biodeviceinfo.h +++ b/uniauth-backend/src/biodeviceinfo.h @@ -21,6 +21,7 @@ #include #include #include +#include struct DeviceInfo { int device_id; @@ -52,6 +53,10 @@ enum BioType { Q_DECLARE_METATYPE(DeviceInfo) Q_DECLARE_METATYPE(QList) + +typedef std::shared_ptr DeviceInfoPtr; +typedef QList DeviceList; + void registerCustomTypes(); QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo); const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo); diff --git a/uniauth-backend/src/main.cpp b/uniauth-backend/src/main.cpp index e52bac8..f719754 100644 --- a/uniauth-backend/src/main.cpp +++ b/uniauth-backend/src/main.cpp @@ -17,6 +17,7 @@ **/ #include #include "serviceinterface.h" +#include "personalizeddata.h" #include int main(int argc, char *argv[]) @@ -24,6 +25,8 @@ int main(int argc, char *argv[]) initUkuiLog4qt("ukui-biometric-uniauth"); QCoreApplication a(argc, argv); + KYLINUSERDATAMNG::instance(); + ServiceInterface serviveInterface; Q_UNUSED(serviveInterface); diff --git a/uniauth-backend/src/personalizeddata.cpp b/uniauth-backend/src/personalizeddata.cpp new file mode 100644 index 0000000..d093977 --- /dev/null +++ b/uniauth-backend/src/personalizeddata.cpp @@ -0,0 +1,345 @@ +#include "personalizeddata.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +enum enum_operation +{ + enum_operation_update = 0, + enum_operation_add, + enum_operation_del, +}; + +PersonalizedData::PersonalizedData(QString user) +{ + KyInfo() << user; + m_user = user; + m_usd_conf_path = QString("/var/lib/lightdm-data/%1/usd/config/ukui-settings-daemon.settings").arg(m_user); + m_greeter_conf_path = QString("/var/lib/lightdm-data/%1/ukui-greeter.conf").arg(m_user); + m_file_watch = new QFileSystemWatcher(); + connect(m_file_watch, &QFileSystemWatcher::fileChanged, this, &PersonalizedData::fileChanged); + this->__load_conf_ukuigreeterconf(); + //无需读取usd配置 + //this->__load_conf_usd_conf(); + +} + +PersonalizedData::~PersonalizedData() +{ + KyInfo() << m_user; + if(0 != m_conf_TimerID) + { + this->killTimer(m_conf_TimerID); + m_conf_TimerID = 0; + } + if(nullptr != m_file_watch) + { + delete m_file_watch; + m_file_watch = nullptr; + } + +} + +void PersonalizedData::getJsonData(QJsonObject & json) +{ + json["user"] = m_user; + { + QJsonObject json_1; + json_1["dateType"] = m_dateType; + json_1["fontSize"] = m_fontSize; + json_1["timeType"] = m_timeType; + json_1["backgroundPath"] = m_backgroundPath; + json_1["color"] = m_color; + json["greeter"] = json_1; + } +} + +QString PersonalizedData::getJsonData() +{ + QJsonObject json; + this->getJsonData(json); + json["operation"] = enum_operation_update; + QJsonDocument document; + document.setObject(json); + return document.toJson(QJsonDocument::Compact); +} + +void PersonalizedData::fileChanged(const QString &path) +{ + KyInfo() << path; + if(m_greeter_conf_path == path) + { + m_greeter_conf_path_changed = true; + } + if(m_usd_conf_path == path) + { + m_usd_conf_path_changed = true; + } + + if(0 != m_conf_TimerID) + { + this->killTimer(m_conf_TimerID); + m_conf_TimerID = 0; + } + m_conf_TimerID = this->startTimer(100); +} + +void PersonalizedData::timerEvent(QTimerEvent *event) +{ + KyInfo() << m_file_watch->files(); + if(event->timerId() == m_conf_TimerID) + { + this->killTimer(m_conf_TimerID); + m_conf_TimerID = 0; + + if(m_greeter_conf_path_changed) + { + m_greeter_conf_path_changed = false; + this->__load_conf_ukuigreeterconf(); + } + if(m_usd_conf_path_changed) + { + m_usd_conf_path_changed = false; + this->__load_conf_usd_conf(); + } + emit KYLINUSERDATAMNG::getInstance()->conf_changed(this->getJsonData()); + } +} + +int PersonalizedData::__load_conf_ukuigreeterconf() +{ + KyInfo(); + QSettings conf(m_greeter_conf_path, QSettings::IniFormat); + if(QSettings::NoError != conf.status()) + { + KyWarning() << m_greeter_conf_path << conf.status(); + return -1; + } + + if(conf.childGroups().contains("Greeter")) + { + conf.beginGroup("Greeter"); + + if(conf.contains("dateType")) + m_dateType = conf.value("dateType", m_dateType).toString(); + + if(conf.contains("fontSize")) + m_fontSize = conf.value("fontSize", m_fontSize).toInt(); + + if(conf.contains("timeType")) + m_timeType = conf.value("timeType", m_timeType).toInt(); + + conf.endGroup(); + } + + if(conf.childGroups().contains("greeter")) + { + conf.beginGroup("greeter"); + + if(conf.contains("backgroundPath")) + { + m_backgroundPath = conf.value("backgroundPath", m_backgroundPath).toString(); + if(!m_backgroundPath.isEmpty()) + { + m_backgroundPath = this->__copy_file(m_backgroundPath); + } + } + + + if(conf.contains("color")) + m_color = conf.value("color", m_color).toString(); + + conf.endGroup(); + } + + if(nullptr != m_file_watch && !m_file_watch->files().contains(m_greeter_conf_path)) + { + m_file_watch->addPath(m_greeter_conf_path); + } + return 0; +} + +int PersonalizedData::__load_conf_usd_conf() +{ + KyInfo(); + QSettings conf(m_usd_conf_path, QSettings::IniFormat); + if(QSettings::NoError != conf.status()) + { + KyWarning() << m_usd_conf_path << conf.status(); + return -1; + } + + if(conf.childGroups().contains("xsettings")) + { + conf.beginGroup("xsettings"); + + if(conf.contains("cursor-size")) + m_cursor_size = conf.value("cursor-size", m_cursor_size).toInt(); + + if(conf.contains("cursor-theme")) + m_cursor_theme = conf.value("cursor-theme", m_cursor_theme).toString(); + + if(conf.contains("scaling-factor")) + m_scaling_factor = conf.value("scaling-factor", m_scaling_factor).toInt(); + + conf.endGroup(); + } + + if(nullptr != m_file_watch && !m_file_watch->files().contains(m_usd_conf_path)) + { + m_file_watch->addPath(m_usd_conf_path); + } + return 0; +} + +QString PersonalizedData::__copy_file(QString oldfile) +{ + if(QFile::exists(oldfile)) + { + QString newfile = "/tmp/loginBackground-" + m_user; + QDate d =QDate::currentDate(); + newfile += d.toString("yyyy-MM-dd"); + if(QFile::exists(newfile)) + { + QFile::remove(newfile); + } + if(QFile::copy(oldfile, newfile)) + { + return newfile; + } + } + return ""; +} + + + +/////////////////////////PersonalizedDataMng////////////////////////////////////// + +PersonalizedDataMng::PersonalizedDataMng(void) +{ + m_usersModel = new QLightDM::UsersModel(this); + connect(m_usersModel, &QAbstractListModel::rowsInserted, this, &PersonalizedDataMng::onUserAdded); + connect(m_usersModel, &QAbstractListModel::rowsRemoved, this, &PersonalizedDataMng::onUserRemoved); + this->__updateUsersInfo(); +} + +PersonalizedDataMng::~PersonalizedDataMng() +{ + if(nullptr != m_usersModel) + { + delete m_usersModel; + m_usersModel = nullptr; + } +} + +QString PersonalizedDataMng::GetConfInformation(QString name) +{ + QJsonObject json; + if(m_userPersonalizedData.contains(name)) + { + QJsonObject json1; + m_userPersonalizedData[name]->getJsonData(json1); + json[name] = json1; + } + else if(name.isEmpty()) + { + for(auto & it : m_userPersonalizedData.toStdMap()) + { + QJsonObject json1; + it.second->getJsonData(json1); + json[it.first] = json1; + } + } + else if("lightdm" == name) + { + QString tmp(m_lightdm_str); + m_lightdm_str = ""; + return tmp; + } + + QJsonDocument document; + document.setObject(json); + QString strJson(document.toJson(QJsonDocument::Compact)); + KyDebug() << strJson; + return strJson; +} + +void PersonalizedDataMng::SetLoginSynInformation(QString val) +{ + m_lightdm_str = val; +} + +void PersonalizedDataMng::onUserAdded(const QModelIndex &, int left, int right) +{ + if(!m_usersModel) + return; + + for(int i = left; i <= right; i++) + { + QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString(); + KyInfo() << left << right << name; + if(!name.isEmpty()) + { + m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name)); + + QJsonObject json; + m_userPersonalizedData[name]->getJsonData(json); + json["operation"] = enum_operation_add; + QJsonDocument document; + document.setObject(json); + emit conf_changed(document.toJson()); + } + } +} + +void PersonalizedDataMng::onUserRemoved(const QModelIndex &, int, int) +{ + if(!m_usersModel) + return; + + auto tmp = m_userPersonalizedData; + for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++) + { + QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString(); + if(!name.isEmpty()) + tmp.remove(name); + } + + if(tmp.size() > 0) + { + KyInfo() << tmp.begin().key(); + m_userPersonalizedData.remove(tmp.begin().key()); + + QJsonObject json; + json["operation"] = enum_operation_del; + json["user"] = tmp.begin().key(); + QJsonDocument document; + document.setObject(json); + emit conf_changed(document.toJson()); + } +} + +void PersonalizedDataMng::__updateUsersInfo() +{ + if (m_usersModel) + { + for(int i = 0; i < m_usersModel->rowCount(QModelIndex()); i++) + { + QString name = m_usersModel->index(i).data(QLightDM::UsersModel::NameRole).toString(); + if(!name.isEmpty()) + { + m_userPersonalizedData[name] = KylinUserDatePtr(new PersonalizedData(name)); + } + + } + } +} + + + diff --git a/uniauth-backend/src/personalizeddata.h b/uniauth-backend/src/personalizeddata.h new file mode 100644 index 0000000..b8fb872 --- /dev/null +++ b/uniauth-backend/src/personalizeddata.h @@ -0,0 +1,140 @@ +#ifndef PERSONALIZEDDATA_H +#define PERSONALIZEDDATA_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ukui-log4qt.h" +#include "CSingleton.h" + + +class PersonalizedData : public QObject +{ + Q_OBJECT +public: + explicit PersonalizedData(QString user); + virtual ~PersonalizedData(); + + ////////////////////ukui-greeter-conf////////////////////////////// + QString dateType(void){ return m_dateType; } + void dateType(QString val){ m_dateType = val; } + + int fontSize(void){ return m_fontSize; } + void fontSize(int val){ m_fontSize = val; } + + int timeType(void){ return m_timeType; } + void timeType(int val){ m_timeType = val; } + + QString backgroundPath(void){ return m_backgroundPath; } + void backgroundPath(QString val){ m_backgroundPath = val; } + + QString color(void){ return m_color; } + void color(QString val){ m_color = val; } + + /////////////////////usd-ukui-settings-daemon//////////////////////////////// + int cursor_size(void){ return m_cursor_size; } + void cursor_size(int val){ m_cursor_size = val; } + + QString cursor_theme(void){ return m_cursor_theme; } + void cursor_theme(QString val){ m_cursor_theme = val; } + + int scaling_factor(void){ return m_scaling_factor; } + void scaling_factor(int val){ m_scaling_factor = val; } + + + void getJsonData(QJsonObject & json); + QString getJsonData(void); + + +protected slots: + void fileChanged(const QString &path); + + virtual void timerEvent( QTimerEvent *event); + +private: + int __load_conf_ukuigreeterconf(void); + int __load_conf_usd_conf(void); + QString __copy_file(QString); +protected: + //ukui-greeter-conf + QString m_dateType = "cn"; + int m_fontSize = 5; + int m_timeType = 24; + QString m_backgroundPath; + QString m_color; + + //usd-ukui-settings-daemon + int m_cursor_size = 48; + QString m_cursor_theme; + int m_scaling_factor = 1; + + //用户名 + QString m_user; + + QFileSystemWatcher * m_file_watch = nullptr; + QString m_greeter_conf_path; + bool m_greeter_conf_path_changed = false; + QString m_usd_conf_path; + bool m_usd_conf_path_changed = false; + int m_conf_TimerID = 0; +}; + + + +typedef QSharedPointer KylinUserDatePtr; + +///////////////////////////////////////////////// +/// \brief The PersonalizedDataMng class +/// + +class PersonalizedDataMng : public QObject +{ + Q_OBJECT +protected: + explicit PersonalizedDataMng(void); + virtual ~PersonalizedDataMng(); + + +public: + QString GetConfInformation(QString); + + void SetLoginSynInformation(QString val); + +signals: + void conf_changed(QString jsonstr); + +protected Q_SLOTS: + void onUserAdded(const QModelIndex&, int, int); + + void onUserRemoved(const QModelIndex&, int, int ); + +protected: + void __updateUsersInfo(); + +protected: + QMap m_userPersonalizedData; + QLightDM::UsersModel * m_usersModel = nullptr; + QString m_lightdm_str; + friend class SingleTon; +}; + +typedef SingleTon KYLINUSERDATAMNG; + +#endif // PERSONALIZEDDATA_H diff --git a/uniauth-backend/src/rsac.cpp b/uniauth-backend/src/rsac.cpp new file mode 100644 index 0000000..0c6877d --- /dev/null +++ b/uniauth-backend/src/rsac.cpp @@ -0,0 +1,199 @@ +#include "rsac.h" +#include +#include + +RSA* publicKeyToRSA(const QByteArray &pubKey) +{ + BIO *pBio = BIO_new_mem_buf(pubKey.data(), pubKey.size()); // 创建内存 + RSA* rsa = PEM_read_bio_RSA_PUBKEY(pBio, nullptr, nullptr, nullptr); + BIO_free_all(pBio); // 释放内存 + return rsa; +} + +RSA* privateKeyToRSA(const QByteArray &priKey) +{ + BIO *pBio = BIO_new_mem_buf(priKey.data(), priKey.size()); // 创建内存 + RSA* rsa = PEM_read_bio_RSAPrivateKey(pBio, nullptr, nullptr, nullptr); + BIO_free_all(pBio); // 释放内存 + return rsa; +} + +/** + * @brief RSAC::generateKeyPair + * 生成密钥对,并分别保存为文件 + * @param priKeyFile 私钥文件名 + * @param pubKeyFile 公钥文件名 + * @param bits 秘钥长度,一般建议1024及以上 + */ +void RSAC::generateKeyPair(const QString &priKeyFile, const QString &pubKeyFile, int bits) +{ + // 生成公钥 + RSA* rsa = RSA_generate_key(bits, RSA_F4, nullptr, nullptr); + BIO *bp = BIO_new(BIO_s_file()); + BIO_write_filename(bp, (void*)pubKeyFile.toStdString().c_str()); + PEM_write_bio_RSAPublicKey(bp, rsa); + BIO_free_all(bp); + + // 生成私钥 + bp = BIO_new(BIO_s_file()); + BIO_write_filename(bp, (void*)priKeyFile.toStdString().c_str()); + PEM_write_bio_RSAPrivateKey(bp, rsa, nullptr, nullptr, 0, nullptr, nullptr); + CRYPTO_cleanup_all_ex_data(); + BIO_free_all(bp); + RSA_free(rsa); +} + +/** + * @brief RSAC::generateKeyPair + * 生成密钥对数据 + * @param privateKey 私钥数据 + * @param publicKey 公钥数据 + * @param bits 秘钥长度,一般建议1024及以上 + */ +void RSAC::generateKeyPair(QByteArray &privateKey, QByteArray &pubKey, int bits) +{ + // 生成密钥对 + RSA *keyPair = RSA_generate_key(bits, RSA_F4, nullptr, nullptr); + + BIO *pri = BIO_new(BIO_s_mem()); + BIO *pub = BIO_new(BIO_s_mem()); + + PEM_write_bio_RSAPrivateKey(pri, keyPair, nullptr, nullptr, 0, nullptr, nullptr); + PEM_write_bio_RSA_PUBKEY(pub, keyPair); + + // 获取长度 + int pri_len = BIO_pending(pri); + int pub_len = BIO_pending(pub); + + privateKey.resize(pri_len); + pubKey.resize(pub_len); + + BIO_read(pri, privateKey.data(), pri_len); + BIO_read(pub, pubKey.data(), pub_len); + + // 内存释放 + RSA_free(keyPair); + BIO_free_all(pub); + BIO_free_all(pri); +} + +/** + * @brief RSAC::encrypt + * RSA加密函数,使用公钥对输入数据,进行加密 + * @param in 输入数据(明文) + * @param out 输出数据(密文) + * @param pubKey 公钥 + * @return 执行结果 + */ +bool RSAC::encrypt(const QByteArray &in, QByteArray &out, const QByteArray& pubKey) +{ + // 公钥数据转RSA + RSA* rsa = publicKeyToRSA(pubKey); + if (rsa == nullptr) + { + return false; + } + + // 对任意长度数据进行加密,超长时,进行分段加密 + int keySize = RSA_size(rsa); + int dataLen = in.size(); + const unsigned char *from = (const unsigned char *)in.data(); + QByteArray to(keySize, 0); + int readLen = 0; + do + { + int select = (keySize - 11) > dataLen ? dataLen : (keySize - 11); + RSA_public_encrypt(select, (from + readLen), (unsigned char *)to.data(), rsa, RSA_PKCS1_PADDING); + dataLen -= select; + readLen += select; + out.append(to); + }while (dataLen > 0); + RSA_free(rsa); + return true; +} + +/** + * @brief RSAC::private_decrypt + * RSA解密函数,使用私钥对输入数据,进行解密 + * @param in 输入数据(密文) + * @param out 输出数据(解密后的内容) + * @param priKey 私钥 + * @return 执行结果 + */ +bool RSAC::decrypt(const QByteArray &in, QByteArray &out, const QByteArray& priKey) +{ + // 私钥数据转RSA + RSA* rsa = privateKeyToRSA(priKey); + if (rsa == nullptr) + { + return false; + } + + // 对任意长度数据进行解密,超长时,进行分段解密 + int keySize = RSA_size(rsa); + int dataLen = in.size(); + const unsigned char *from = (const unsigned char *)in.data(); + QByteArray to(keySize, 0); + int readLen = 0; + do + { + int size = RSA_private_decrypt(keySize, (from + readLen), (unsigned char *)to.data(), rsa, RSA_PKCS1_PADDING); + dataLen -= keySize; + readLen += keySize; + out.append(to.data(), size); + }while (dataLen > 0); + RSA_free(rsa); + return true; +} + +/** + * @brief RSAC::sign + * 使用私钥对摘要数据进行签名 + * @param digest 摘要数据 + * @param sign 签名后的数据 + * @param priKey 私钥 + * @return 执行结果 + */ +bool RSAC::sign(const QByteArray &digest, QByteArray &sign, const QByteArray& priKey) +{ + // 私钥数据转RSA + RSA* rsa = privateKeyToRSA(priKey); + if (rsa == nullptr) + { + return false; + } + + // 对digest进行签名 + unsigned int siglen = 0; + QByteArray temp(RSA_size(rsa), 0); + RSA_sign(NID_sha1, (const unsigned char*)digest.data(), digest.size(), + (unsigned char*)temp.data(), &siglen, rsa); + sign.clear(); + sign.append(temp.data(), siglen); + RSA_free(rsa); + return true; +} + +/** + * @brief RSAC::verify + * 使用公钥对摘要数据进行验签 + * @param digest 摘要数据 + * @param sign 签名后的数据 + * @param pubKey 公钥 + * @return 执行结果 + */ +bool RSAC::verify(const QByteArray &digest, const QByteArray &sign, const QByteArray& pubKey) +{ + // 公钥数据转RSA + RSA* rsa = publicKeyToRSA(pubKey); + if (rsa == nullptr) + { + return false; + } + + // 对digest、sign进行验签 + int ret = RSA_verify(NID_sha1, (const unsigned char*)digest.data(), digest.size(), + (const unsigned char *)sign.data(), sign.size(), rsa); + RSA_free(rsa); + return (ret == 1); +} diff --git a/uniauth-backend/src/rsac.h b/uniauth-backend/src/rsac.h new file mode 100644 index 0000000..93d4678 --- /dev/null +++ b/uniauth-backend/src/rsac.h @@ -0,0 +1,26 @@ +#ifndef RSAC_H +#define RSAC_H + +#include + +/** + * @brief The RSAC class + * RSA算法相关实现,包括密钥对生成,加密与解密,签名与验签。 + */ +class RSAC +{ +public: + // 生成秘钥对 + void generateKeyPair(const QString& priKeyFile, const QString &pubKeyFile, int bits = 1024); + void generateKeyPair(QByteArray& priKey, QByteArray& pubKey, int bits = 1024); + + // 对数据进行加解密 + bool encrypt(const QByteArray& in, QByteArray& out, const QByteArray& pubKey); + bool decrypt(const QByteArray& in, QByteArray& out, const QByteArray& priKey); + + // 对摘要进行签名和验签 + bool sign(const QByteArray& digest, QByteArray& sign, const QByteArray &priKey); + bool verify(const QByteArray& digest, const QByteArray &sign, const QByteArray &pubKey); +}; + +#endif // RSAC_H diff --git a/uniauth-backend/src/serviceinterface.cpp b/uniauth-backend/src/serviceinterface.cpp index b6ae9f0..58670dd 100644 --- a/uniauth-backend/src/serviceinterface.cpp +++ b/uniauth-backend/src/serviceinterface.cpp @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -29,11 +32,25 @@ #include #include #include +#include #include #include "servicemanager.h" +#include "personalizeddata.h" +#include +#include +#include +#define UKUI_GREETER "/usr/sbin/ukui-greeter" +#define UKUI_SCREENSAVER "/usr/bin/ukui-screensaver-dialog" + +#define GREETER_DBUS_PATH "/" +#define GREETER_DBUS_INTERFACE "org.ukui.greeter" +#define SCREENSAVER_DBUS_PATH "/" +#define SCREENSAVER_DBUS_INTERFACE "org.ukui.screensaver" #define COMM_CONFIG_PATH "/etc/biometric-auth/ukui-biometric.conf" #define USER_CONFIG_PATH "/home/%1/.biometric_auth/ukui_biometric.conf" +#define OLD_990_USER_CONFIG_PATH "/home/%1/.biometric-auth/ukui-biometric.conf" +#define PROC_CPUINFO "/proc/cpuinfo" ServiceInterface::ServiceInterface() { @@ -50,9 +67,10 @@ ServiceInterface::ServiceInterface() } registerCustomTypes(); + checkIs990(); m_serviceInterface = new QDBusInterface(DBUS_SERVICE, DBUS_PATH, DBUS_INTERFACE, - QDBusConnection::systemBus()); + QDBusConnection::systemBus(), this); m_serviceInterface->setTimeout(2147483647); connect(m_serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)), @@ -63,6 +81,9 @@ ServiceInterface::ServiceInterface() ServiceManager *sm = ServiceManager::instance(); connect(sm, &ServiceManager::serviceStatusChanged, this, &ServiceInterface::onBiometricDbusChanged); + + rsac.generateKeyPair(priKey, pubKey, 1024); + connect(KYLINUSERDATAMNG::getInstance(), &PersonalizedDataMng::conf_changed, this, &ServiceInterface::updateUserInformation); } void ServiceInterface::setDefaultDevice(QString userName, int bioDevType, QString deviceName) @@ -475,8 +496,22 @@ bool ServiceInterface::getBioAuthStatus(QString userName, int bioAuthType) default: return false; } + + //同步990旧的配置文件,然后删除 + if(getIs990() && (bioAuthType == ENABLETYPE_BIO)){ + QString oldConfigPath = QString(OLD_990_USER_CONFIG_PATH).arg(userName); + QSettings oldSettings(oldConfigPath, QSettings::IniFormat); + if(oldSettings.contains(strBioAuthType)){ + settings.setValue(strBioAuthType,oldSettings.value(strBioAuthType).toBool()); + oldSettings.remove(strBioAuthType); + oldSettings.sync(); + } + } if (settings.contains(strBioAuthType)) { return settings.value(strBioAuthType).toBool(); + }else if(getIs990() && (bioAuthType == ENABLETYPE_BIO)){ + //990默认为打开 + return true; } else { QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat); if (settings2.contains(strBioAuthType)) { @@ -496,6 +531,23 @@ int ServiceInterface::getMaxFailedTimes() return 3; } +int ServiceInterface::getFTimeoutTimes() +{ + QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat); + if(sysSettings.contains("FaceTimeoutTimes")) + return sysSettings.value("FaceTimeoutTimes").toInt(); + else + return 1; +} + +void ServiceInterface::setFTimeoutTimes(int times) +{ + if (times < 1) + times = 1; + QSettings settings(COMM_CONFIG_PATH, QSettings::IniFormat); + settings.setValue("FaceTimeoutTimes", times); +} + bool ServiceInterface::getQRCodeEnable() { bool isEnable = false; @@ -576,6 +628,44 @@ void ServiceInterface::onUSBDeviceHotPlug(int drvid, int action, int deviceNum) } } +//记录当前生物认证信息 +void ServiceInterface::recordAuthDrive(QString appName,int drvid,bool insert) +{ + if(insert){ + m_AuthingDriveList.insert(appName,drvid); + }else{ + m_AuthingDriveList.remove(appName); + } +} + + +//获取当前正在认证的应用 +QStringList ServiceInterface::getAllAuthApp() +{ + return m_AuthingDriveList.keys(); +} + +//根据应用名称获取认证的驱动 +int ServiceInterface::getAppAuthDrive(QString appName) +{ + if(m_AuthingDriveList.contains(appName)){ + return m_AuthingDriveList.value(appName); + } + return -1; +} + +QString ServiceInterface::GetUserInformation(QString username) +{ + KyInfo() << username; + return KYLINUSERDATAMNG::getInstance()->GetConfInformation(username); +} + +void ServiceInterface::SetLoginSynInformation(QString val) +{ + KyInfo() << val; + KYLINUSERDATAMNG::getInstance()->SetLoginSynInformation(val); +} + void ServiceInterface::waitBiometricServiceStatus() { qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` get biometric status"; @@ -628,7 +718,7 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId) QDBusArgument argument; QList qlist; QDBusVariant item; - DeviceInfo *deviceInfo; + DeviceInfoPtr deviceInfo = nullptr; /* 返回值为 i -- int 和 av -- array of variant */ QDBusPendingReply > reply = m_serviceInterface->call("GetDrvList"); @@ -652,7 +742,7 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId) variant = item.variant(); /* 转为普通QVariant对象 */ /* 解封装得到 QDBusArgument 对象 */ argument = variant.value(); - deviceInfo = new DeviceInfo(); + deviceInfo = std::make_shared(); argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */ if (nDriId == deviceInfo->device_id) { if (getCommDefaultDevice(deviceInfo->biotype).isEmpty()) { @@ -662,19 +752,13 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId) } } } else { - for (auto devInfo : m_listDeviceInfos) { - if (devInfo) { - delete devInfo; - devInfo = nullptr; - } - } m_listDeviceInfos.clear(); for (int i = 0; i < deviceCount; i++) { item = qlist[i]; /* 取出一个元素 */ variant = item.variant(); /* 转为普通QVariant对象 */ /* 解封装得到 QDBusArgument 对象 */ argument = variant.value(); - deviceInfo = new DeviceInfo(); + deviceInfo = std::make_shared(); argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */ m_listDeviceInfos.push_back(deviceInfo); } @@ -797,3 +881,230 @@ void ServiceInterface::onBiometricDbusChanged(bool bActive) initData(); } } + +void ServiceInterface::checkIs990() +{ + QRegExp r1("kirin.*9.0"); + r1.setCaseSensitivity(Qt::CaseInsensitive); + QRegExp r2("pangu.*m900"); + r2.setCaseSensitivity(Qt::CaseInsensitive); + + QFile file(PROC_CPUINFO); + if(!file.exists()){ + is990 = false; + } + file.open(QFile::ReadOnly); + QString str(file.readAll()); + is990 = (str.contains(r1) || str.contains(r2)); + file.close(); +} + +bool ServiceInterface::getIs990() +{ + return is990; +} + +QString ServiceInterface::getPublicEncrypt() +{ + return pubKey; +} + +bool ServiceInterface::sendPassword(QString username,QByteArray password) +{ + QByteArray decryptText; + QByteArray encryptText; + rsac.decrypt(password, decryptText, priKey); // 解密 + //如果处于登录状态 + + qDebug()<<"sendPassword"< stateReply = iface.call("getPublicEncrypt"); + + if(!stateReply.isValid()){ + qWarning()<< "Get state error:" << stateReply.error(); + qDebug()<<"getPublicEncrypt failed"; + return ""; + } + return stateReply.value(); +} + +bool ServiceInterface::sendSignalLoginFinished(QString username,bool res) +{ + qDebug()<<"sendSignalLoginFinished "< stateReply = iface.call("sendPassword",username,array); + if(!stateReply.isValid()){ + disconnect(connection); + return false; + } + + if(!stateReply.value()){ + disconnect(connection); + return stateReply.value(); + } + + QTimer::singleShot(30000, &loopTemp, SLOT(quit())); + + loopTemp.exec(); + disconnect(connection); + + return ret; +} +QString ServiceInterface::getProcessNameFromPid(int pid) +{ + QString filename = "/proc/" + QString::number(pid) + "/cmdline"; + qDebug()<<"filename is "<pw_name); + } + return ""; +} + +void ServiceInterface::onDbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner) +{ + if(newOwner.isEmpty()){ + for(QString str:loginAppList.keys()){ + if(name == loginAppList.value(str)){ + qDebug()<<"remove name "<serviceOwner(msg.service()).value(); + qDebug() << "Sender Pid " << conn.interface()->servicePid(msg.service()).value(); + qDebug() << "Sender uid " << conn.interface()->serviceUid(msg.service()).value(); + + int pid = conn.interface()->servicePid(msg.service()).value(); + QString serviceOwner = conn.interface()->serviceOwner(msg.service()).value(); + int uid = conn.interface()->serviceUid(msg.service()).value(); + + QString appName = getProcessNameFromPid(pid); + qDebug()<<"appName = "< #include #include +#include #include +#include +#include "rsac.h" #define DBUS_SERVICE "org.ukui.Biometric" #define DBUS_PATH "/org/ukui/Biometric" @@ -57,6 +60,10 @@ public slots: void setBioAuthStatus(int bioAuthType, bool status); // 获取最大失败次数 int getMaxFailedTimes(); + // 获取人脸识别超时停用次数 + int getFTimeoutTimes(); + // 设置人脸识别超时停用次数 + void setFTimeoutTimes(int times); // 获取是否使能微信扫码登录 bool getQRCodeEnable(); // 获取是否双认证 @@ -69,17 +76,39 @@ public slots: bool getUseFirstDevice(); // 获取是否隐藏切换按钮 bool getHiddenSwitchButton(); - + // 记录当前正在进行生物认证的设备 + void recordAuthDrive(QString appName,int drvid,bool insert); + // 获取当前正在进行生物认证的应用 + QStringList getAllAuthApp(); + // 获取当前应用在认证的驱动 + int getAppAuthDrive(QString appName); + //获取用户配置 + QString GetUserInformation(QString username); + //同步登录界面配置 + void SetLoginSynInformation(QString val); + // 获取公钥 + QString getPublicEncrypt(); + //发送用户名和密码 + bool sendPassword(QString username,QByteArray password); + //前端注册到后端接口 + bool registerLoginApp(); + //发送认证结果 + bool sendSignalLoginFinished(QString username,bool res); private slots: void onUSBDeviceHotPlug(int drvid, int action, int deviceNum); void onBiometricDbusChanged(bool bActive); - + void onDbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner); signals: //默认设备改变 void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName); //开关状态改变 void bioAuthStatusChanged(QString userName, int type, bool status); - + //用户配置改变 + void updateUserInformation(QString jsonstring); + //单点登录完成信号 + void onSignalLoginFinished(QString username,bool res); + //登录服务以启动信号 + void onLoginServicdRegisted(); private: //设置默认设备 void setDefaultDevice(QString userName, int bioDevType, QString deviceName); @@ -95,11 +124,34 @@ private: void updateCommDefaultDevice(int nDriId); // 等待生物识别服务 void waitBiometricServiceStatus(); - + //判断系统是否为990 + void checkIs990(); + //获取系统是否为990 + bool getIs990(); + //根据pid获取进程名称 + QString getProcessNameFromPid(int pid); + //根据uid获取用户名 + QString getUserNameFromUid(int uid); + //获取登录锁屏界面的公钥 + QString getLoginPubKey(QString service,QString path,QString interface); + //发送密码到登录锁屏界面 + bool sendLoginPassword(QString service,QString path,QString interface,QString username,QByteArray array); + //处理首次登录逻辑 + bool handleFirstSingleLogn(QString username,QByteArray decryptText); private: QDBusInterface *m_serviceInterface = nullptr; - QList m_listDeviceInfos; + DeviceList m_listDeviceInfos; int deviceCount = 0; + bool is990 = false; + QMap m_AuthingDriveList; + + QMap loginAppList; + RSAC rsac; + QByteArray priKey, pubKey; + bool isFirstLogin = true; + bool hasSaveLogin = false; + QString savedUsername; + QByteArray savedPassword; }; #endif // SERVICEINTERFACE_H diff --git a/uniauth-backend/src/servicemanager.cpp b/uniauth-backend/src/servicemanager.cpp index 7219d32..a9b61c3 100644 --- a/uniauth-backend/src/servicemanager.cpp +++ b/uniauth-backend/src/servicemanager.cpp @@ -83,6 +83,8 @@ void ServiceManager::onDBusNameOwnerChanged(const QString &name, << (newOwner.isEmpty() ? "inactivate" : "activate"); Q_EMIT serviceStatusChanged(!newOwner.isEmpty()); } + + Q_EMIT dbusNameOwnerChanged(name,oldOwner,newOwner); } /*! diff --git a/uniauth-backend/src/servicemanager.h b/uniauth-backend/src/servicemanager.h index 0128b38..6c85df3 100644 --- a/uniauth-backend/src/servicemanager.h +++ b/uniauth-backend/src/servicemanager.h @@ -36,6 +36,7 @@ private: Q_SIGNALS: void serviceStatusChanged(bool activate); + void dbusNameOwnerChanged(QString name,QString oldOwner,QString newOwner); public Q_SLOTS: void onDBusNameOwnerChanged(const QString &name,