feat(global config & single login): global config & single login

Description: 全局配置与单点登录

Log: 无
This commit is contained in:
yangmin 2023-11-15 10:24:48 +08:00
parent 2b8038b74d
commit 953fb420e5
39 changed files with 2667 additions and 112 deletions

View File

@ -35,6 +35,7 @@ void KeyWatcher::run()
current.c_cc[VMIN] = 1;
current.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &current);
bool isInputEnd = false;
while(!isInterruptionRequested()){
@ -52,12 +53,19 @@ 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和之后的程序运行
}

View File

@ -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,6 +319,7 @@ 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;
@ -328,7 +350,7 @@ 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:

184
bioauth/i18n_ts/mn.ts Normal file
View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="mn">
<context>
<name>BioAuthWidget</name>
<message>
<location filename="../src/bioauthwidget.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>More</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/bioauthwidget.ui" line="146"/>
<location filename="../src/bioauthwidget.cpp" line="41"/>
<source>Retry</source>
<translation> </translation>
</message>
<message>
<source>Too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">使</translation>
</message>
<message>
<source>Bioauth authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">%1</translation>
</message>
<message>
<source>Password</source>
<translation> </translation>
</message>
<message>
<source>Current Device: </source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="96"/>
<location filename="../src/bioauthwidget.cpp" line="212"/>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="102"/>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation>%1 %2 </translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="226"/>
<source>Please use wechat to scan the code</source>
<translation> </translation>
</message>
</context>
<context>
<name>BioDevices</name>
<message>
<location filename="../src/biodevices.cpp" line="78"/>
<source>Unplugging of %1 device detected</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="88"/>
<source>%1 device insertion detected</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="97"/>
<source>ukui-biometric-manager</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="100"/>
<source>biometric</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="647"/>
<source>FingerPrint</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="649"/>
<source>FingerVein</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="651"/>
<source>Iris</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="653"/>
<source>Face</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="655"/>
<source>VoicePrint</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="657"/>
<source>ukey</source>
<translation> </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="659"/>
<source>QRCode</source>
<translation> </translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>BioDevicesWidget</name>
<message>
<location filename="../src/biodeviceswidget.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>Device types:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Back</source>
<translation type="vanished"></translation>
</message>
<message>
<source>OK</source>
<translation type="vanished"></translation>
</message>
<message>
<source>FingerPrint</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>LoginOptionsWidget</name>
<message>
<location filename="../src/loginoptionswidget.cpp" line="61"/>
<source>Login Options</source>
<translation> </translation>
</message>
<message>
<location filename="../src/loginoptionswidget.cpp" line="294"/>
<source>Password</source>
<translation> </translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Biometric</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>FingerPrint</source>
<translation type="vanished"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Iris</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Face</source>
<translation type="vanished"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="vanished"></translation>
</message>
</context>
</TS>

View File

@ -100,8 +100,8 @@
</message>
<message>
<location filename="../src/biodevices.cpp" line="657"/>
<source>ukey</source>
<translation type="unfinished"></translation>
<source>Ukey</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="659"/>

184
bioauth/i18n_ts/zh_HK.ts Normal file
View File

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_Hant">
<context>
<name>BioAuthWidget</name>
<message>
<location filename="../src/bioauthwidget.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>More</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/bioauthwidget.ui" line="146"/>
<location filename="../src/bioauthwidget.cpp" line="41"/>
<source>Retry</source>
<translation></translation>
</message>
<message>
<source>Too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">使</translation>
</message>
<message>
<source>Bioauth authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">%1</translation>
</message>
<message>
<source>Password</source>
<translation></translation>
</message>
<message>
<source>Current Device: </source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="96"/>
<location filename="../src/bioauthwidget.cpp" line="212"/>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation>%1</translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="102"/>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation>%1 %2 </translation>
</message>
<message>
<location filename="../src/bioauthwidget.cpp" line="226"/>
<source>Please use wechat to scan the code</source>
<translation>使</translation>
</message>
</context>
<context>
<name>BioDevices</name>
<message>
<location filename="../src/biodevices.cpp" line="78"/>
<source>Unplugging of %1 device detected</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="88"/>
<source>%1 device insertion detected</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="97"/>
<source>ukui-biometric-manager</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="100"/>
<source>biometric</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="647"/>
<source>FingerPrint</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="649"/>
<source>FingerVein</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="651"/>
<source>Iris</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="653"/>
<source>Face</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="655"/>
<source>VoicePrint</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="657"/>
<source>ukey</source>
<translation></translation>
</message>
<message>
<location filename="../src/biodevices.cpp" line="659"/>
<source>QRCode</source>
<translation></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>BioDevicesWidget</name>
<message>
<location filename="../src/biodeviceswidget.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>Device types:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Back</source>
<translation type="vanished"></translation>
</message>
<message>
<source>OK</source>
<translation type="vanished"></translation>
</message>
<message>
<source>FingerPrint</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>LoginOptionsWidget</name>
<message>
<location filename="../src/loginoptionswidget.cpp" line="61"/>
<source>Login Options</source>
<translation></translation>
</message>
<message>
<location filename="../src/loginoptionswidget.cpp" line="294"/>
<source>Password</source>
<translation></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Biometric</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>FingerPrint</source>
<translation type="vanished"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Iris</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Face</source>
<translation type="vanished"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="vanished"></translation>
</message>
</context>
</TS>

View File

@ -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);

View File

@ -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();

View File

@ -225,6 +225,9 @@ Q_DECLARE_METATYPE(DeviceInfo)
typedef std::shared_ptr<DeviceInfo> DeviceInfoPtr;
typedef QList<DeviceInfoPtr> DeviceList;
typedef QMap<int, DeviceList> DeviceMap;
typedef std::shared_ptr<FeatureInfo> FeatureInfoPtr;
typedef QList<FeatureInfoPtr> FeatureList;
typedef QMap<QString, FeatureList> FeatureMap;
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo);
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo);

View File

@ -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);

View File

@ -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:
//默认设备改变

View File

@ -17,6 +17,7 @@
**/
#include "bioauth.h"
#include <QList>
#include <unistd.h>
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<int> 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<qint32, qint32> 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);

View File

@ -94,7 +94,7 @@ void BioDevices::onUSBDeviceHotPlug(int deviceId, int action, int devNumNow)
"org.freedesktop.Notifications",
QDBusConnection::sessionBus());
QList<QVariant> args;
args<<(tr("ukui-biometric-manager"))
args<<(tr("Biometric Manager"))
<<((unsigned int) 0)
<<"biometric-manager"
<<tr("biometric")
@ -200,10 +200,32 @@ int BioDevices::GetUserDevCount(int uid)
}
FeatureMap BioDevices::GetUserFeatures(int uid)
{
FeatureMap featureMap;
QList<QDBusVariant> 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<QVariant> variantList = result.arguments();
listsize = variantList[0].value<int>();
variantList[1].value<QDBusArgument>() >> qlist;
for (int i = 0; i < listsize; i++) {
FeatureInfoPtr pFeatureInfo = std::make_shared<FeatureInfo>();
qlist[i].variant().value<QDBusArgument>() >> *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<int> 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<int, QList<DeviceInfo>> 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");
}

View File

@ -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:"<<mapFeatures.size();
for(auto pDeviceInfo : deviceList)
{
int nDevFeatureCount = 0;
@ -407,8 +414,8 @@ void LoginOptionsWidget::readDevicesInfo()
} else {
if (m_uid == -1) {
nDevFeatureCount = 0;
} else {
nDevFeatureCount = m_bioDevices->GetUserDevFeatureCount(m_uid, pDeviceInfo->device_id);
} else if(mapFeatures.contains(pDeviceInfo->device_shortname)){
nDevFeatureCount = mapFeatures[pDeviceInfo->device_shortname].size();
}
}
qDebug() << *pDeviceInfo << ",FeatureCount:"<<nDevFeatureCount;
@ -496,6 +503,7 @@ void LoginOptionsWidget::startAuth_()
m_labelFaceLoad->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)

View File

@ -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<QVariant> 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<QVariant> 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;

5
debian/control vendored
View File

@ -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

View File

@ -1 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><clipPath id="clip-path"><circle cx="8" cy="8" r="8" fill="none"/></clipPath></defs><g clip-path="url(#clip-path)"><path d="M8.2,4.33H8A2.3,2.3,0,0,0,5.73,5.91a3.59,3.59,0,0,0-.09,1.5,14.1,14.1,0,0,1-1.3,8.89.45.45,0,0,0,.18.61.54.54,0,0,0,.21.05.46.46,0,0,0,.4-.24,15,15,0,0,0,1.4-9.43,2.83,2.83,0,0,1,.06-1.11c.13-.4.41-.87,1.49-.95H8.2a1.26,1.26,0,0,1,1.24.85A11.83,11.83,0,0,1,10,8.35,8.18,8.18,0,0,1,10,9.58v.57a.85.85,0,0,1,0,.16.44.44,0,0,0,.38.5h.06a.45.45,0,0,0,.45-.39,1.51,1.51,0,0,0,0-.3V9.58a10.42,10.42,0,0,0-.07-1.36,13.39,13.39,0,0,0-.56-2.43A2.16,2.16,0,0,0,8.2,4.33Z" fill="#1a1a1a"/><path d="M8.05,1a6.57,6.57,0,0,0-1.23.12,5.81,5.81,0,0,0-4.6,6.76c.08.52.14,1,.21,1.57l.09.74a.44.44,0,0,0,.45.39H3a.44.44,0,0,0,.38-.5l-.09-.74c-.06-.53-.13-1.06-.21-1.6A4.91,4.91,0,0,1,7,2,5.33,5.33,0,0,1,8,1.9a5.33,5.33,0,0,1,3.8,1.69.43.43,0,0,0,.31.13.42.42,0,0,0,.32-.13.45.45,0,0,0,0-.64A6.15,6.15,0,0,0,8.05,1Z" fill="#1a1a1a"/><path d="M5.54,4.88h0M5.3,3.93a.49.49,0,0,0-.2,0,1.64,1.64,0,0,0-.58.56,4.38,4.38,0,0,0-.6,3.38,13.61,13.61,0,0,1-.11,5,9.55,9.55,0,0,1-1,2.68A.45.45,0,0,0,3,16.2a.42.42,0,0,0,.22.05A.45.45,0,0,0,3.64,16,10.4,10.4,0,0,0,4.69,13.1a14.69,14.69,0,0,0,.12-5.31,3.4,3.4,0,0,1,.44-2.72,1,1,0,0,1,.25-.28.46.46,0,0,0,.2-.61.45.45,0,0,0-.4-.25Z" fill="#1a1a1a"/><path d="M8.15,2.72a5.46,5.46,0,0,0-1.51.22.45.45,0,0,0-.31.56.43.43,0,0,0,.43.32h.12a4.42,4.42,0,0,1,1.25-.19,3.07,3.07,0,0,1,3,2.23,13.82,13.82,0,0,1,.57,4.41,19.75,19.75,0,0,1-.91,5.93,3.74,3.74,0,0,1-.18.48.44.44,0,0,0,.21.6.43.43,0,0,0,.19,0,.45.45,0,0,0,.41-.25c.09-.19.16-.39.23-.58a20.8,20.8,0,0,0,.95-6.22A14.66,14.66,0,0,0,12,5.56,3.93,3.93,0,0,0,8.15,2.72Z" fill="#1a1a1a"/><path d="M3,13.15H3m-.5-.69a.45.45,0,0,0-.4.25,2.37,2.37,0,0,0-.18.53,3,3,0,0,1-.1.32c-.07.16-.15.32-.23.49a6.25,6.25,0,0,0-.31.69.45.45,0,0,0,.26.58.44.44,0,0,0,.16,0,.45.45,0,0,0,.42-.29,4.57,4.57,0,0,1,.28-.6c.09-.18.18-.36.25-.54a2.44,2.44,0,0,0,.14-.44,1.89,1.89,0,0,1,.12-.36.46.46,0,0,0-.21-.61.45.45,0,0,0-.2,0Z" fill="#1a1a1a"/><path d="M13.25,4.89h-.1a.46.46,0,0,0-.34.54,22.64,22.64,0,0,1,.58,5.38,18,18,0,0,1-.66,4.74l0,.14v0a.45.45,0,0,0,.05.57.46.46,0,0,0,.33.13.47.47,0,0,0,.31-.12.81.81,0,0,0,.21-.46.15.15,0,0,1,0-.07,18.82,18.82,0,0,0,.69-5,23.9,23.9,0,0,0-.6-5.59.45.45,0,0,0-.44-.34Z" fill="#1a1a1a"/><path d="M10.35,11.43a.44.44,0,0,0-.45.39,17.13,17.13,0,0,1-1.28,5.06.45.45,0,0,0,.22.6.43.43,0,0,0,.19,0,.45.45,0,0,0,.41-.26,18.25,18.25,0,0,0,1.35-5.33.45.45,0,0,0-.39-.5Z" fill="#1a1a1a"/><path d="M8,15.61H8m-.49-.69a.46.46,0,0,0-.41.26l-.64,1.37a.45.45,0,0,0,.21.6.46.46,0,0,0,.19,0,.44.44,0,0,0,.41-.26l.64-1.37A.44.44,0,0,0,7.71,15a.49.49,0,0,0-.19-.05Z" fill="#1a1a1a"/><path d="M8.06,6.56H8a.46.46,0,0,0-.37.52,17.57,17.57,0,0,1-.07,6.52.45.45,0,0,0,.35.53H8a.44.44,0,0,0,.44-.35A18.12,18.12,0,0,0,8.5,6.93a.43.43,0,0,0-.44-.37Z" fill="#1a1a1a"/></g></svg>
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#262626;}</style></defs><path class="cls-1" d="M2.79,13.45a2.53,2.53,0,0,1,.12-.36.46.46,0,0,0-.21-.61H2.5v0a.46.46,0,0,0-.4.25,2.19,2.19,0,0,0-.17.49,6.9,6.9,0,0,0,.71.72v0A2.25,2.25,0,0,0,2.79,13.45Z"/><path class="cls-1" d="M10.4,11.39l-.05,0a.44.44,0,0,0-.45.39A16.89,16.89,0,0,1,9,15.93a6.54,6.54,0,0,0,1-.19,18.07,18.07,0,0,0,.81-3.85A.44.44,0,0,0,10.4,11.39Z"/><path class="cls-1" d="M7.71,15A.41.41,0,0,0,7.52,15v0a.46.46,0,0,0-.41.26l-.33.72c.3,0,.61.07.92.08l.22-.46A.43.43,0,0,0,7.71,15Z"/><path class="cls-1" d="M6.53,7.29a3,3,0,0,1,.06-1.11c.13-.4.41-.87,1.49-.95H8.2a1.25,1.25,0,0,1,1.24.85A12,12,0,0,1,10,8.35a8.42,8.42,0,0,1,0,1.23v.57a.43.43,0,0,1,0,.16.44.44,0,0,0,.37.5h.07a.45.45,0,0,0,.45-.39,1.5,1.5,0,0,0,0-.3V9.58a10.33,10.33,0,0,0-.07-1.36,13.39,13.39,0,0,0-.56-2.43A2.15,2.15,0,0,0,8.2,4.33H8A2.31,2.31,0,0,0,5.73,5.91a3.46,3.46,0,0,0-.09,1.5,14.16,14.16,0,0,1-.85,7.91,8.36,8.36,0,0,0,.83.32A15,15,0,0,0,6.53,7.29Z"/><path class="cls-1" d="M12.43,3A6.14,6.14,0,0,0,8.05,1a6.41,6.41,0,0,0-1.23.12,5.81,5.81,0,0,0-4.6,6.76c.08.52.14,1,.21,1.57l.09.74a.44.44,0,0,0,.45.39H3a.44.44,0,0,0,.38-.49h0l-.09-.74c-.06-.53-.13-1.06-.21-1.6A4.92,4.92,0,0,1,7,2H7a5.56,5.56,0,0,1,1-.1,5.38,5.38,0,0,1,3.8,1.69.44.44,0,0,0,.31.13.42.42,0,0,0,.32-.13.45.45,0,0,0,0-.64Z"/><path class="cls-1" d="M4.81,7.79a3.43,3.43,0,0,1,.44-2.72,1,1,0,0,1,.25-.28.46.46,0,0,0,.2-.61.46.46,0,0,0-.4-.25.67.67,0,0,0-.2,0,1.64,1.64,0,0,0-.58.56,4.38,4.38,0,0,0-.6,3.38,13.56,13.56,0,0,1-.11,5,9.89,9.89,0,0,1-.5,1.6A7.11,7.11,0,0,0,4.1,15a10.26,10.26,0,0,0,.59-1.88A14.81,14.81,0,0,0,4.81,7.79Z"/><path class="cls-1" d="M12,5.56A3.93,3.93,0,0,0,8.15,2.72a5.51,5.51,0,0,0-1.51.22.45.45,0,0,0-.31.55h0a.43.43,0,0,0,.43.32h.12a4.46,4.46,0,0,1,1.25-.19,3.07,3.07,0,0,1,3,2.23,13.72,13.72,0,0,1,.57,4.41A19.83,19.83,0,0,1,11,15.41a8.06,8.06,0,0,0,1.06-.53,20.79,20.79,0,0,0,.53-4.65A14.73,14.73,0,0,0,12,5.56Z"/><path class="cls-1" d="M13.72,5.15a.45.45,0,0,0-.44-.34l0,.08h-.1a.46.46,0,0,0-.34.54,22.63,22.63,0,0,1,.58,5.38,18.5,18.5,0,0,1-.35,3.4,7.35,7.35,0,0,0,1.12-1.11,18.59,18.59,0,0,0,.16-2.36A23.88,23.88,0,0,0,13.72,5.15Z"/><path class="cls-1" d="M8.06,6.56H8a.46.46,0,0,0-.37.52,17.65,17.65,0,0,1-.07,6.52.45.45,0,0,0,.35.53H8a.44.44,0,0,0,.44-.35A17.94,17.94,0,0,0,8.5,6.93.43.43,0,0,0,8.06,6.56Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -8,9 +8,11 @@
<description>Run the biometric authentication control tool</description>
<description xml:lang="zh">运行生物识别认证控制工具</description>
<description xml:lang="bo">འཁོར་སྐྱོད་སྐྱེ་དངོས་ཀྱི་ངོས་འཛིན་ཁས་ལེན་ཚོད་འཛིན་ཡོ་བྱད།།</description>
<description xml:lang="mn">ᠠᠵᠢᠯᠯᠠᠭᠠᠨ ᠤ ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠵᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ </description>
<message>Authentication is required to enable or disable biometric authentication</message>
<message xml:lang="zh">开启或关闭生物识别认证需要进行身份验证</message>
<message xml:lang="bo">སྒོ་རྒྱག་པའམ་ཡང་ན་སྒོ་རྒྱག་པའི་སྐྱེ་དངོས་ངོས་འཛིན་བདེན་དཔངར་སྤྲོད་བྱེད་པར་ཐོབ་ཐང་གི་ཚོད་ལྟསར་སྤྲོད་བྱ་དགོས།</message>
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠭᠡᠷᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠨᠡᠭᠡᠭᠡᠬᠦ ᠪᠤᠶᠤ ᠬᠠᠭᠠᠬᠤ ᠳᠤ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨ᠎ᠠ᠃</message>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>no</allow_any>

View File

@ -8,9 +8,11 @@
<description>Run the biometric device driver control tool</description>
<description xml:lang="zh">运行生物识别设备驱动控制工具</description>
<description xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་ཚོད་འཛིན་ཡོ་བྱད་</description>
<description xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠪᠡᠷ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠡᠵᠡᠮᠳᠡᠯ ᠦᠨ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠤᠨ᠎ᠠ </description>
<message>Authentication is required to change the status of biometric device's driver</message>
<message xml:lang="zh">改变生物识别设备驱动状态需要进行身份验证</message>
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་གནས་ཚུལ་ལ་འགྱུར་ལྡོག་གཏོང་བར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠢ ᠢᠯᠭᠠᠨ ᠲᠠᠨᠢᠬᠤ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢᠨ ᠬᠥᠳᠡᠯᠭᠡᠭᠦᠷ ᠪᠣᠯᠭᠠᠬᠤ ᠪᠠᠶᠢᠳᠠᠯ ᠢ ᠬᠤᠪᠢᠷᠠᠭᠤᠯᠬᠤ ᠳᠤ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠤᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠯ ᠬᠢᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠶ᠃</message>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>

View File

@ -8,9 +8,11 @@
<description>Restart Service</description>
<description xml:lang="zh">重启生物特征服务</description>
<description xml:lang="bo">བསྐྱར་དུ་ཞབས་འདེགས་ཞུ་བ</description>
<description xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠤᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠡᠭᠢᠯᠡᠭᠦᠯᠪᠡ᠃</description>
<message>Authentication is required to restart biometric service</message>
<message xml:lang="zh">重启生物特征服务需要身份验证</message>
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
<message xml:lang="mn">ᠠᠮᠢᠳᠤ ᠪᠣᠳᠠᠰ ᠤᠨ ᠣᠨᠴᠠᠯᠢᠭ ᠰᠢᠨᠵᠢ ᠲᠡᠮᠳᠡᠭ ᠦᠨ ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ ᠶᠢ ᠳᠠᠬᠢᠨ ᠰᠡᠩᠬᠡᠷᠡᠭᠦᠯᠬᠦ ᠳᠦ ᠪᠡᠶ᠎ᠡ ᠶᠢᠨ ᠭᠠᠷᠤᠯ ᠢ ᠰᠢᠯᠭᠠᠨ ᠭᠡᠷᠡᠴᠢᠯᠡᠬᠦ ᠴᠢᠬᠤᠯᠠ ᠲᠠᠶ ᠪᠠᠶᠢᠨ᠎ᠠ </message>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>

View File

@ -8,6 +8,7 @@ isShownInControlCenter=false
UseFirstDevice=true
MaxFailedTimes=5
HiddenSwitchButton=false
FaceTimeoutTimes=1
[Functions]
EnableQRCode=true

View File

@ -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

441
polkit-agent/i18n_ts/mn.ts Normal file
View File

@ -0,0 +1,441 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="mn">
<context>
<name>BioAuthWidget</name>
<message>
<source>Retry</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation type="obsolete">%1使</translation>
</message>
<message>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation type="obsolete">%1%2</translation>
</message>
<message>
<source>Please use wechat to scan the code</source>
<translation type="vanished">使</translation>
</message>
</context>
<context>
<name>BioDevices</name>
<message>
<source>FingerPrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Iris</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Face</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
<message>
<source>QRCode</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>LoginOptionsWidget</name>
<message>
<source>Login Options</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="../src/mainwindow.cpp" line="65"/>
<source>Authentication</source>
<translation> </translation>
</message>
<message>
<source>Fingerprint authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">%1</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="26"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>More</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Restart</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Password</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="409"/>
<location filename="../src/mainwindow.cpp" line="1075"/>
<location filename="../src/mainwindow.cpp" line="1146"/>
<source>Biometric</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="480"/>
<source>use password</source>
<translation> </translation>
</message>
<message>
<source>DeviceType:</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Back</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Details</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Action Id:</source>
<translation type="obsolete">:</translation>
</message>
<message>
<source>Description:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Polkit.subject-pid:</source>
<translation type="vanished">Polkit.subject-pid</translation>
</message>
<message>
<source>Retry</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Device types:</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Vendor:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Action:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Polkit.caller-pid:</source>
<translation type="vanished">Polkit.caller-pid</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="441"/>
<location filename="../src/mainwindow.cpp" line="1077"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="460"/>
<location filename="../src/mainwindow.cpp" line="1073"/>
<source>Authenticate</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1079"/>
<location filename="../src/mainwindow.cpp" line="1189"/>
<source>Use password</source>
<translation> </translation>
</message>
<message>
<source>Auth</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">使</translation>
</message>
<message>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation type="vanished">%1%2</translation>
</message>
<message>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">%1使</translation>
</message>
<message>
<source>in authentication, please wait...</source>
<translation type="vanished">...</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1225"/>
<location filename="../src/mainwindow.cpp" line="1298"/>
<location filename="../src/mainwindow.cpp" line="1299"/>
<source>Please try again in %1 minutes.</source>
<translation>%1 .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1236"/>
<location filename="../src/mainwindow.cpp" line="1308"/>
<location filename="../src/mainwindow.cpp" line="1309"/>
<source>Please try again in %1 seconds.</source>
<translation>%1 .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1246"/>
<location filename="../src/mainwindow.cpp" line="1247"/>
<location filename="../src/mainwindow.cpp" line="1317"/>
<location filename="../src/mainwindow.cpp" line="1318"/>
<source>Account locked permanently.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="834"/>
<location filename="../src/mainwindow.cpp" line="835"/>
<source>Password cannot be empty</source>
<translation> </translation>
</message>
<message>
<source>Failed to verify %1, please enter password.</source>
<translation type="vanished">%1.</translation>
</message>
<message>
<source>Unable to verify %1, please enter password.</source>
<translation type="vanished">%1.</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="242"/>
<location filename="../src/mainwindow.cpp" line="246"/>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation>%1/ %2 </translation>
</message>
<message>
<source>An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="731"/>
<source>Password: </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="335"/>
<source>Please enter your password or enroll your fingerprint </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="259"/>
<source>Abnormal network</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="665"/>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="733"/>
<source>_Password: </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="735"/>
<source>_Password:</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="850"/>
<source>Authentication failed, please try again.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="779"/>
<source>days left</source>
<translation> </translation>
</message>
<message>
<source>Biometric/code scan authentication failed too many times, please enter the password.</source>
<translation type="vanished">/使.</translation>
</message>
<message>
<source>Bioauth/code scan authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">/%1</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="226"/>
<location filename="../src/mainwindow.cpp" line="1421"/>
<location filename="../src/mainwindow.cpp" line="1423"/>
<source>Failed to verify %1, please enter password to unlock</source>
<translation>%1/ </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="231"/>
<location filename="../src/mainwindow.cpp" line="233"/>
<location filename="../src/mainwindow.cpp" line="1425"/>
<source>Unable to verify %1, please enter password to unlock</source>
<translation>%1/ </translation>
</message>
<message>
<source>NET Exception</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="671"/>
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="108"/>
<location filename="../src/mainwindow.cpp" line="729"/>
<source>Input Password</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="105"/>
<source>Insert the ukey into the USB port</source>
<translation> USB </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="107"/>
<source>Enter the ukey password</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="783"/>
<source>hours left</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="787"/>
<source>minutes left</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="791"/>
<source>seconds left</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="880"/>
<location filename="../src/mainwindow.cpp" line="888"/>
<source>Input your password to authentication</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1440"/>
<source>Verify face recognition or enter password to unlock</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1445"/>
<source>Press fingerprint or enter password to unlock</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1450"/>
<source>Verify voiceprint or enter password to unlock</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1455"/>
<source>Verify finger vein or enter password to unlock</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1460"/>
<source>Verify iris or enter password to unlock</source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1465"/>
<source>Use the bound wechat scanning code or enter the password to unlock</source>
<translation> </translation>
</message>
<message>
<source>Use the bound wechat scanning code or enter the password to log in</source>
<translation type="vanished">使</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="779"/>
<location filename="../src/mainwindow.cpp" line="783"/>
<location filename="../src/mainwindow.cpp" line="787"/>
<location filename="../src/mainwindow.cpp" line="791"/>
<source>Account locked,</source>
<translation> </translation>
</message>
<message>
<source>Authentication failed, please try again</source>
<translation type="obsolete"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>
<message>
<location filename="../src/PolkitListener.cpp" line="88"/>
<source>Another client is already authenticating, please try again later.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="261"/>
<source>Authentication failure, please try again.</source>
<translation> .</translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="268"/>
<source>Password input error!</source>
<translation> !</translation>
</message>
<message>
<source>Account locked %1 minutes due to %2 fail attempts</source>
<translation type="vanished">%1%2</translation>
</message>
<message>
<source>Authentication failure,there are still %1 remaining opportunities</source>
<translation type="vanished">%1</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>FingerPrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Iris</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Face</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="obsolete"></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,441 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_Hant">
<context>
<name>BioAuthWidget</name>
<message>
<source>Retry</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation type="obsolete">%1使</translation>
</message>
<message>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation type="obsolete">%1%2</translation>
</message>
<message>
<source>Please use wechat to scan the code</source>
<translation type="vanished">使</translation>
</message>
</context>
<context>
<name>BioDevices</name>
<message>
<source>FingerPrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Iris</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Face</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
<message>
<source>QRCode</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>LoginOptionsWidget</name>
<message>
<source>Login Options</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Wechat</source>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="../src/mainwindow.cpp" line="67"/>
<source>Authentication</source>
<translation></translation>
</message>
<message>
<source>Fingerprint authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">%1</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="26"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>More</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Restart</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Password</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="409"/>
<location filename="../src/mainwindow.cpp" line="1077"/>
<location filename="../src/mainwindow.cpp" line="1145"/>
<source>Biometric</source>
<translation>使</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="480"/>
<source>use password</source>
<translation>使</translation>
</message>
<message>
<source>DeviceType:</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Back</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Details</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Action Id:</source>
<translation type="obsolete">:</translation>
</message>
<message>
<source>Description:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Polkit.subject-pid:</source>
<translation type="vanished">Polkit.subject-pid</translation>
</message>
<message>
<source>Retry</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Device types:</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Vendor:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Action:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Polkit.caller-pid:</source>
<translation type="vanished">Polkit.caller-pid</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="441"/>
<location filename="../src/mainwindow.cpp" line="1079"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="460"/>
<location filename="../src/mainwindow.cpp" line="1075"/>
<source>Authenticate</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1081"/>
<location filename="../src/mainwindow.cpp" line="1185"/>
<source>Use password</source>
<translation>使</translation>
</message>
<message>
<source>Auth</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">使</translation>
</message>
<message>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation type="vanished">%1%2</translation>
</message>
<message>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation type="vanished">%1使</translation>
</message>
<message>
<source>in authentication, please wait...</source>
<translation type="vanished">...</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1221"/>
<location filename="../src/mainwindow.cpp" line="1294"/>
<location filename="../src/mainwindow.cpp" line="1295"/>
<source>Please try again in %1 minutes.</source>
<translation>%1</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1232"/>
<location filename="../src/mainwindow.cpp" line="1304"/>
<location filename="../src/mainwindow.cpp" line="1305"/>
<source>Please try again in %1 seconds.</source>
<translation>%1</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1242"/>
<location filename="../src/mainwindow.cpp" line="1243"/>
<location filename="../src/mainwindow.cpp" line="1313"/>
<location filename="../src/mainwindow.cpp" line="1314"/>
<source>Account locked permanently.</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="836"/>
<location filename="../src/mainwindow.cpp" line="837"/>
<source>Password cannot be empty</source>
<translation></translation>
</message>
<message>
<source>Failed to verify %1, please enter password.</source>
<translation type="vanished">%1.</translation>
</message>
<message>
<source>Unable to verify %1, please enter password.</source>
<translation type="vanished">%1.</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="244"/>
<location filename="../src/mainwindow.cpp" line="248"/>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation>%1%2</translation>
</message>
<message>
<source>An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="733"/>
<source>Password: </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="337"/>
<source>Please enter your password or enroll your fingerprint </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="261"/>
<source>Abnormal network</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="667"/>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="735"/>
<source>_Password: </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="737"/>
<source>_Password:</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="852"/>
<source>Authentication failed, please try again.</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="781"/>
<source>days left</source>
<translation></translation>
</message>
<message>
<source>Biometric/code scan authentication failed too many times, please enter the password.</source>
<translation type="vanished">/使.</translation>
</message>
<message>
<source>Bioauth/code scan authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished">/%1</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="228"/>
<location filename="../src/mainwindow.cpp" line="1417"/>
<location filename="../src/mainwindow.cpp" line="1419"/>
<source>Failed to verify %1, please enter password to unlock</source>
<translation>%1</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="233"/>
<location filename="../src/mainwindow.cpp" line="235"/>
<location filename="../src/mainwindow.cpp" line="1421"/>
<source>Unable to verify %1, please enter password to unlock</source>
<translation>%1</translation>
</message>
<message>
<source>NET Exception</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="673"/>
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="110"/>
<location filename="../src/mainwindow.cpp" line="731"/>
<source>Input Password</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="107"/>
<source>Insert the ukey into the USB port</source>
<translation>USB埠</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="109"/>
<source>Enter the ukey password</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="785"/>
<source>hours left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="789"/>
<source>minutes left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="793"/>
<source>seconds left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="882"/>
<location filename="../src/mainwindow.cpp" line="890"/>
<source>Input your password to authentication</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1436"/>
<source>Verify face recognition or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1441"/>
<source>Press fingerprint or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1446"/>
<source>Verify voiceprint or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1451"/>
<source>Verify finger vein or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1456"/>
<source>Verify iris or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1461"/>
<source>Use the bound wechat scanning code or enter the password to unlock</source>
<translation>使</translation>
</message>
<message>
<source>Use the bound wechat scanning code or enter the password to log in</source>
<translation type="vanished">使</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="781"/>
<location filename="../src/mainwindow.cpp" line="785"/>
<location filename="../src/mainwindow.cpp" line="789"/>
<location filename="../src/mainwindow.cpp" line="793"/>
<source>Account locked,</source>
<translation></translation>
</message>
<message>
<source>Authentication failed, please try again</source>
<translation type="obsolete"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>
<message>
<location filename="../src/PolkitListener.cpp" line="90"/>
<source>Another client is already authenticating, please try again later.</source>
<translation></translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="265"/>
<source>Authentication failure, please try again.</source>
<translation></translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="272"/>
<source>Password input error!</source>
<translation></translation>
</message>
<message>
<source>Account locked %1 minutes due to %2 fail attempts</source>
<translation type="vanished">%1%2</translation>
</message>
<message>
<source>Authentication failure,there are still %1 remaining opportunities</source>
<translation type="vanished">%1</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<source>FingerPrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>FingerVein</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Iris</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Face</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>VoicePrint</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="obsolete"></translation>
</message>
</context>
</TS>

View File

@ -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();

View File

@ -30,6 +30,7 @@
#include <QFontMetrics>
#include <QtMath>
#include <QAbstractItemView>
#include <KWindowSystem>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
@ -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,13 +108,11 @@ 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;
if(uCurLoginOptType == LOGINOPT_TYPE_GENERAL_UKEY){
@ -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);
} 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();
}
@ -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);
}
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>459</width>
<height>547</height>
<height>646</height>
</rect>
</property>
<property name="sizePolicy">
@ -120,6 +120,9 @@
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="titleTipLayout">
<property name="topMargin">
<number>8</number>
</property>
<property name="bottomMargin">
<number>8</number>
</property>
@ -380,19 +383,6 @@
</property>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
@ -410,7 +400,7 @@
<item>
<widget class="QPushButton" name="btnBioAuth">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true"/>
@ -442,7 +432,7 @@
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true"/>
@ -461,7 +451,7 @@
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true"/>

View File

@ -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}");

View File

@ -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/)

View File

@ -0,0 +1,46 @@
#ifndef CSINGLETON_H
#define CSINGLETON_H
template <typename T>
class SingleTon
{
public:
// 创建单例实例
template<typename... Args>
static T* instance(Args&&... args)
{
if (m_pInstance == nullptr)
{
m_pInstance = new T(std::forward<Args>(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 <class T>
T* SingleTon<T>::m_pInstance = nullptr;
#endif

View File

@ -21,6 +21,7 @@
#include <QDBusInterface>
#include <QDBusArgument>
#include <QDBusMetaType>
#include <memory>
struct DeviceInfo {
int device_id;
@ -52,6 +53,10 @@ enum BioType {
Q_DECLARE_METATYPE(DeviceInfo)
Q_DECLARE_METATYPE(QList<QDBusVariant>)
typedef std::shared_ptr<DeviceInfo> DeviceInfoPtr;
typedef QList<DeviceInfoPtr> DeviceList;
void registerCustomTypes();
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo);
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo);

View File

@ -17,6 +17,7 @@
**/
#include <QCoreApplication>
#include "serviceinterface.h"
#include "personalizeddata.h"
#include <ukui-log4qt.h>
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);

View File

@ -0,0 +1,345 @@
#include "personalizeddata.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QJsonArray>
#include <QFile>
#include <QDate>
#include <QTime>
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));
}
}
}
}

View File

@ -0,0 +1,140 @@
#ifndef PERSONALIZEDDATA_H
#define PERSONALIZEDDATA_H
#include <QObject>
#include <QSettings>
#include <QMap>
#include <QFile>
#include <QTimer>
#include <QEventLoop>
#include <QTimerEvent>
#include <QFileSystemWatcher>
#include <QSharedPointer>
#include <QLightDM/Greeter>
#include <QLightDM/SessionsModel>
#include <QLightDM/UsersModel>
#include <QModelIndex>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>
#include <QJsonArray>
#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<PersonalizedData> 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<QString, KylinUserDatePtr > m_userPersonalizedData;
QLightDM::UsersModel * m_usersModel = nullptr;
QString m_lightdm_str;
friend class SingleTon<PersonalizedDataMng>;
};
typedef SingleTon<PersonalizedDataMng> KYLINUSERDATAMNG;
#endif // PERSONALIZEDDATA_H

View File

@ -0,0 +1,199 @@
#include "rsac.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
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);
}

View File

@ -0,0 +1,26 @@
#ifndef RSAC_H
#define RSAC_H
#include <QString>
/**
* @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

View File

@ -19,6 +19,9 @@
#include <QDBusConnection>
#include <QSettings>
#include <QDir>
#include <QRegExp>
#include <QFile>
#include <QTimer>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
@ -29,11 +32,25 @@
#include <QDBusMetaType>
#include <QDBusConnectionInterface>
#include <QDBusContext>
#include <QDBusInterface>
#include <QDBusMessage>
#include "servicemanager.h"
#include "personalizeddata.h"
#include <unistd.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#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<QDBusVariant> qlist;
QDBusVariant item;
DeviceInfo *deviceInfo;
DeviceInfoPtr deviceInfo = nullptr;
/* 返回值为 i -- int 和 av -- array of variant */
QDBusPendingReply<int, QList<QDBusVariant> > reply = m_serviceInterface->call("GetDrvList");
@ -652,7 +742,7 @@ void ServiceInterface::updateCommDefaultDevice(int nDriId)
variant = item.variant(); /* 转为普通QVariant对象 */
/* 解封装得到 QDBusArgument 对象 */
argument = variant.value<QDBusArgument>();
deviceInfo = new DeviceInfo();
deviceInfo = std::make_shared<DeviceInfo>();
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<QDBusArgument>();
deviceInfo = new DeviceInfo();
deviceInfo = std::make_shared<DeviceInfo>();
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"<<loginAppList.count();
if(loginAppList.contains("lightdm")){
qDebug()<<"login:";
isFirstLogin = false;
QString publicKey = getLoginPubKey(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE);
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
return sendLoginPassword(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE,username,encryptText);
}
//处于锁屏状态
if(loginAppList.contains(username)){
qDebug()<<"unlock:";
isFirstLogin = false;
QString publicKey = getLoginPubKey(loginAppList.value(username),SCREENSAVER_DBUS_PATH,SCREENSAVER_DBUS_INTERFACE);
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
return sendLoginPassword(loginAppList.value(username),SCREENSAVER_DBUS_PATH,SCREENSAVER_DBUS_INTERFACE,username,encryptText);
}
//如果是第一次调用,则配置自动登录
if(isFirstLogin){
qDebug()<<"isFirstLogin:";
isFirstLogin = false;
hasSaveLogin = true;
return handleFirstSingleLogn(username,decryptText);
}
isFirstLogin = false;
return false;
}
bool ServiceInterface::handleFirstSingleLogn(QString username,QByteArray decryptText)
{
QEventLoop loopTemp;
bool ret = false;
QByteArray encryptText;
qDebug()<<"handleFirstSingleLogn wait";
QMetaObject::Connection connection = QObject::connect(this, &ServiceInterface::onLoginServicdRegisted, [&loopTemp]() {
if (loopTemp.isRunning()) {
loopTemp.quit();
}
});
QTimer::singleShot(10000, &loopTemp, SLOT(quit()));
loopTemp.exec();
qDebug()<<"handleFirstSingleLogn finished";
disconnect(connection);
qDebug()<<loginAppList.count();
if(loginAppList.contains("lightdm")){
isFirstLogin = false;
QString publicKey = getLoginPubKey(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE);
if(publicKey.isEmpty()){
qDebug()<<"get Login PubKey failed!";
return false;
}
rsac.encrypt(decryptText, encryptText, publicKey.toLatin1());
return sendLoginPassword(loginAppList.value("lightdm"),GREETER_DBUS_PATH,GREETER_DBUS_INTERFACE,username,encryptText);
}
return ret;
}
QString ServiceInterface::getLoginPubKey(QString service,QString path,QString interface)
{
QDBusInterface iface(service,
path,
interface,
QDBusConnection::systemBus());
QDBusReply<QString> 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 "<<username<<res;
emit onSignalLoginFinished(username,res);
return true;
}
bool ServiceInterface::sendLoginPassword(QString service,QString path,QString interface,QString username,QByteArray array)
{
QEventLoop loopTemp;
bool ret = false;
qDebug()<<"sendLoginPassword";
QMetaObject::Connection connection = QObject::connect(this, &ServiceInterface::onSignalLoginFinished, [&loopTemp,&ret](QString username,bool res) {
qDebug()<<"onSignalLoginFinished:"<<username<<res;
ret = res;
if (loopTemp.isRunning()) {
loopTemp.quit();
}
});
QDBusInterface iface(service,
path,
interface,
QDBusConnection::systemBus());
QDBusReply<bool> 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 "<<filename;
QFile file(filename);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
return "";
}
QByteArray text = file.readAll();
return QString(text);
}
QString ServiceInterface::getUserNameFromUid(int uid)
{
struct passwd *pw = NULL;
pw = getpwuid(uid);
if(pw){
return QString(pw->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 "<<name;
loginAppList.remove(str);
}
}
}
}
bool ServiceInterface::registerLoginApp()
{
QDBusConnection conn = connection();
QDBusMessage msg = message();
qDebug() << "Sender Name" << conn.interface()->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 = "<<appName;
if(appName != UKUI_GREETER && appName != UKUI_SCREENSAVER){
return false;
}
QString appUser = getUserNameFromUid(uid);
if(appUser.isEmpty())
return false;
qDebug()<<"insert "<<appUser<<serviceOwner;
loginAppList.insert(appUser,serviceOwner);
if(appUser == "lightdm" && hasSaveLogin){
QTimer::singleShot(1000, this, [=](){
emit onLoginServicdRegisted();
});
}
return true;
}

View File

@ -22,7 +22,10 @@
#include <QCoreApplication>
#include <QDBusContext>
#include <QObject>
#include <QMap>
#include <QFileSystemWatcher>
#include <QDBusInterface>
#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<DeviceInfo *> m_listDeviceInfos;
DeviceList m_listDeviceInfos;
int deviceCount = 0;
bool is990 = false;
QMap<QString,int> m_AuthingDriveList;
QMap<QString,QString> loginAppList;
RSAC rsac;
QByteArray priKey, pubKey;
bool isFirstLogin = true;
bool hasSaveLogin = false;
QString savedUsername;
QByteArray savedPassword;
};
#endif // SERVICEINTERFACE_H

View File

@ -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);
}
/*!

View File

@ -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,