fix:bug#143415 【安全套件】卫士通Ukey绑定后授权提示信息乱码

This commit is contained in:
winnerym 2022-10-24 10:58:14 +08:00
parent 2ce6516dcf
commit fa9a9d8586
53 changed files with 3180 additions and 475 deletions

View File

@ -26,6 +26,7 @@ add_subdirectory(bioauth)
add_subdirectory(bioauth-bin)
add_subdirectory(pam-biometric)
add_subdirectory(polkit-agent)
add_subdirectory(uniauth-backend)
add_subdirectory(images)
add_dependencies(bioauth BioAuth)

View File

@ -91,7 +91,12 @@
<translation>Q或者Esc取消</translation>
</message>
<message>
<location filename="../src/main.cpp" line="263"/>
<location filename="../src/main.cpp" line="267"/>
<source>BIOMETRIC AUTHENTICATION IS CLOSED</source>
<translation></translation>
</message>
<message>
<location filename="../src/main.cpp" line="271"/>
<source>AUTHENTICATION SUCCESS</source>
<translation></translation>
</message>

View File

@ -237,14 +237,15 @@ int main(int argc, char *argv[])
exit(BIO_ERROR);
BioDevices bioDevices(true);
bioDevices.setUId(uid);
int maxFailedTimes = bioDevices.getFailedTimes();
int failedTimes = 0;
DeviceInfoPtr deviceInfo = bioDevices.getDefaultDevice(uid);
bool isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton();
if(!deviceInfo)
if(!deviceInfo){ // 只检查默认设备,不再使用第一个设备
exit(BIO_ERROR);
}
if(bioDevices.getFeatureCount(uid)<1)
exit(BIO_ERROR);
exit(BIO_ERROR);
showMessage(QObject::tr("BIOMETRIC AUTHENTICATION"), START);
if(!isHiddenSwitchButton)
@ -259,6 +260,11 @@ 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_);
if(!isBioEnable){
showMessage(QObject::tr("BIOMETRIC AUTHENTICATION IS CLOSED"), RESULT);
exit(BIO_IGNORE);
}
if(result && uid == uid_) {
showMessage(QObject::tr("AUTHENTICATION SUCCESS"), RESULT);
exit(BIO_SUCCESS);
@ -277,7 +283,7 @@ int main(int argc, char *argv[])
showMessage(QObject::tr("Failed to verify %1, you still have %2 verification opportunities").arg(bioDevices.bioTypeToString_tr(deviceInfo->biotype)).arg(maxFailedTimes-m_failedTimes[deviceInfo->device_id]),RESULT);
}else{
showMessage(QObject::tr("Unable to verify %1, please enter password.").arg(bioDevices.bioTypeToString_tr(deviceInfo->biotype)),RESULT);
exit(BIO_IGNORE);
exit(BIO_IGNORE);
}
Option option = showOption(bioDevices.count() > 1);
switch(option) {

View File

@ -6,6 +6,7 @@ qt5_wrap_ui(BioAuthWidgets_SRC
qt5_wrap_cpp(BioAuth_SRC
include/bioauth.h
include/biodevices.h
include/uniauthservice.h
)
qt5_wrap_cpp(BioAuthWidgets_SRC
include/bioauthwidget.h
@ -19,6 +20,7 @@ set(BioAuth_SRC
src/bioauth.cpp
src/biodevices.cpp
src/biotypes.cpp
src/uniauthservice.cpp
)
set(BioAuthWidgets_SRC

View File

@ -29,15 +29,15 @@
</message>
<message>
<source>%1 too many unsuccessful attempts,please enter password.</source>
<translation type="unfinished"></translation>
<translation>%1</translation>
</message>
<message>
<source>%1 authentication failure,there are still %2 remaining opportunities</source>
<translation type="unfinished"></translation>
<translation>%1 %2</translation>
</message>
<message>
<source>Please use wechat to scan the code</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
<context>
@ -52,7 +52,7 @@
</message>
<message>
<source>biometric</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>VoicePrint</source>
@ -60,11 +60,11 @@
</message>
<message>
<source>Unplugging of %1 device detected</source>
<translation>%1</translation>
<translation>%1</translation>
</message>
<message>
<source>%1 device insertion detected</source>
<translation>%1</translation>
<translation>%1</translation>
</message>
<message>
<source>FingerPrint</source>
@ -76,11 +76,11 @@
</message>
<message>
<source>ukui-biometric-manager</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>QRCode</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
<context>
@ -106,7 +106,7 @@
<name>LoginOptionsWidget</name>
<message>
<source>Login Options</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
</TS>

View File

@ -22,6 +22,7 @@
#include <QMap>
#include <QList>
#include "biotypes.h"
#include "uniauthservice.h"
class QDBusInterface;
@ -39,6 +40,7 @@ public:
explicit BioDevices(bool isIgnoreQrCode = false, QObject *parent = nullptr);
int count();
void setUId(int nUId);
QMap<int, QList<DeviceInfo>> getAllDevices();
QMap<int, QList<DeviceInfo>> getUserDevices(int uid);
QList<DeviceInfo> getDevices(int type);
@ -59,6 +61,7 @@ public:
bool GetHiddenSwitchButton();
bool GetQRCodeEnable();
bool GetBioAuthEnable();
QStringList getAllDefDevices();
/**
* @brief UpdateStatus
* @param drvid id
@ -66,6 +69,7 @@ public:
* int devStatus, int opsStatus, notifyMessageId, ...>
*/
StatusReslut UpdateStatus(int drvid);
bool GetBioAuthEnable(uid_t uid);
private:
void connectToService();
@ -83,6 +87,9 @@ private:
bool isShowHotPlug;
bool useFirstDevice;
bool m_isIgnoreQrCode = false;
UniAuthService *m_uniAuthService = nullptr;
int m_nUId = -1;
QList<int> m_listPriority;
};

View File

@ -62,6 +62,104 @@ enum DBusResult {
DBUS_RESULT_PERMISSIONDENIED
};
/**
* @brief Identifyops状态
*/
/* 定义操作类型 */
typedef enum {
OPS_TYPE_COMM = 0,
OPS_TYPE_OPEN,
OPS_TYPE_ENROLL,
OPS_TYPE_VERIFY,
OPS_TYPE_IDENTIFY,
OPS_TYPE_CAPTURE,
OPS_TYPE_SEARCH,
OPS_TYPE_CLEAN,
OPS_TYPE_GET_FLIST,
OPS_TYPE_RENAME,
OPS_TYPE_CLOSE,
}BioOpsType;
/*
*
*/
typedef enum {
OPS_COMM_SUCCESS = OPS_TYPE_COMM * 100, /** 空闲状态 **/
OPS_COMM_FAIL, /** 操作失败 **/
OPS_COMM_NO_MATCH = OPS_COMM_FAIL, /** 不匹配 **/
OPS_COMM_ERROR, /** 通用操作错误 **/
OPS_COMM_STOP_BY_USER, /** 用户取消 **/
OPS_COMM_TIMEOUT, /** 操作超时 **/
OPS_COMM_OUT_OF_MEM, /** 无法分配内存 **/
OPS_COMM_MAX,
OPS_OPEN_SUCCESS = OPS_TYPE_OPEN * 100, /** 打开设备完成 **/
OPS_OPEN_FAIL, /** 打开设备失败 **/
OPS_OPEN_ERROR, /** 打开设备遇到错误 **/
OPS_OPEN_MAX,
OPS_ENROLL_SUCCESS = OPS_TYPE_ENROLL * 100, /** 录入信息成功 **/
OPS_ENROLL_FAIL, /** 录入失败 **/
OPS_ENROLL_ERROR, /** 录入过程中遇到错误 **/
OPS_ENROLL_STOP_BY_USER, /** 录入被用户中断 **/
OPS_ENROLL_TIMEOUT, /** 操作超时 **/
OPS_ENROLL_MAX,
OPS_VERIFY_MATCH = OPS_TYPE_VERIFY * 100, /** 认证匹配 **/
OPS_VERIFY_NO_MATCH, /** 认证不匹配 **/
OPS_VERIFY_ERROR, /** 认证过程中遇到错误 **/
OPS_VERIFY_STOP_BY_USER, /** 认证被用户中断 **/
OPS_VERIFY_TIMEOUT, /** 操作超时 **/
OPS_VERIFY_MAX,
OPS_IDENTIFY_MATCH = OPS_TYPE_IDENTIFY * 100, /** 识别到指定特征 **/
OPS_IDENTIFY_NO_MATCH, /** 未识别出指定特征 **/
OPS_IDENTIFY_ERROR, /** 识别过程中遇到错误 **/
OPS_IDENTIFY_STOP_BY_USER, /** 识别被用户中断 **/
OPS_IDENTIFY_TIMEOUT, /** 操作超时 **/
OPS_IDENTIFY_MAX,
OPS_CAPTURE_SUCCESS = OPS_TYPE_CAPTURE * 100, /** 捕获成功 **/
OPS_CAPTURE_FAIL, /** 捕获失败 **/
OPS_CAPTURE_ERROR, /** 捕获过程中遇到错误 **/
OPS_CAPTURE_STOP_BY_USER, /** 捕获被用户中断 **/
OPS_CAPTURE_TIMEOUT, /** 操作超时 **/
OPS_CAPTURE_MAX,
OPS_SEARCH_MATCH = OPS_TYPE_SEARCH * 100, /** 搜索到指定特征 **/
OPS_SEARCH_NO_MATCH, /** 未搜索到指定特征 **/
OPS_SEARCH_ERROR, /** 搜索过程中遇到错误 **/
OPS_SEARCH_STOP_BY_USER, /** 搜索被用户中断 **/
OPS_SEARCH_TIMEOUT, /** 操作超时 **/
OPS_SEARCH_MAX,
OPS_CLEAN_SUCCESS = OPS_TYPE_CLEAN * 100, /** 清理特征成功 **/
OPS_CLEAN_FAIL, /** 清理失败 **/
OPS_CLEAN_ERROR, /** 清理过程中遇到错误 **/
OPS_CLEAN_STOP_BY_USER, /** 清理被用户中断 **/
OPS_CLEAN_TIMEOUT, /** 操作超时 **/
OPS_CLEAN_MAX,
OPS_GET_FLIST_SUCCESS = OPS_TYPE_GET_FLIST * 100, /** 获取特征列表完成 **/
OPS_GET_FLIST_FAIL, /** 获取特征列表失败 **/
OPS_GET_FLIST_ERROR, /** 获取特征列表过程中遇到错误 **/
OPS_GET_FLIST_STOP_BY_USER, /** 获取特征列表被用户中断 **/
OPS_GET_FLIST_TIMEOUT, /** 获取特征列表超时 **/
OPS_GET_FLIST_MAX,
OPS_RENAME_SUCCESS = OPS_TYPE_RENAME * 100, /** 重命名特征完成 **/
OPS_RENAME_FAIL, /** 重命名特征失败 **/
OPS_RENAME_ERROR, /** 重命名特征过程中遇到错误 **/
OPS_RENAME_STOP_BY_USER, /** 重命名特征被用户中断 **/
OPS_RENAME_TIMEOUT, /** 重命名特征超时 **/
OPS_RENAME_MAX,
OPS_CLOSE_SUCCESS = OPS_TYPE_CLOSE * 100, /** 关闭设备完成 **/
OPS_CLOSE_FAIL, /** 关闭设备失败 **/
OPS_CLOSE_ERROR, /** 关闭设备过程中遇到错误 **/
OPS_CLOSE_MAX,
}OpsResult;
/**
* @brief UpdateStauts调用返回的结果
*/

View File

@ -45,6 +45,7 @@ public:
DeviceInfoPtr findDeviceByName(const QString &name);
void setDeviceDisable(int nDevId, bool bDisable = true);
bool isDeviceDisable(int nDevId);
void lockStatusChanged(bool locked);
/**
* @brief
@ -71,6 +72,7 @@ public:
bool isAuthenticating() {
return m_isInAuth;
}
QPixmap loadSvg(QString path, QString color, int size);
public slots:
void readDevicesInfo();
@ -99,11 +101,10 @@ private:
void clearOptionButtons();
void updateOptionButtons();
void startAuth_();
bool getAuthDouble();
QPixmap PixmapToRound(const QPixmap &src, int radius);
QPixmap scaledPixmap(int width, int height, QString url);
QPixmap loadSvg(QString path, QString color, int size);
QPixmap drawSymbolicColoredPixmap(QPixmap &source, QString cgColor);
void updatePixmap();
private:
BioAuth *m_biomericProxy = nullptr;
@ -129,10 +130,14 @@ private:
QMap<int, QToolButton*> m_mapOptBtns;
QWidget *m_widgetImage = nullptr;
QLabel *m_labelFace = nullptr;
QLabel *m_labelFaceLoad = nullptr;
QLabel *m_labelQRCode = nullptr; // 二维码图标
QLabel *m_labelQRCodeMsg = nullptr; // 二维码状态消息提示
QLabel *m_labelQRCodeTip = nullptr;
QMap<int, QMap<int,bool>> m_mapDisableDev;
bool is_Lock = false;
QPixmap m_waitingPixmap;
QTimer *w_timer;
};
#endif // LOGINOPTIONSWIDGET_H

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#ifndef UNIAUTH_SERVICE_H
#define UNIAUTH_SERVICE_H
#include <QtDBus>
#include <QDBusAbstractInterface>
enum authEnableType {
ENABLETYPE_BIO, // 全局总使能
ENABLETYPE_SAVER, // 锁屏
ENABLETYPE_GREETER, // 登录
ENABLETYPE_POLKIT, // 授权
ENABLETYPE_SU, // 暂保留
ENABLETYPE_SUDO, // 暂保留
ENABLETYPE_LOGIN, // 暂保留
};
class UniAuthService : public QDBusAbstractInterface
{
Q_OBJECT
public:
explicit UniAuthService(QObject *parent = nullptr);
public Q_SLOTS:
// 设置默认设备
void setDefaultDevice(int bioDevType, QString deviceName);
// 获取默认设备
QString getDefaultDevice(QString userName, int bioDevType);
// 获取所有默认设备
QStringList getAllDefaultDevice(QString userName);
//生物特征开关接口
bool getBioAuthStatus(QString userName, int bioAuthType);
void setBioAuthStatus(int bioAuthType, bool status);
// 获取最大失败次数
int getMaxFailedTimes();
// 获取是否使能微信扫码登录
bool getQRCodeEnable();
// 获取是否双认证
bool getDoubleAuth();
// 获取用户绑定
bool getUserBind();
// 获取是否在控制面板显示
bool getIsShownInControlCenter();
// 获取是否使用第一个设备
bool getUseFirstDevice();
// 获取是否隐藏切换按钮
bool getHiddenSwitchButton();
public:
bool isActivatable();
Q_SIGNALS:
//默认设备改变
void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName);
//开关状态改变
void bioAuthStatusChanged(QString userName, int type, bool status);
private:
bool m_isActivatable;
};
#endif // UNIAUTH_SERVICE_H

View File

@ -29,14 +29,26 @@
BioDevices::BioDevices(bool isIgnoreQrCode, QObject *parent)
: QObject(parent),
m_uniAuthService(new UniAuthService(this)),
isShowHotPlug(false),
useFirstDevice(false),
m_isIgnoreQrCode(isIgnoreQrCode)
{
connectToService();
getDevicesList();
useFirstDevice = getUseFirstDevice();
m_listPriority.clear();
m_listPriority.push_back(BIOTYPE_FACE);
m_listPriority.push_back(BIOTYPE_FINGERPRINT);
m_listPriority.push_back(BIOTYPE_IRIS);
m_listPriority.push_back(BIOTYPE_VOICEPRINT);
m_listPriority.push_back(BIOTYPE_FINGERVEIN);
m_listPriority.push_back(REMOTE_QRCODE_TYPE);
}
void BioDevices::setUId(int nUId)
{
m_nUId = nUId;
getDevicesList();
}
void BioDevices::connectToService()
@ -92,6 +104,31 @@ void BioDevices::onUSBDeviceHotPlug(int deviceId, int action, int devNumNow)
}
}
bool BioDevices::GetBioAuthEnable(uid_t uid)
{
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
struct passwd *pwd = getpwuid(uid);
if (pwd) {
return m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO);
} else {
return false;
}
} else {
QString configPath = "/etc/biometric-auth/ukui-biometric.conf";
QSettings settings(configPath, QSettings::IniFormat);
qDebug() << "configure path: " << settings.fileName();
if(settings.allKeys().contains("EnableAuth")){
return settings.value("EnableAuth").toBool();
}else{
QSettings sysSettings(GET_STR(CONFIG_FILE), QSettings::IniFormat);
if(sysSettings.contains("EnableAuth"))
return sysSettings.value("EnableAuth").toBool();
else
return true;
}
}
}
/**
*
@ -237,48 +274,128 @@ void BioDevices::setIsShowHotPlug(bool isShow)
bool BioDevices::getUseFirstDevice()
{
QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
return settings.value("UseFirstDevice").toBool();
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
return m_uniAuthService->getUseFirstDevice();
} else {
QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
return settings.value("UseFirstDevice").toBool();
}
}
bool BioDevices::GetHiddenSwitchButton()
{
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if(sysSettings.contains("HiddenSwitchButton"))
return sysSettings.value("HiddenSwitchButton").toBool();
else
return false;
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
return m_uniAuthService->getHiddenSwitchButton();
} else {
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if(sysSettings.contains("HiddenSwitchButton"))
return sysSettings.value("HiddenSwitchButton").toBool();
else
return false;
}
}
int BioDevices::getFailedTimes()
{
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if(sysSettings.contains("MaxFailedTimes"))
return sysSettings.value("MaxFailedTimes").toInt();
else
return 3;
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
return m_uniAuthService->getMaxFailedTimes();
} else {
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if(sysSettings.contains("MaxFailedTimes"))
return sysSettings.value("MaxFailedTimes").toInt();
else
return 3;
}
}
bool BioDevices::GetQRCodeEnable()
{
bool isEnable = false;
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
sysSettings.beginGroup("Functions");
if (sysSettings.allKeys().contains("EnableQRCode")) {
isEnable = sysSettings.value("EnableQRCode").toBool();
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
return m_uniAuthService->getQRCodeEnable();
} else {
bool isEnable = false;
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
sysSettings.beginGroup("Functions");
if (sysSettings.allKeys().contains("EnableQRCode")) {
isEnable = sysSettings.value("EnableQRCode").toBool();
}
sysSettings.endGroup();
return isEnable;
}
sysSettings.endGroup();
return isEnable;
}
/**
* ukui-greeter 1
* ukui-screensaver 1<<1
* ukui-polkit 1<<2
* sudo 1<<3
* su 1<<4
* login 1<<5
**/
bool BioDevices::GetBioAuthEnable()
{
bool isEnable = false;
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if (sysSettings.allKeys().contains("EnableAuth")) {
isEnable = sysSettings.value("EnableAuth").toBool();
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
bool isEnable = false;
struct passwd *pwd = getpwuid(m_nUId);
if (pwd) {
isEnable = m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO);
}
if (isEnable && !isShowHotPlug) {
if(qAppName() == "polkit-ukui-authentication-agent-1") //获取polkit开关是否打开
isEnable = m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_POLKIT);
if(qAppName() == "bioauth"){ //获取父进程名称为sudosu或者login
int ppid = getppid(); //获取父进程pid
QString filename = "/proc/" + QString::number(ppid) + "/cmdline";
QFile file(filename);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
}
QByteArray text = file.readAll();
file.close();
if(text.contains("sudo")){
isEnable = m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_SUDO);
}else if(text.contains("su")){
isEnable = m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_SU);
}else if(text.contains("login")){
isEnable = m_uniAuthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_LOGIN);
}
}
}
return isEnable;
} else {
bool isEnable = false;
int isEnableApp = 0;
QSettings sysSettings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
if (sysSettings.allKeys().contains("EnableAuth")) {
isEnable = sysSettings.value("EnableAuth").toBool();
}
if (isEnable && sysSettings.allKeys().contains("EnableAuthApp")) {
isEnableApp = sysSettings.value("EnableAuthApp").toInt();
if(qAppName() == "polkit-ukui-authentication-agent-1") //获取polkit开关是否打开
isEnable = isEnableApp & (1<<2);
if(qAppName() == "bioauth"){ //获取父进程名称为sudosu或者login
int ppid = getppid(); //获取父进程pid
QString filename = "/proc/" + QString::number(ppid) + "/cmdline";
QFile file(filename);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
}
QByteArray text = file.readAll();
file.close();
if(text.contains("sudo")){
isEnable = isEnableApp & (1<<3);
}else if(text.contains("su")){
isEnable = isEnableApp & (1<<4);
}else if(text.contains("login")){
isEnable = isEnableApp & (1<<5);
}
}
}
return isEnable;
}
return isEnable;
}
DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid)
@ -286,53 +403,105 @@ DeviceInfoPtr BioDevices::getDefaultDevice(uid_t uid)
if(deviceInfos.size() <= 0)
return nullptr;
QString defaultDeviceName;
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
QString defaultDeviceName = "";
struct passwd *pwdInfo = getpwuid(uid);
DeviceInfoPtr ptrDevInfo = nullptr;
if (pwdInfo) {
for (auto bioType : m_listPriority) {
QString strDeviceName = m_uniAuthService->getDefaultDevice(pwdInfo->pw_name, bioType);
if(!strDeviceName.isEmpty()) {
ptrDevInfo = findDevice(strDeviceName);
if (ptrDevInfo) {
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
defaultDeviceName = strDeviceName;
break;
}
}
}
}
}
if(defaultDeviceName.isEmpty()){
return nullptr;
}
return ptrDevInfo;
} else {
QString defaultDeviceName;
struct passwd *pwd = getpwuid(uid);
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
qDebug() << userConfig.fileName();
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
qDebug() << defaultDeviceName;
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)) {
QSettings sysConfig(GET_STR(CONFIG_FILE), QSettings::IniFormat);
defaultDeviceName = sysConfig.value(DEFAULT_DEVICE).toString();
}
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)){
struct passwd *pwd = getpwuid(uid);
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
qDebug() << userConfig.fileName();
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
qDebug() << defaultDeviceName;
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)) {
QSettings sysConfig(GET_STR(CONFIG_FILE), QSettings::IniFormat);
defaultDeviceName = sysConfig.value(DEFAULT_DEVICE).toString();
}
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)){
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
}
qDebug() << "default device: " << defaultDeviceName;
// 终端不默认使用第一个设备
if(defaultDeviceName.isEmpty()){
return nullptr;
}
bool defValid = false;
DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName);
if (ptrDevInfo) {
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
defValid = true;
}
}
if (!defValid) {
ptrDevInfo = nullptr;
}
return ptrDevInfo;
}
qDebug() << "default device: " << defaultDeviceName;
// 终端不默认使用第一个设备
if(defaultDeviceName.isEmpty()){
// if(!useFirstDevice)
// return nullptr;
// else
// return getFirstDevice(uid);
return nullptr;
}
bool defValid = false;
DeviceInfoPtr ptrDevInfo = findDevice(defaultDeviceName);
if (ptrDevInfo) {
if (GetUserDevFeatureCount(uid,ptrDevInfo->device_id) > 0) {
defValid = true;
}
QStringList BioDevices::getAllDefDevices()
{
QStringList listDefDevices;
if (m_uniAuthService && m_uniAuthService->isActivatable()) {
struct passwd *pwdInfo = getpwuid(m_nUId);
if (pwdInfo) {
listDefDevices = m_uniAuthService->getAllDefaultDevice(pwdInfo->pw_name);
}
} else {
QString defaultDeviceName;
struct passwd *pwd = getpwuid(m_nUId);
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
qDebug() << userConfig.fileName();
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
qDebug() << defaultDeviceName;
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)) {
QSettings sysConfig(GET_STR(CONFIG_FILE), QSettings::IniFormat);
defaultDeviceName = sysConfig.value(DEFAULT_DEVICE).toString();
}
if(defaultDeviceName.isEmpty() || !findDevice(defaultDeviceName)){
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
}
qDebug() << "default device: " << defaultDeviceName;
if(!defaultDeviceName.isEmpty()){
listDefDevices.push_back(defaultDeviceName);
}
}
if (!defValid) {
// if(!useFirstDevice)
// ptrDevInfo = nullptr;
// else
// ptrDevInfo = getFirstDevice(uid);
ptrDevInfo = nullptr;
}
return ptrDevInfo;
return listDefDevices;
}
int BioDevices::GetLastDevice(const QString &userName)

View File

@ -27,6 +27,7 @@ LoginOptionsWidget::LoginOptionsWidget(QWidget *parent)
: QWidget(parent)
, m_biomericProxy(new BioAuth(this))
, m_bioDevices(new BioDevices())
, w_timer(nullptr)
{
initUI();
initConnections();
@ -73,8 +74,17 @@ void LoginOptionsWidget::initUI()
m_labelFace->setObjectName("faceLabel");
m_labelFace->setAlignment(Qt::AlignCenter);
m_labelFace->setFixedSize(154,154);
QImage img;
setFaceImg(img);
QHBoxLayout *layoutFace = new QHBoxLayout();
layoutFace->setContentsMargins(0,0,0,0);
layoutFace->setAlignment(Qt::AlignCenter);
m_labelFace->setLayout(layoutFace);
m_labelFaceLoad = new QLabel();
m_labelFaceLoad->setAlignment(Qt::AlignCenter);
m_labelFaceLoad->setFixedSize(142, 142);
m_labelFaceLoad->setStyleSheet(QString("QLabel{background-color: rgba(230,230,230,0.39); border-radius: %1px; border: 8px solid white;}").arg(71));
layoutFace->addWidget(m_labelFaceLoad, 0, Qt::AlignVCenter);
// QImage img;
// setFaceImg(img);
m_labelFace->hide();
// 二维码窗口
m_labelQRCode = new QLabel(m_widgetImage);
@ -85,11 +95,11 @@ void LoginOptionsWidget::initUI()
m_layoutMain->addLayout(m_layoutImage);
QVBoxLayout *layoutQRCode = new QVBoxLayout();
layoutQRCode->setAlignment(Qt::AlignCenter);
layoutQRCode->setSpacing(10);
layoutQRCode->setSpacing(5);
m_labelQRCode->setLayout(layoutQRCode);
m_labelQRCodeTip = new QLabel();
m_labelQRCodeTip->setFixedSize(22,22);
m_labelQRCodeTip->setPixmap(QIcon::fromTheme("ukui-dialog-warning").pixmap(QSize(22,22)));
m_labelQRCodeTip->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(QSize(22,22)));
layoutQRCode->addWidget(m_labelQRCodeTip, 0, Qt::AlignHCenter);
m_labelQRCodeMsg = new QLabel();
m_labelQRCodeMsg->setFixedHeight(24);
@ -117,7 +127,7 @@ void LoginOptionsWidget::initConnections()
if (m_bioDevices) {
connect(m_bioDevices, &BioDevices::deviceCountChanged,
this, &LoginOptionsWidget::onUSBDeviceCountChange);
readDevicesInfo();
//readDevicesInfo();
}
connect(m_btnGroup, SIGNAL(buttonClicked(int)), this, SLOT(onOptionSelected(int)));
}
@ -293,6 +303,9 @@ void LoginOptionsWidget::setUser(int uid)
}
m_uid = uid;
if (bNeedUpdateDevInfo) {
if (m_bioDevices) {
m_bioDevices->setUId(m_uid);
}
readDevicesInfo();
}
}
@ -303,6 +316,7 @@ void LoginOptionsWidget::readDevicesInfo()
bool isAuthEnable = m_bioDevices->GetBioAuthEnable();
bool isQRCodeEnable = m_bioDevices->GetQRCodeEnable();
DeviceList deviceList = m_bioDevices->GetDevList();
QStringList listDefDevices = m_bioDevices->getAllDefDevices();
for(auto pDeviceInfo : deviceList)
{
int nDevFeatureCount = 0;
@ -323,7 +337,10 @@ void LoginOptionsWidget::readDevicesInfo()
continue;
int nDevType = LOGINOPT_TYPE_OTHERS;
nDevType = convertDeviceType(pDeviceInfo->biotype);
m_mapDevices[nDevType].push_back(pDeviceInfo);
if (listDefDevices.contains(pDeviceInfo->device_shortname) &&
!m_mapDevices.contains(nDevType)) {
m_mapDevices[nDevType].push_back(pDeviceInfo);
}
}
}
updateOptionButtons();
@ -333,7 +350,7 @@ void LoginOptionsWidget::readDevicesInfo()
void LoginOptionsWidget::startAuth(DeviceInfoPtr device, int uid)
{
if(!m_biomericProxy)
if(!device || !m_biomericProxy || is_Lock)
{
qWarning() << "BiometricProxy doesn't exist.";
return;
@ -363,7 +380,24 @@ void LoginOptionsWidget::startAuth_()
m_isInAuth = true;
m_dupFD = -1;
if(!w_timer)
{
w_timer = new QTimer(this);
w_timer->setInterval(150);
connect(w_timer, &QTimer::timeout, this, &LoginOptionsWidget::updatePixmap);
}
m_waitingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(24, 24);
if(m_curLoginOptType == LOGINOPT_TYPE_QRCODE) {
m_labelQRCodeTip->setPixmap(m_waitingPixmap);
m_labelQRCodeTip->show();
m_labelQRCodeMsg->hide();
} else if(m_curLoginOptType == LOGINOPT_TYPE_FACE) {
m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(230,230,230,0.39);").arg(77));
m_labelFace->setPixmap(QPixmap(""));
m_labelFaceLoad->setPixmap(m_waitingPixmap);
m_labelFaceLoad->show();
}
w_timer->start();
m_biomericProxy->startAuth(m_uid, m_curDevInfo);
}
@ -386,6 +420,18 @@ void LoginOptionsWidget::stopAuth()
setFaceImg(img);
}
void LoginOptionsWidget::updatePixmap()
{
QMatrix matrix;
matrix.rotate(90.0);
m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation);
if(m_curLoginOptType == LOGINOPT_TYPE_QRCODE)
m_labelQRCodeTip->setPixmap(m_waitingPixmap);
else if(m_curLoginOptType == LOGINOPT_TYPE_FACE) {
m_labelFaceLoad->setPixmap(m_waitingPixmap);
}
}
void LoginOptionsWidget::onIdentifyComplete(int uid, bool ret, int retErrNo)
{
if(m_isStopped == true)
@ -414,6 +460,10 @@ void LoginOptionsWidget::onIdentifyComplete(int uid, bool ret, int retErrNo)
if(ret.result == 0 && (ret.opsStatus == 404 || ret.opsStatus == 304
|| ret.opsStatus == 8)) { // 304认证超时 8网络异常
Q_EMIT authComplete(uid, false, 1);
} else if (ret.opsStatus == OPS_IDENTIFY_STOP_BY_USER || ret.opsStatus == OPS_VERIFY_STOP_BY_USER) {
Q_EMIT authComplete(uid, false, -2); // 主动停止,直接重试
} else if (ret.opsStatus == OPS_OPEN_FAIL || ret.opsStatus == OPS_OPEN_ERROR) { // 无法打开设备(设备是坏的/被占用),直接禁用
Q_EMIT authComplete(uid, false, 5);
} else {
Q_EMIT authComplete(uid, false, 2);
}
@ -518,6 +568,7 @@ void LoginOptionsWidget::onFrameWritten(int drvid)
m_labelQRCode->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,100%);").arg(6));
setQRCode(srcQImage);
m_labelQRCode->show();
m_labelQRCodeTip->hide();
m_labelFace->hide();
} else {
m_labelFace->hide();
@ -527,6 +578,10 @@ void LoginOptionsWidget::onFrameWritten(int drvid)
m_labelFace->hide();
m_labelQRCode->hide();
}
if(w_timer && w_timer->isActive())
{
w_timer->stop();
}
Q_EMIT updateImage(srcQImage);
}
@ -544,11 +599,17 @@ void LoginOptionsWidget::setQRCodeMsg(QString strMsg)
{
if (strMsg.isEmpty()) {
m_labelQRCodeMsg->hide();
m_labelQRCodeTip->hide();
//m_labelQRCodeTip->hide();
} else {
//一开始认证时就没有网,直接停止加载状态
if(w_timer && w_timer->isActive())
{
w_timer->stop();
}
m_labelQRCodeMsg->setText(strMsg);
m_labelQRCodeMsg->show();
m_labelQRCodeTip->show();
m_labelQRCodeTip->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(QSize(22,22)));
}
}
@ -563,15 +624,22 @@ void LoginOptionsWidget::setFaceImg(QImage& imgFace, int nStatus)
switch(nStatus) {
case 1:
faceImage = loadSvg(QString("%1/images/ukui-loginopt-lose.svg").arg(GET_STR(UKUI_BIOMETRIC)),"black",48);
m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(230,230,230,40%);").arg(77));
break;
case 2:
faceImage = loadSvg(QString("%1/images/ukui-loginopt-smile.svg").arg(GET_STR(UKUI_BIOMETRIC)),"gray",48);
m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(230,230,230,100%);").arg(77));
break;
default:
faceImage = loadSvg(QString("%1/images/ukui-loginopt-smile.svg").arg(GET_STR(UKUI_BIOMETRIC)),"black",48);
m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(230,230,230,40%);").arg(77));
break;
}
}
m_labelFace->setAlignment(Qt::AlignCenter);
m_labelFace->setPixmap(faceImage);
m_labelFaceLoad->hide();
}
void LoginOptionsWidget::onStatusChanged(int drvid, const QString &message)
@ -646,24 +714,10 @@ DeviceInfoPtr LoginOptionsWidget::findDeviceByName(const QString &name)
QString LoginOptionsWidget::GetDefaultDevice(uid_t uid)
{
QString defaultDeviceName;
struct passwd *pwd = getpwuid(uid);
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
qDebug() << userConfig.fileName();
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
qDebug() << defaultDeviceName;
if(defaultDeviceName.isEmpty() || !findDeviceByName(defaultDeviceName)) {
QSettings sysConfig(GET_STR(CONFIG_FILE), QSettings::IniFormat);
defaultDeviceName = sysConfig.value(DEFAULT_DEVICE).toString();
}
if(defaultDeviceName.isEmpty() || !findDeviceByName(defaultDeviceName)){
QString userConfigFile = QString(pwd->pw_dir) + "/.biometric_auth/ukui_biometric.conf";
QSettings userConfig(userConfigFile, QSettings::IniFormat);
defaultDeviceName = userConfig.value(DEFAULT_DEVICE).toString();
QString defaultDeviceName = "";
DeviceInfoPtr pDeviceInfo = m_bioDevices->getDefaultDevice(uid);
if (pDeviceInfo) {
defaultDeviceName = pDeviceInfo->device_shortname;
}
qDebug() << "default device: " << defaultDeviceName;
@ -691,13 +745,6 @@ void LoginOptionsWidget::onUSBDeviceCountChange(int newNum)
updateUIStatus(false);
}
bool LoginOptionsWidget::getAuthDouble()
{
QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat);
bool distribId = settings.value("DoubleAuth").toBool();
return distribId;
}
void LoginOptionsWidget::updateUIStatus(bool update)
{
if (m_mapOptBtns.contains(-1)) {
@ -810,6 +857,17 @@ bool LoginOptionsWidget::isDeviceDisable(int nDevId)
return false;
}
void LoginOptionsWidget::lockStatusChanged(bool locked)
{
if(locked){
is_Lock = true;
stopAuth();
} else {
is_Lock = false;
readDevicesInfo();
}
}
QPixmap LoginOptionsWidget::loadSvg(QString path, QString color, int size)
{
int origSize = size;

View File

@ -0,0 +1,251 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include "uniauthservice.h"
#include <QDebug>
#include <pwd.h>
#define UNIAUTH_DBUS_SERVICE "org.ukui.UniauthBackend"
#define UNIAUTH_DBUS_PATH "/org/ukui/UniauthBackend"
#define UNIAUTH_DBUS_INTERFACE "org.ukui.UniauthBackend"
#define FD_DBUS_SERVICE "org.freedesktop.DBus"
#define FD_DBUS_PATH "/org/freedesktop/DBus"
#define FD_DBUS_INTERFACE "org.freedesktop.DBus"
UniAuthService::UniAuthService(QObject *parent)
: QDBusAbstractInterface(UNIAUTH_DBUS_SERVICE,
UNIAUTH_DBUS_PATH,
UNIAUTH_DBUS_INTERFACE,
QDBusConnection::systemBus(),
parent)
, m_isActivatable(false)
{
setTimeout(2147483647);
QDBusInterface *dbusService = new QDBusInterface(FD_DBUS_SERVICE,
FD_DBUS_PATH,
FD_DBUS_INTERFACE,
QDBusConnection::systemBus());
if (dbusService) {
QDBusReply<QStringList> result = dbusService->call(QStringLiteral("ListActivatableNames"));
if(!result.isValid()) {
qWarning() << "ListActivatableNames error:" << result.error().message();
} else {
QStringList listNames = result.value();
if (listNames.contains(UNIAUTH_DBUS_INTERFACE)) {
m_isActivatable = true;
}
}
}
}
// 设置默认设备
void UniAuthService::setDefaultDevice(int bioDevType, QString deviceName)
{
qDebug() << " bioType : " << bioDevType << "deviceName : " << deviceName;
QDBusMessage result = call(QStringLiteral("setDefaultDevice"), bioDevType, deviceName);
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "setDefaultDevice error:" << result.errorMessage();
return ;
}
return ;
}
// 获取默认设备
QString UniAuthService::getDefaultDevice(QString userName, int bioDevType)
{
QDBusMessage result = call(QStringLiteral("getDefaultDevice"), userName, bioDevType);
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getDefaultDevice error:" << result.errorMessage();
return "";
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
QString strDefDevice = varResult.takeFirst().toString();
return strDefDevice;
} else {
return "";
}
}
// 获取所有默认设备
QStringList UniAuthService::getAllDefaultDevice(QString userName)
{
QStringList listDefDevices;
QDBusReply<QStringList> result = call(QStringLiteral("getAllDefaultDevice"), userName);
if(!result.isValid()) {
qWarning() << "getAllDefaultDevice error:" << result.error().message();
} else {
listDefDevices = result.value();
}
return listDefDevices;
}
//生物特征开关接口
bool UniAuthService::getBioAuthStatus(QString userName, int bioAuthType)
{
QDBusMessage bioResult = call(QStringLiteral("getBioAuthStatus"), userName, bioAuthType);
if(bioResult.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getBioStatus error:" << bioResult.errorMessage();
return false;
}
QList<QVariant> varResult = bioResult.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
void UniAuthService::setBioAuthStatus(int bioAuthType, bool status)
{
qDebug() << "setBioAuthStatus bioAuthType : " << bioAuthType << "status : " << status;
QDBusMessage result = call(QStringLiteral("setBioAuthStatus"), bioAuthType, status);
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "setBioAuthStatus error:" << result.errorMessage();
return ;
}
return ;
}
// 获取最大失败次数
int UniAuthService::getMaxFailedTimes()
{
QDBusMessage result = call(QStringLiteral("getMaxFailedTimes"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getMaxFailedTimes error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toInt();
} else {
return 3;
}
}
// 获取是否使能微信扫码登录
bool UniAuthService::getQRCodeEnable()
{
QDBusMessage result = call(QStringLiteral("getQRCodeEnable"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getQRCodeEnable error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
// 获取是否双认证
bool UniAuthService::getDoubleAuth()
{
QDBusMessage result = call(QStringLiteral("getDoubleAuth"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getDoubleAuth error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
// 获取用户绑定
bool UniAuthService::getUserBind()
{
QDBusMessage result = call(QStringLiteral("getUserBind"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getUserBind error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
// 获取是否在控制面板显示
bool UniAuthService::getIsShownInControlCenter()
{
QDBusMessage result = call(QStringLiteral("getIsShownInControlCenter"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getIsShownInControlCenter error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
// 获取是否使用第一个设备
bool UniAuthService::getUseFirstDevice()
{
QDBusMessage result = call(QStringLiteral("getUseFirstDevice"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getUseFirstDevice error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
// 获取是否隐藏切换按钮
bool UniAuthService::getHiddenSwitchButton()
{
QDBusMessage result = call(QStringLiteral("getHiddenSwitchButton"));
if(result.type() == QDBusMessage::ErrorMessage)
{
qWarning() << "getHiddenSwitchButton error:" << result.errorMessage();
return false;
}
QList<QVariant> varResult = result.arguments();
if (varResult.size() > 0) {
return varResult.takeFirst().toBool();
} else {
return false;
}
}
bool UniAuthService::isActivatable()
{
return m_isActivatable;
}

View File

@ -1,4 +1,6 @@
/etc/biometric-auth/ukui-biometric.conf
/usr/share/ukui-biometric/ukui-biometric.conf
/usr/share/dbus-1/system-services/org.ukui.UniauthBackend.service
/etc/dbus-1/system.d/org.ukui.UniauthBackend.conf
/lib/security/*
/usr/bin/*
/usr/share/pam-configs/*

View File

@ -3,3 +3,52 @@ set -e
#DEBHELPER#
pam-auth-update --package
#update default conf
config_file=/etc/biometric-auth/ukui-biometric.conf
delimeter='='
get_opt(){
file=$1
section=$2
key=$3
val=$(awk -F "$delimeter" '/\['${section}'\]/{a=1}(a==1 && "'${key}'"==$1){print $2;exit}' ${file})
echo ${val}
}
is_key_exist(){
file=$1
section=$2
key=$3
is_exist=$(awk -F "$delimeter" '/\['${section}'\]/{a=1}(a==1 && "'${key}'"==$1){print '1';exit}' ${file})
echo ${is_exist}
}
set_opt(){
file=$1
section=$2
key=$3
val=$4
contain_section=$(awk '/\['${section}'\]/ {print NR}' ${file})
if [ ${#contain_section} -gt 0 ]; then
is_exist=$(is_key_exist $file $section $key)
if [ "${is_exist}" = "1" ]; then
awk -F "$delimeter" '/\['${section}'\]/{a=1}(a==1 && "'${key}'"==$1){gsub($2,"'${val}'");a=0} {print $0}' ${file} 1<>${file}
else
sed -i "s/\[${section}\]/\[${section}\]\n${key}\=${val}/g" ${file}
fi
else
echo -e "\n[${section}]\n${key}=${val}" >> ${file}
sed -i "s/\-e//g" ${file}
fi
}
if [ ! -f ${config_file} ]; then
mkdir -p /etc/biometric-auth
cp /usr/share/ukui-biometric/ukui-biometric.conf ${config_file}
else
set_opt ${config_file} General UseFirstDevice true
set_opt ${config_file} General MaxFailedTimes 5
set_opt ${config_file} Functions EnableQRCode true
fi

View File

@ -39,7 +39,7 @@ set_target_properties(pam_biometric PROPERTIES PREFIX "")
install(TARGETS pam_biometric DESTINATION /lib/security)
install(FILES pam-configs/pam-biometric DESTINATION /usr/share/pam-configs)
install(FILES data/ukui-biometric.conf DESTINATION /etc/biometric-auth)
install(FILES data/ukui-biometric.conf DESTINATION /usr/share/ukui-biometric)
install(FILES
${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.bioctl-helper.policy
${PROJECT_BINARY_DIR}/data/org.freedesktop.plicykit.pkexec.biodrvctl.policy

View File

@ -7,8 +7,10 @@
<action id="org.freedesktop.policykit.pkexec.bioctl">
<description>Run the biometric authentication control tool</description>
<description xml:lang="zh">运行生物识别认证控制工具</description>
<description xml:lang="bo">འཁོར་སྐྱོད་སྐྱེ་དངོས་ཀྱི་ངོས་འཛིན་ཁས་ལེན་ཚོད་འཛིན་ཡོ་བྱད།།</description>
<message>Authentication is required to enable or disable biometric authentication</message>
<message xml:lang="zh">开启或关闭生物识别认证需要进行身份验证</message>
<message xml:lang="bo">སྒོ་རྒྱག་པའམ་ཡང་ན་སྒོ་རྒྱག་པའི་སྐྱེ་དངོས་ངོས་འཛིན་བདེན་དཔངར་སྤྲོད་བྱེད་པར་ཐོབ་ཐང་གི་ཚོད་ལྟསར་སྤྲོད་བྱ་དགོས།</message>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>no</allow_any>

View File

@ -7,8 +7,10 @@
<action id="org.freedesktop.policykit.pkexec.biodrvctl">
<description>Run the biometric device driver control tool</description>
<description xml:lang="zh">运行生物识别设备驱动控制工具</description>
<message>Authentication is required to change the status of biometric device's driver</message>
<message xml:lang="zh">改变生物识别设备驱动状态需要进行身份验证</message>
<description xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་སྒྲག་ཆས་ཀྱི་ཁ་ལོ་བའི་ཚོད་འཛིན་ཡོ་བྱད་</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>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>

View File

@ -7,8 +7,10 @@
<action id="org.freedesktop.policykit.pkexec.biorestart">
<description>Restart Service</description>
<description xml:lang="zh">重启生物特征服务</description>
<message>Authentication is required to restart biometric service</message>
<message xml:lang="zh">重启生物特征服务需要身份验证</message>
<description xml:lang="bo">བསྐྱར་དུ་ཞབས་འདེགས་ཞུ་བ</description>
<message>Authentication is required to restart biometric service</message>
<message xml:lang="zh">重启生物特征服务需要身份验证</message>
<message xml:lang="bo">སྐྱ་དངོས་དབྱེ་འབྱེད་ཞབས་ཞུ་སླར་གསོ་བྱེད་པར་བདེན་དཔང་ར་སྤྲད་བྱ་དགོས།</message>
<icon_name>stock_person</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>

View File

@ -1,5 +1,6 @@
[General]
EnableAuth=false
EnableAuthApp=63
DefaultDevice=
DoubleAuth=false
UserBind=false

View File

@ -20,6 +20,7 @@
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <syslog.h>
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <string.h>
@ -31,6 +32,8 @@
#include <signal.h>
#include <errno.h>
#define USER_CONFIG_FILE "/home/%s/.biometric_auth/ukui_biometric.conf"
/* Declare log function */
extern int enable_debug;
extern char *log_prefix;
@ -50,28 +53,70 @@ static void signal_handler(int signo)
logger("signal_handler is triggered\n");
}
int enable_biometric_authentication_app()
{
char conf_file[] = GET_STR(CONFIG_FILE);
FILE *file;
char line[1024];
int i;
int is_enable = 0;
if((file = fopen(conf_file, "r")) == NULL){
logger("open configure file failed: %s\n", strerror(errno));
return 1;
}
while(fgets(line, sizeof(line), file)) {
i = sscanf(line, "EnableAuthApp=%d\n", &is_enable);
if(i > 0) {
logger("EnableAuthApp=%d\n", is_enable);
break;
}
}
fclose(file);
return is_enable;
}
/*
* Check if the service should use biometric authentication
*/
int service_filter(char *service)
{
//int is_enable = enable_biometric_authentication_app();
//syslog(LOG_INFO,"is_enable = %d service = %s\n",is_enable,service);
if (strcmp(service, "lightdm") == 0) {
int ret = system("/bin/chmod -f a+wr /tmp/bio.log");
(void)ret; /* Suppress gcc ignoring return value warning */
//if(is_enable & 1 == 0)
// return 0;
return 1;
}
if (strcmp(service, "ukui-screensaver-qt") == 0){
//if((is_enable & (1<<1)) == 0)
// return 0;
return 1;
}
if (strcmp(service, "ukui-screensaver-qt") == 0)
if (strcmp(service, "polkit-1") == 0){
//if((is_enable & (1<<2)) == 0)
// return 0;
return 1;
if (strcmp(service, "sudo") == 0)
return 1;
if (strcmp(service, "login") == 0)
}
if (strcmp(service, "sudo") == 0){
//if((is_enable & (1<<3)) == 0)
// return 0;
return 1;
if (strcmp(service, "su") == 0)
}
if (strcmp(service, "su") == 0){
//if((is_enable & (1<<4)) == 0)
// return 0;
return 1;
// if (strcmp(service, "mate-screensaver") == 0)
// return 1;
if (strcmp(service, "polkit-1") == 0)
}
if (strcmp(service, "login") == 0){
//if((is_enable & (1<<5)) == 0)
// return 0;
return 1;
}
#ifdef ENABLE_BIOTEST
if (strcmp(service, "biotest") == 0)
return 1;
@ -104,11 +149,11 @@ int call_conversation(pam_handle_t *pamh, int msg_style, char *msg, char *resp)
status = conv_struct->conv(1, message, &response, conv_struct->appdata_ptr);
logger("Finish conv callback function\n");
if (resp)
strcpy(resp, response->resp);
if (resp && response->resp)
strcpy(resp, response->resp);
/* Use typecast to suppress gcc warnings */
free((void *)message[0]);
if (response)
if (response->resp)
free(response->resp);
free(response);
@ -215,9 +260,9 @@ int parent(int pid, pam_handle_t *pamh, int need_call_conv)
logger("The GUI-Child process terminate abnormally.\n");
if (bio_result == BIO_SUCCESS) {
if(!enable_biometric_authentication(pamh) && !enable_qrcode_authentication(pamh)) {
logger("disable biometric authentication.\n");
return PAM_SYSTEM_ERR;
if(!enable_biometric_authentication(pamh) && !enable_qrcode_authentication(pamh)) {
logger("disable biometric authentication.\n");
return PAM_SYSTEM_ERR;
}
logger("pam_biometric.so return PAM_SUCCESS\n");
return PAM_SUCCESS;
@ -395,18 +440,47 @@ int enable_by_polkit()
int enable_biometric_authentication(pam_handle_t *pamh)
{
char *username = NULL;
int is_found = 0;
int is_auth_enable = 0;
pam_get_item(pamh, PAM_USER, (const void **)&username);
if (username) {
char conf_file_user[256];
snprintf(conf_file_user, 255, USER_CONFIG_FILE, username);
FILE *file = NULL;
char line[1024], is_enable[16];
int i;
if((file = fopen(conf_file_user, "r")) == NULL){
logger("open configure file failed: %s\n", strerror(errno));
} else {
while(fgets(line, sizeof(line), file)) {
i = sscanf(line, "EnableAuth=%15s\n", is_enable);
if(i > 0) {
logger("EnableAuth=%s\n", is_enable);
is_found = 1;
break;
}
}
fclose(file);
if(!strcmp(is_enable, "true"))
is_auth_enable = 1;
}
}
if (is_found != 0) {
return is_auth_enable;
}
char conf_file[] = GET_STR(CONFIG_FILE);
FILE *file;
char line[1024], is_enable[16];
int i;
if((file = fopen(conf_file, "r")) == NULL){
logger("open configure file failed: %s\n", strerror(errno));
return 0;
}
while(fgets(line, sizeof(line), file)) {
i = sscanf(line, "EnableAuth=%s\n", is_enable);
i = sscanf(line, "EnableAuth=%15s\n", is_enable);
if(i > 0) {
logger("EnableAuth=%s\n", is_enable);
break;
@ -421,18 +495,47 @@ int enable_biometric_authentication(pam_handle_t *pamh)
int enable_qrcode_authentication(pam_handle_t *pamh)
{
char *username = NULL;
int is_found = 0;
int is_auth_enable = 0;
pam_get_item(pamh, PAM_USER, (const void **)&username);
if (username) {
char conf_file_user[256];
snprintf(conf_file_user, 255, USER_CONFIG_FILE, username);
FILE *file = NULL;
char line[1024], is_enable[16];
int i;
if((file = fopen(conf_file_user, "r")) == NULL){
logger("open configure file failed: %s\n", strerror(errno));
} else {
while(fgets(line, sizeof(line), file)) {
i = sscanf(line, "EnableQRCode=%15s\n", is_enable);
if(i > 0) {
logger("EnableQRCode=%s\n", is_enable);
is_found = 1;
break;
}
}
fclose(file);
if(!strcmp(is_enable, "true"))
is_auth_enable = 1;
}
}
if (is_found != 0) {
return is_auth_enable;
}
char conf_file[] = GET_STR(CONFIG_FILE);
FILE *file;
char line[1024], is_enable[16];
int i;
if((file = fopen(conf_file, "r")) == NULL){
logger("open configure file failed: %s\n", strerror(errno));
return 0;
}
while(fgets(line, sizeof(line), file)) {
i = sscanf(line, "EnableQRCode=%s\n", is_enable);
i = sscanf(line, "EnableQRCode=%15s\n", is_enable);
if(i > 0) {
logger("EnableQRCode=%s\n", is_enable);
break;
@ -502,8 +605,6 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
return PAM_IGNORE;
}
/* Different services use different processing function */
if (strcmp(service, "lightdm") == 0) {
char buf[128];

View File

@ -3,11 +3,11 @@
# Usage: bioctl status|enable|disable
if [ "$1" = "enable" ]; then
pkexec /usr/bin/bioctl-helper enable
pkexec /usr/bin/bioctl-helper enable $2
elif [ "$1" = "disable" ]; then
pkexec /usr/bin/bioctl-helper disable
pkexec /usr/bin/bioctl-helper disable $2
elif [ "$1" = "status" ]; then
/usr/bin/bioctl-helper status
/usr/bin/bioctl-helper status $2
else
echo "Usage: bioctl status|enable|disable"
fi

View File

@ -23,6 +23,13 @@ if [ ! -f $CONFIG_FILE ]; then
fi
contain_key=`grep -c "^EnableAuth=" $CONFIG_FILE`
contain_key_app=`grep -c "^EnableAuthApp=" $CONFIG_FILE`
greeter=1
screensaver=$[1<<1]
polkit=$[1<<2]
sudo=$[1<<3]
su=$[1<<4]
login=$[1<<5]
if [ "$1" = "enable" ]; then
test_privilege
@ -34,25 +41,158 @@ if [ "$1" = "enable" ]; then
#执行 pam-auth-update 了。
#pam-auth-update --package pam-biometric
if [ "$contain_key" = "1" ]; then
if [[ $# > 1 ]] && [[ $2 = "greeter" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $greeter ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "screensaver" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $screensaver ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "sudo" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $sudo ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "polkit" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $polkit ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "su" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $su ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "login" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app | $login ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=63" >> $CONFIG_FILE
fi
elif [ "$contain_key" = "1" ]; then
sed -i 's/^EnableAuth=[a-zA-Z0-9]*/EnableAuth=true/g' $CONFIG_FILE
else
echo "EnableAuth=true" >> $CONFIG_FILE
fi
elif [ "$1" = "disable" ]; then
test_privilege
if [ "$contain_key" = "1" ]; then
if [[ $# > 1 ]] && [[ $2 = "greeter" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[~$greeter] ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "screensaver" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[ ~$screensaver ]]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "sudo" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[ ~$sudo ] ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "polkit" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[~$polkit] ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "su" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[~$su] ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [[ $# > 1 ]] && [[ $2 = "login" ]]; then
if [ "$contain_key_app" = "1" ]; then
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=$[ $cur_status_app & $[~$login] ]
sed -i "s/^EnableAuthApp=[a-zA-Z0-9]*/EnableAuthApp=$cur_status_app/g" $CONFIG_FILE
else
echo "EnableAuthApp=0" >> $CONFIG_FILE
fi
elif [ "$contain_key" = "1" ]; then
sed -i 's/^EnableAuth=[a-zA-Z0-9]*/EnableAuth=false/g' $CONFIG_FILE
else
echo "EnableAuth=false" >> $CONFIG_FILE
fi
elif [ "$1" = "status" ]; then
cur_status=`sed '/^EnableAuth/!d;s/.*=//' $CONFIG_FILE`
if [ "$cur_status" = "true" ]; then
echo "enable"
cur_status=`sed '/^EnableAuth=/!d;s/.*=//' $CONFIG_FILE`
cur_status_app=`sed '/^EnableAuthApp=/!d;s/.*=//' $CONFIG_FILE`
if [[ $# > 1 ]] && [[ $2 = "greeter" ]];then
if [ $[ $[cur_status_app] & $[greeter] ] = $greeter ]; then
echo "enable"
else
echo "disable"
fi
elif [[ $# > 1 ]] && [[ $2 = "screensaver" ]];then
if [ $[$cur_status_app & $screensaver] = $screensaver ]; then
echo "enable"
else
echo "disable"
fi
elif [[ $# > 1 ]] && [[ $2 = "sudo" ]];then
if [ $[$cur_status_app & $sudo] = $sudo ]; then
echo "enable"
else
echo "disable"
fi
elif [[ $# > 1 ]] && [[ $2 = "polkit" ]];then
if [ $[$cur_status_app & $polkit] = $polkit ]; then
echo "enable"
else
echo "disable"
fi
elif [[ $# > 1 ]] && [[ $2 = "su" ]];then
if [ $[$cur_status_app & $su] = $su ]; then
echo "enable"
else
echo "disable"
fi
elif [[ $# > 1 ]] && [[ $2 = "login" ]];then
if [ $[$cur_status_app & $login] = $login ]; then
echo "enable"
else
echo "disable"
fi
elif [ "$cur_status" = "true" ]; then
echo "enable"
else
echo "disable"
echo "disable"
fi
else
echo "Usage: bioctl status|enable|disable"

View File

@ -35,6 +35,7 @@ else
fi
if [ $? -eq 0 ]; then
systemctl reset-failed biometric-authentication.service
systemctl restart biometric-authentication.service
fi

View File

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6)
project(ukui-polkit-agent)
pkg_check_modules(QGS REQUIRED gsettings-qt)
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)
@ -18,11 +19,17 @@ configure_file(
include_directories(
${QGS_INCLUDE_DIRS}
${KDKINFO_INCLUDE_DIRS}
)
link_directories(
${KDKINFO_LIBRARY_DIRS}
)
set(EXTRA_LIBS
${EXTRA_LIBS}
${QGS_LIBRARIES}
${KDKINFO_LIBRARIES}
)
include_directories(
@ -42,6 +49,7 @@ set(polkit_SRCS
src/users.cpp
src/pam-tally.c
src/modeButton.cpp
src/kalabel.cpp
../common/generic.cpp
)

View File

@ -9,180 +9,185 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="299"/>
<location filename="../src/mainwindow.cpp" line="836"/>
<location filename="../src/mainwindow.cpp" line="893"/>
<location filename="../src/mainwindow.ui" line="302"/>
<location filename="../src/mainwindow.cpp" line="882"/>
<location filename="../src/mainwindow.cpp" line="948"/>
<source>Biometric</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="360"/>
<location filename="../src/mainwindow.ui" line="373"/>
<source>use password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="331"/>
<location filename="../src/mainwindow.cpp" line="838"/>
<location filename="../src/mainwindow.ui" line="334"/>
<location filename="../src/mainwindow.cpp" line="884"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="350"/>
<location filename="../src/mainwindow.cpp" line="834"/>
<location filename="../src/mainwindow.ui" line="353"/>
<location filename="../src/mainwindow.cpp" line="880"/>
<source>Authenticate</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="63"/>
<location filename="../src/mainwindow.cpp" line="65"/>
<source>Authentication</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="161"/>
<location filename="../src/mainwindow.cpp" line="1111"/>
<location filename="../src/mainwindow.cpp" line="164"/>
<location filename="../src/mainwindow.cpp" line="1176"/>
<source>Failed to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="165"/>
<location filename="../src/mainwindow.cpp" line="1113"/>
<location filename="../src/mainwindow.cpp" line="168"/>
<location filename="../src/mainwindow.cpp" line="1178"/>
<source>Unable to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="171"/>
<location filename="../src/mainwindow.cpp" line="175"/>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="183"/>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="247"/>
<location filename="../src/mainwindow.cpp" line="261"/>
<source>Please enter your password or enroll your fingerprint </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="475"/>
<location filename="../src/mainwindow.cpp" line="511"/>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="517"/>
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="536"/>
<location filename="../src/mainwindow.cpp" line="578"/>
<source>Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="538"/>
<location filename="../src/mainwindow.cpp" line="580"/>
<source>_Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="540"/>
<location filename="../src/mainwindow.cpp" line="582"/>
<source>_Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="581"/>
<location filename="../src/mainwindow.cpp" line="585"/>
<location filename="../src/mainwindow.cpp" line="589"/>
<location filename="../src/mainwindow.cpp" line="593"/>
<location filename="../src/mainwindow.cpp" line="623"/>
<location filename="../src/mainwindow.cpp" line="627"/>
<location filename="../src/mainwindow.cpp" line="631"/>
<location filename="../src/mainwindow.cpp" line="635"/>
<source>Account locked,</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="581"/>
<location filename="../src/mainwindow.cpp" line="623"/>
<source>days left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="585"/>
<location filename="../src/mainwindow.cpp" line="627"/>
<source>hours left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="589"/>
<location filename="../src/mainwindow.cpp" line="631"/>
<source>minutes left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="593"/>
<location filename="../src/mainwindow.cpp" line="635"/>
<source>seconds left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="633"/>
<location filename="../src/mainwindow.cpp" line="634"/>
<location filename="../src/mainwindow.cpp" line="675"/>
<location filename="../src/mainwindow.cpp" line="676"/>
<source>Password cannot be empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="840"/>
<location filename="../src/mainwindow.cpp" line="927"/>
<location filename="../src/mainwindow.cpp" line="886"/>
<location filename="../src/mainwindow.cpp" line="991"/>
<source>Use password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="962"/>
<location filename="../src/mainwindow.cpp" line="1029"/>
<location filename="../src/mainwindow.cpp" line="1030"/>
<location filename="../src/mainwindow.cpp" line="1026"/>
<location filename="../src/mainwindow.cpp" line="1093"/>
<location filename="../src/mainwindow.cpp" line="1094"/>
<source>Please try again in %1 minutes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="972"/>
<location filename="../src/mainwindow.cpp" line="1039"/>
<location filename="../src/mainwindow.cpp" line="1040"/>
<location filename="../src/mainwindow.cpp" line="1036"/>
<location filename="../src/mainwindow.cpp" line="1103"/>
<location filename="../src/mainwindow.cpp" line="1104"/>
<source>Please try again in %1 seconds.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="981"/>
<location filename="../src/mainwindow.cpp" line="982"/>
<location filename="../src/mainwindow.cpp" line="1048"/>
<location filename="../src/mainwindow.cpp" line="1049"/>
<location filename="../src/mainwindow.cpp" line="1045"/>
<location filename="../src/mainwindow.cpp" line="1046"/>
<location filename="../src/mainwindow.cpp" line="1112"/>
<location filename="../src/mainwindow.cpp" line="1113"/>
<source>Account locked permanently.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1127"/>
<location filename="../src/mainwindow.cpp" line="1193"/>
<source>Verify face recognition or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1132"/>
<location filename="../src/mainwindow.cpp" line="1198"/>
<source>Press fingerprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1137"/>
<location filename="../src/mainwindow.cpp" line="1203"/>
<source>Verify voiceprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1142"/>
<location filename="../src/mainwindow.cpp" line="1208"/>
<source>Verify finger vein or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1147"/>
<location filename="../src/mainwindow.cpp" line="1213"/>
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1152"/>
<location filename="../src/mainwindow.cpp" line="1218"/>
<source>Use the bound wechat scanning code or enter the password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="534"/>
<location filename="../src/mainwindow.cpp" line="576"/>
<source>Input Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="649"/>
<location filename="../src/mainwindow.cpp" line="187"/>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="691"/>
<source>Authentication failed, please try again.</source>
<translation type="unfinished"></translation>
</message>
@ -190,17 +195,17 @@
<context>
<name>PolkitListener</name>
<message>
<location filename="../src/PolkitListener.cpp" line="59"/>
<location filename="../src/PolkitListener.cpp" line="88"/>
<source>Another client is already authenticating, please try again later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="226"/>
<location filename="../src/PolkitListener.cpp" line="257"/>
<source>Authentication failure, please try again.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="233"/>
<location filename="../src/PolkitListener.cpp" line="264"/>
<source>Password input error!</source>
<translation type="unfinished"></translation>
</message>

View File

@ -1,194 +1,421 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="bo_CN">
<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>
<source>Form</source>
<translation></translation>
</message>
<message>
<source>days left</source>
<translation></translation>
</message>
<message>
<source>Please enter your password or enroll your fingerprint </source>
<translation></translation>
</message>
<message>
<source>Authenticate</source>
<translation></translation>
</message>
<message>
<source>in authentication, please wait...</source>
<translation type="vanished"> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="65"/>
<source>Authentication</source>
<translation></translation>
</message>
<message>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<source>Description:</source>
<translation type="vanished">:</translation>
</message>
<message>
<source>Biometric</source>
<translation></translation>
</message>
<message>
<source>Too many unsuccessful attempts,please enter password.</source>
<translation type="vanished"> </translation>
</message>
<message>
<source>Action:</source>
<translation type="vanished"></translation>
<translation></translation>
</message>
<message>
<source>Fingerprint authentication failed, you still have %1 verification opportunities</source>
<translation type="vanished"> </translation>
<translation type="vanished">%1</translation>
</message>
<message>
<source>Polkit.caller-pid:</source>
<translation type="vanished">Polkit.caller-pid</translation>
<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="302"/>
<location filename="../src/mainwindow.cpp" line="882"/>
<location filename="../src/mainwindow.cpp" line="948"/>
<source>Biometric</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="373"/>
<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>Account locked,</source>
<translation></translation>
<source>Retry</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>hours left</source>
<translation></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>
<source>Details</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Password: </source>
<translation></translation>
</message>
<message>
<source>minutes left</source>
<translation></translation>
</message>
<message>
<source>Authentication failed, please try again.</source>
<translation> </translation>
<source>Device types:</source>
<translation type="obsolete"></translation>
</message>
<message>
<source>Vendor:</source>
<translation type="vanished"></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>seconds left</source>
<translation></translation>
<source>Action:</source>
<translation type="vanished"></translation>
</message>
<message>
<source>Password cannot be empty</source>
<translation></translation>
<source>Polkit.caller-pid:</source>
<translation type="vanished">Polkit.caller-pid</translation>
</message>
<message>
<source>use password</source>
<translation type="unfinished"></translation>
<location filename="../src/mainwindow.ui" line="334"/>
<location filename="../src/mainwindow.cpp" line="884"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="353"/>
<location filename="../src/mainwindow.cpp" line="880"/>
<source>Authenticate</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="886"/>
<location filename="../src/mainwindow.cpp" line="991"/>
<source>Use password</source>
<translation type="unfinished"></translation>
<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="1026"/>
<location filename="../src/mainwindow.cpp" line="1093"/>
<location filename="../src/mainwindow.cpp" line="1094"/>
<source>Please try again in %1 minutes.</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1036"/>
<location filename="../src/mainwindow.cpp" line="1103"/>
<location filename="../src/mainwindow.cpp" line="1104"/>
<source>Please try again in %1 seconds.</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1045"/>
<location filename="../src/mainwindow.cpp" line="1046"/>
<location filename="../src/mainwindow.cpp" line="1112"/>
<location filename="../src/mainwindow.cpp" line="1113"/>
<source>Account locked permanently.</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="675"/>
<location filename="../src/mainwindow.cpp" line="676"/>
<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="175"/>
<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="578"/>
<source>Password: </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="261"/>
<source>Please enter your password or enroll your fingerprint </source>
<translation> </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="187"/>
<source>Abnormal network</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="511"/>
<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="580"/>
<source>_Password: </source>
<translation>_Password </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="582"/>
<source>_Password:</source>
<translation>_Password</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="691"/>
<source>Authentication failed, please try again.</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="623"/>
<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="164"/>
<location filename="../src/mainwindow.cpp" line="1176"/>
<source>Failed to verify %1, please enter password to unlock</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="168"/>
<location filename="../src/mainwindow.cpp" line="1178"/>
<source>Unable to verify %1, please enter password to unlock</source>
<translation>%1 </translation>
</message>
<message>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Verify face recognition or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press fingerprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Verify voiceprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Verify finger vein or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Input Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Use the bound wechat scanning code or enter the password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="517"/>
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
<translation type="unfinished"></translation>
<translation> </translation>
</message>
<message>
<source>_Password:</source>
<translation type="unfinished"></translation>
<location filename="../src/mainwindow.cpp" line="576"/>
<source>Input Password</source>
<translation></translation>
</message>
<message>
<source>_Password: </source>
<translation type="unfinished"></translation>
<location filename="../src/mainwindow.cpp" line="627"/>
<source>hours left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="631"/>
<source>minutes left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="635"/>
<source>seconds left</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1193"/>
<source>Verify face recognition or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1198"/>
<source>Press fingerprint or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1203"/>
<source>Verify voiceprint or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1208"/>
<source>Verify finger vein or enter password to unlock</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1213"/>
<source>Verify iris or enter password to unlock</source>
<translation>iris </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1218"/>
<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="623"/>
<location filename="../src/mainwindow.cpp" line="627"/>
<location filename="../src/mainwindow.cpp" line="631"/>
<location filename="../src/mainwindow.cpp" line="635"/>
<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>
<source>Authentication failure, please try again.</source>
<translation> </translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="88"/>
<source>Another client is already authenticating, please try again later.</source>
<translation> </translation>
<translation> </translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="257"/>
<source>Authentication failure, please try again.</source>
<translation></translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="264"/>
<source>Password input error!</source>
<translation type="unfinished"></translation>
<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

@ -145,10 +145,6 @@
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
@ -181,6 +177,14 @@
<source>_Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>

View File

@ -145,10 +145,6 @@
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
@ -181,6 +177,14 @@
<source>_Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>

View File

@ -145,10 +145,6 @@
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
@ -181,6 +177,14 @@
<source>_Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>

View File

@ -145,10 +145,6 @@
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>NET Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
@ -181,6 +177,14 @@
<source>_Password: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PolkitListener</name>

View File

@ -34,131 +34,136 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../src/mainwindow.cpp" line="63"/>
<location filename="../src/mainwindow.cpp" line="65"/>
<source>Authentication</source>
<translation>Kimlik Doğrulama</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="161"/>
<location filename="../src/mainwindow.cpp" line="1111"/>
<location filename="../src/mainwindow.cpp" line="164"/>
<location filename="../src/mainwindow.cpp" line="1176"/>
<source>Failed to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="165"/>
<location filename="../src/mainwindow.cpp" line="1113"/>
<location filename="../src/mainwindow.cpp" line="168"/>
<location filename="../src/mainwindow.cpp" line="1178"/>
<source>Unable to verify %1, please enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="171"/>
<location filename="../src/mainwindow.cpp" line="175"/>
<source>Failed to verify %1, you still have %2 verification opportunities</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="183"/>
<source>NET Exception</source>
<location filename="../src/mainwindow.cpp" line="187"/>
<source>Abnormal network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="475"/>
<location filename="../src/mainwindow.cpp" line="511"/>
<source>This operation requires the administrator&apos;s authorization. Please enter your password to allow this operation.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="517"/>
<source>A program is attempting to perform an action that requires privileges.It requires authorization to perform the action.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="534"/>
<location filename="../src/mainwindow.cpp" line="576"/>
<source>Input Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="581"/>
<location filename="../src/mainwindow.cpp" line="585"/>
<location filename="../src/mainwindow.cpp" line="589"/>
<location filename="../src/mainwindow.cpp" line="593"/>
<location filename="../src/mainwindow.cpp" line="623"/>
<location filename="../src/mainwindow.cpp" line="627"/>
<location filename="../src/mainwindow.cpp" line="631"/>
<location filename="../src/mainwindow.cpp" line="635"/>
<source>Account locked,</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="581"/>
<location filename="../src/mainwindow.cpp" line="623"/>
<source>days left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="585"/>
<location filename="../src/mainwindow.cpp" line="627"/>
<source>hours left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="589"/>
<location filename="../src/mainwindow.cpp" line="631"/>
<source>minutes left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="593"/>
<location filename="../src/mainwindow.cpp" line="635"/>
<source>seconds left</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="633"/>
<location filename="../src/mainwindow.cpp" line="634"/>
<location filename="../src/mainwindow.cpp" line="675"/>
<location filename="../src/mainwindow.cpp" line="676"/>
<source>Password cannot be empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="840"/>
<location filename="../src/mainwindow.cpp" line="927"/>
<location filename="../src/mainwindow.cpp" line="886"/>
<location filename="../src/mainwindow.cpp" line="991"/>
<source>Use password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="962"/>
<location filename="../src/mainwindow.cpp" line="1029"/>
<location filename="../src/mainwindow.cpp" line="1030"/>
<location filename="../src/mainwindow.cpp" line="1026"/>
<location filename="../src/mainwindow.cpp" line="1093"/>
<location filename="../src/mainwindow.cpp" line="1094"/>
<source>Please try again in %1 minutes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="972"/>
<location filename="../src/mainwindow.cpp" line="1039"/>
<location filename="../src/mainwindow.cpp" line="1040"/>
<location filename="../src/mainwindow.cpp" line="1036"/>
<location filename="../src/mainwindow.cpp" line="1103"/>
<location filename="../src/mainwindow.cpp" line="1104"/>
<source>Please try again in %1 seconds.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="981"/>
<location filename="../src/mainwindow.cpp" line="982"/>
<location filename="../src/mainwindow.cpp" line="1048"/>
<location filename="../src/mainwindow.cpp" line="1049"/>
<location filename="../src/mainwindow.cpp" line="1045"/>
<location filename="../src/mainwindow.cpp" line="1046"/>
<location filename="../src/mainwindow.cpp" line="1112"/>
<location filename="../src/mainwindow.cpp" line="1113"/>
<source>Account locked permanently.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1127"/>
<location filename="../src/mainwindow.cpp" line="1193"/>
<source>Verify face recognition or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1132"/>
<location filename="../src/mainwindow.cpp" line="1198"/>
<source>Press fingerprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1137"/>
<location filename="../src/mainwindow.cpp" line="1203"/>
<source>Verify voiceprint or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1142"/>
<location filename="../src/mainwindow.cpp" line="1208"/>
<source>Verify finger vein or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1147"/>
<location filename="../src/mainwindow.cpp" line="1213"/>
<source>Verify iris or enter password to unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="1152"/>
<location filename="../src/mainwindow.cpp" line="1218"/>
<source>Use the bound wechat scanning code or enter the password to unlock</source>
<translation type="unfinished"></translation>
</message>
@ -180,9 +185,9 @@
<translation type="obsolete">Parola</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="299"/>
<location filename="../src/mainwindow.cpp" line="836"/>
<location filename="../src/mainwindow.cpp" line="893"/>
<location filename="../src/mainwindow.ui" line="302"/>
<location filename="../src/mainwindow.cpp" line="882"/>
<location filename="../src/mainwindow.cpp" line="948"/>
<source>Biometric</source>
<translation>Biyometrik</translation>
</message>
@ -231,19 +236,19 @@
<translation type="vanished">Polkit.caller-pid</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="331"/>
<location filename="../src/mainwindow.cpp" line="838"/>
<location filename="../src/mainwindow.ui" line="334"/>
<location filename="../src/mainwindow.cpp" line="884"/>
<source>Cancel</source>
<translation>İptal</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="350"/>
<location filename="../src/mainwindow.cpp" line="834"/>
<location filename="../src/mainwindow.ui" line="353"/>
<location filename="../src/mainwindow.cpp" line="880"/>
<source>Authenticate</source>
<translation>Kimlik Doğrulaması</translation>
</message>
<message>
<location filename="../src/mainwindow.ui" line="360"/>
<location filename="../src/mainwindow.ui" line="373"/>
<source>use password</source>
<translation type="unfinished"></translation>
</message>
@ -252,7 +257,7 @@
<translation type="obsolete">Kimlik Doğrulaması</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="247"/>
<location filename="../src/mainwindow.cpp" line="261"/>
<source>Please enter your password or enroll your fingerprint </source>
<translation type="unfinished"></translation>
</message>
@ -265,22 +270,22 @@
<translation type="vanished">Bir uygulama, ayrıcalıklar gerektiren bir eylem gerçekleştirmeye çalışıyor. Bu işlemi gerçekleştirmek için kimlik doğrulaması gerekiyor.</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="536"/>
<location filename="../src/mainwindow.cpp" line="578"/>
<source>Password: </source>
<translation type="unfinished">Parola </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="538"/>
<location filename="../src/mainwindow.cpp" line="580"/>
<source>_Password: </source>
<translation type="unfinished">_Parola </translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="540"/>
<location filename="../src/mainwindow.cpp" line="582"/>
<source>_Password:</source>
<translation type="unfinished">_Parola</translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="649"/>
<location filename="../src/mainwindow.cpp" line="691"/>
<source>Authentication failed, please try again.</source>
<translation>Kimlik doğrulama başarısız, lütfen tekrar deneyin.</translation>
</message>
@ -292,17 +297,17 @@
<context>
<name>PolkitListener</name>
<message>
<location filename="../src/PolkitListener.cpp" line="59"/>
<location filename="../src/PolkitListener.cpp" line="88"/>
<source>Another client is already authenticating, please try again later.</source>
<translation>Başka bir hesap zaten kimlik doğrulaması yapıyor, lütfen daha sonra tekrar deneyin.</translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="226"/>
<location filename="../src/PolkitListener.cpp" line="257"/>
<source>Authentication failure, please try again.</source>
<translation>Kimlik doğrulama hatalı, lütfen tekrar deneyin.</translation>
</message>
<message>
<location filename="../src/PolkitListener.cpp" line="233"/>
<location filename="../src/PolkitListener.cpp" line="264"/>
<source>Password input error!</source>
<translation type="unfinished"></translation>
</message>

View File

@ -240,7 +240,17 @@
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="538"/>
<location filename="../src/mainwindow.cpp" line="187"/>
<source>Abnormal network</source>
<translation></translation>
</message>
<message>
<location filename="../src/mainwindow.cpp" line="511"/>
<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="580"/>
<source>_Password: </source>
<translation> </translation>
</message>

View File

@ -73,6 +73,7 @@ int main(int argc, char *argv[])
BioDevices devices;
devices.setIsShowHotPlug(true);
devices.setUId(getuid());
agent.exec();
return EXIT_SUCCESS;
}

View File

@ -35,6 +35,7 @@
#include "PolkitListener.h"
#include "mainwindow.h"
#include "generic.h"
#include <libkysysinfo.h>
PolkitListener::PolkitListener(QObject *parent)
: Listener(parent),
@ -42,12 +43,40 @@ PolkitListener::PolkitListener(QObject *parent)
currentIdentity(0),
mainWindow(nullptr)
{
m_isSupportTableMode = isSupportTableMode();
m_isMavis = isMavis();
qDebug()<<"isSupportTableMode:"<<m_isSupportTableMode;
}
PolkitListener::~PolkitListener()
{
}
bool PolkitListener::isMavis()
{
char *prjName = kdk_system_get_projectName();
if (prjName) {
QString strFeature = QString(prjName);
free(prjName);
if (!strFeature.isEmpty()) {
if(strFeature == "V10SP1-edu"){
m_isSupportTableMode = true;
return true;
}
}
}
return false;
}
bool PolkitListener::isSupportTableMode()
{
unsigned int nFeature = kdk_system_get_productFeatures();
if (nFeature&0x02) { // 支持平板模式
return true;
}
return false;
}
/* initiateAuthentication message from polkit */
void PolkitListener::initiateAuthentication(
const QString &actionId, const QString &message,
@ -119,8 +148,10 @@ void PolkitListener::initiateAuthentication(
// XAtomHelper::getInstance()->setWindowMotifHint(mainWindow->winId(), hints);
mainWindow->setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint);
mainWindow->setIcon(iconName);
mainWindow->setCurProject(m_isMavis);
mainWindow->setHeader(message);
mainWindow->setUsers(usersList);
mainWindow->setEditInputMethod(m_isSupportTableMode);
/*
mainWindow->setDetails(subjectPid, callerPid,
actionDesc.actionId(),

View File

@ -32,6 +32,10 @@ public:
PolkitListener(QObject *parent = 0);
virtual ~PolkitListener();
private:
bool isSupportTableMode();
bool isMavis();
public slots:
void initiateAuthentication(const QString &actionId,
const QString &message,
@ -58,6 +62,8 @@ private:
QString cookie;
MainWindow *mainWindow;
bool unacknowledged_messages = false;
bool m_isSupportTableMode = false;
bool m_isMavis = false;
private slots:

View File

@ -0,0 +1,44 @@
#include "kalabel.h"
KALabel::KALabel(QWidget *parent)
: QLabel(parent)
{
m_strText = "";
}
KALabel::KALabel(QString strText, QWidget *parent)
: QLabel(strText, parent)
{
m_strText = strText;
}
void KALabel::setText(const QString &strText)
{
m_strText = strText;
QLabel::setText(strText);
}
void KALabel::paintEvent(QPaintEvent *event)
{
QString strEText = getElidedText(font(), width() ,m_strText);
if (strEText != m_strText) {
QLabel::setText(strEText);
setToolTip(m_strText);
} else {
QLabel::setText(m_strText);
setToolTip("");
}
QLabel::paintEvent(event);
}
QString KALabel::getElidedText(QFont font,int width,QString strInfo)
{
QFontMetrics fontMetrics(font);
//如果当前字体下,字符串长度大于指定宽度
if(fontMetrics.width(strInfo) > width)
{
strInfo= QFontMetrics(font).elidedText(strInfo, Qt::ElideRight, width);
}
return strInfo;
}

View File

@ -0,0 +1,23 @@
#ifndef KALABEL_H
#define KALABEL_H
#include <QLabel>
class KALabel : public QLabel
{
Q_OBJECT
public:
KALabel(QWidget *parent = nullptr);
KALabel(QString strText, QWidget *parent = nullptr);
QString getElidedText(QFont font,int width,QString strInfo);
public slots:
void setText(const QString &);
protected:
void paintEvent(QPaintEvent *event);
private:
QString m_strText;
};
#endif // KALABEL_H

View File

@ -35,6 +35,7 @@
#include <pwd.h>
#include <libintl.h>
#include <locale.h>
#include <QMatrix>
#include "bioauthwidget.h"
#include <QHBoxLayout>
#include <QAction>
@ -54,10 +55,10 @@ MainWindow::MainWindow(QWidget *parent) :
authMode(UNDEFINED),
useDoubleAuth(false),
m_timer(nullptr),
w_timer(nullptr),
isLockingFlg(false),
m_nCurLockMin(0),
isbioSuccess(false),
useFirstDevice(false)
isbioSuccess(false)
{
ui->setupUi(this);
setWindowTitle(tr("Authentication"));
@ -87,7 +88,7 @@ MainWindow::MainWindow(QWidget *parent) :
// headerLayout->addWidget(closeBtn);
// 登录选项
m_labelTip = new QLabel();
m_labelTip = new KALabel();
m_labelTip->setText("");
m_labelTip->hide();
m_loginOptsWidget = new LoginOptionsWidget();
@ -98,7 +99,6 @@ MainWindow::MainWindow(QWidget *parent) :
maxFailedTimes = bioDevices.getFailedTimes();
isHiddenSwitchButton = bioDevices.GetHiddenSwitchButton();
useFirstDevice = bioDevices.getUseFirstDevice();
connect(m_loginOptsWidget, &LoginOptionsWidget::optionSelected,
this, [&](unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo){
@ -143,7 +143,13 @@ MainWindow::MainWindow(QWidget *parent) :
emit switchToBiometric();
authMode = UNDEFINED;
} else {
if (nStatus >= 2) {
if (nStatus == 5 && m_deviceInfo) {
if(w_timer && w_timer->isActive())
w_timer->stop();
QImage imgFailed;
m_loginOptsWidget->setFaceImg(imgFailed, 2);
return;
} else if (nStatus >= 2 && nStatus != 5)if (nStatus >= 2) {
if (m_deviceInfo) {
uid_t curUid = getUid(userName);
if(m_failMap.contains(curUid) && m_failMap[curUid].contains(m_deviceInfo->device_id)){
@ -157,6 +163,7 @@ MainWindow::MainWindow(QWidget *parent) :
m_loginOptsWidget->setFaceImg(imgFailed, 1);
}
if(m_failMap[curUid][m_deviceInfo->device_id] >= maxFailedTimes){
no_changes = true;
if (m_deviceInfo->biotype == REMOTE_QRCODE_TYPE) {
setLoginTypeTip(tr("Failed to verify %1, please enter password to unlock").arg(BioDevices::bioTypeToString_tr(m_deviceInfo->biotype)));
QImage nullImage;
@ -168,6 +175,7 @@ MainWindow::MainWindow(QWidget *parent) :
useDoubleAuth = false;
return ;
}
no_changes = false;
setLoginTypeTip(tr("Failed to verify %1, you still have %2 verification opportunities")
.arg(BioDevices::bioTypeToString_tr(m_deviceInfo->biotype))
.arg(maxFailedTimes-m_failMap[curUid][m_deviceInfo->device_id]));
@ -180,7 +188,7 @@ MainWindow::MainWindow(QWidget *parent) :
}
if (m_uCurLoginOptType == LOGINOPT_TYPE_QRCODE && nStatus == 1) {
m_isNetworkErr = true;
m_loginOptsWidget->setQRCodeMsg(tr("NET Exception"));
m_loginOptsWidget->setQRCodeMsg(tr("Abnormal network"));
startBioAuth(10000);
} else {
startBioAuth();
@ -221,6 +229,16 @@ MainWindow::MainWindow(QWidget *parent) :
fontSize = settings->get("system-font-size").toInt();
connect(settings, &QGSettings::changed,
this, &MainWindow::onConfigurationChanged);
QDBusInterface *interfaceScreensaver = new QDBusInterface(
"org.ukui.ScreenSaver",
"/",
"org.ukui.ScreenSaver",
QDBusConnection::sessionBus());
connect(interfaceScreensaver, SIGNAL(lock()),
this, SLOT(onLockStatus()));
connect(interfaceScreensaver, SIGNAL(unlock()),
this, SLOT(onUnlockStatus()));
}
MainWindow::~MainWindow()
@ -337,6 +355,7 @@ void MainWindow::on_cmbUsers_currentTextChanged(const QString &userName)
m_deviceInfo = DeviceInfoPtr();
ui->lblMessage->clear();
ui->lblMessage->setToolTip("");
setMessage("");
isLockingFlg = false;
emit userChanged(this->userName);
}
@ -390,6 +409,19 @@ void MainWindow::on_btnAuth_clicked()
on_lePassword_returnPressed();
}
void MainWindow::onLockStatus()
{
//m_loginOptsWidget->stopAuth();
m_loginOptsWidget->lockStatusChanged(true);
}
void MainWindow::onUnlockStatus()
{
//m_loginOptsWidget->readDevicesInfo();
m_loginOptsWidget->lockStatusChanged(false);
startBioAuth();
}
/*** pagePassword ***/
void MainWindow::editIcon()
{
@ -414,6 +446,17 @@ void MainWindow::on_lePassword_returnPressed()
{
emit accept(ui->lePassword->text());
ui->btnAuth->hide();
ui->btnLoading->show();
if(!w_timer)
{
w_timer = new QTimer(this);
w_timer->setInterval(150);
connect(w_timer, &QTimer::timeout, this, &MainWindow::updatePixmap);
}
m_waitingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(24, 24);
ui->btnLoading->setIcon(QIcon(m_waitingPixmap));
w_timer->start();
// switchWidget(UNDEFINED);
// setMessage(tr("in authentication, please wait..."));
}
@ -469,7 +512,11 @@ void MainWindow::setIcon(const QString &iconName)
void MainWindow::setHeader(const QString &text)
{
ui->lblHeader->setText(text);
if(is_Mavis)
ui->lblHeader->setText(tr("This operation requires the administrator's authorization. "
"Please enter your password to allow this operation."));
else
ui->lblHeader->setText(text);
ui->lblHeader->adjustSize();
ui->lblHeader->height();
ui->lblContent->setText(tr("A program is attempting to perform an action that requires privileges."
@ -566,17 +613,17 @@ QString MainWindow::check_is_pam_message(QString text)
textdomain("Linux-PAM");
char* str;
QString strTrans = "";
QByteArray ba = text.toLatin1(); // must
QByteArray ba = text.toLocal8Bit(); // must
str=ba.data();
char l_str[1024];
int a,b;
//兼容旧版本翻译,以及适配新版本翻译
if(text.contains("attemps",Qt::CaseSensitive) && sscanf(str,"Authenticated failed, %d login attemps left",&a))
sprintf(str,_("Authenticated failed, %d login attemps left"),a);
snprintf(l_str,1024,_("Authenticated failed, %d login attemps left"),a);
else if(text.contains("attempts",Qt::CaseSensitive) && sscanf(str,"Authenticated failed, %d login attempts left",&a))
sprintf(str,_("Authenticated failed, %d login attempts left"),a);
snprintf(l_str,1024,_("Authenticated failed, %d login attempts left"),a);
else if(text.contains("attempt",Qt::CaseSensitive) && sscanf(str,"Authenticated failed, %d login attempt left",&a))
sprintf(str,_("Authenticated failed, %d login attempt left"),a);
snprintf(l_str,1024,_("Authenticated failed, %d login attempt left"),a);
else if(text.contains("days",Qt::CaseSensitive) && sscanf(str,"Account locked, %d days left",&a)){
strTrans = tr("Account locked,") + QString("%1 ").arg(a) + tr("days left");
return strTrans;
@ -594,12 +641,11 @@ QString MainWindow::check_is_pam_message(QString text)
return strTrans;
}
else{
str = _(str);
return _(str);
}
qDebug()<<"str = "<<str;
return QString(str);
qDebug()<<"l_str = "<<l_str;
return QString(l_str);
}
void MainWindow::setMessage(const QString &text,situation situat)
@ -609,8 +655,8 @@ void MainWindow::setMessage(const QString &text,situation situat)
QPalette pe;
pe.setColor(QPalette::WindowText,Qt::red);
ui->lblMessage->setPalette(pe);
ui->lePassword->setStyleSheet("QLineEdit{background-color: palette(Button);"
"lineedit-password-character:42;border-radius: 6px;border: 1px solid #F3222D;}");
// ui->lePassword->setStyleSheet("QLineEdit{background-color: palette(Button);"
// "border-radius: 6px;border: 1px solid #F3222D;}");
}else if(situat == TRUE){
QColor color = palette().color(QPalette::WindowText);
QPalette pal(this->palette());
@ -649,12 +695,14 @@ void MainWindow::setAuthResult(bool result, const QString &text)
message = tr("Authentication failed, please try again.");
}
if(authMode == PASSWORD)
if(authMode == PASSWORD) {
switchWidget(PASSWORD);
setMessage(message,ERROR);
}
else if(authMode == BIOMETRIC)
setMessage(message,ERROR);
switchWidget(PASSWORD);
}
void MainWindow::clearEdit()
@ -705,6 +753,7 @@ void MainWindow::switchAuthMode(Mode mode)
break;
case BIOMETRIC:
{
authMode = mode;
qDebug() << "switch to biometric";
if (m_deviceInfo) {
if (!m_loginOptsWidget->findDeviceById(m_deviceInfo->device_id)
@ -712,10 +761,10 @@ void MainWindow::switchAuthMode(Mode mode)
m_deviceInfo = DeviceInfoPtr();
}
}
if(authMode == PASSWORD) {
/*if(authMode == PASSWORD) {
emit accept(BIOMETRIC_IGNORE);
return;
}else if(!enableBioAuth){
}else */if(!enableBioAuth){
qDebug() << "It doesn't meet the condition for enabling biometric authentication, switch to password.";
emit accept(BIOMETRIC_IGNORE);
return;
@ -725,19 +774,13 @@ void MainWindow::switchAuthMode(Mode mode)
if(strDeviceName.isEmpty() && !m_deviceInfo)
{
qDebug() << "No default device";
if(useFirstDevice == true){
m_deviceInfo = m_loginOptsWidget->getFirstDevInfo();
} else {
emit accept(BIOMETRIC_IGNORE);
return;
}
emit accept(BIOMETRIC_IGNORE);
return;
}
//第一次,获取默认设备的设备信息,之后使用的则是从设备选择窗口传出的设备信息
if(!m_deviceInfo)
{
m_deviceInfo = m_loginOptsWidget->findDeviceByName(strDeviceName);
if (!m_deviceInfo)
m_deviceInfo = m_loginOptsWidget->getFirstDevInfo();
}
if(!m_deviceInfo){
emit accept(BIOMETRIC_IGNORE);
@ -751,7 +794,7 @@ void MainWindow::switchAuthMode(Mode mode)
startBioAuth();
emit accept(BIOMETRIC_IGNORE);
return;
} else if(authMode == UNDEFINED){
} /*else if(authMode == UNDEFINED){
authMode = BIOMETRIC;
if(enableBioAuth) {
@ -787,13 +830,13 @@ void MainWindow::switchAuthMode(Mode mode)
startBioAuth();
emit accept(BIOMETRIC_IGNORE);
return;
} else {
} else {*/
/* pass biometric's pam module if there are not available devices */
qDebug() << "It doesn't meet the condition for enabling biometric authentication, switch to password.";
emit accept(BIOMETRIC_IGNORE);
return;
}
}
// qDebug() << "It doesn't meet the condition for enabling biometric authentication, switch to password.";
// emit accept(BIOMETRIC_IGNORE);
// return;
// }
// }
}
break;
default:
@ -831,6 +874,7 @@ void MainWindow::switchWidget(Mode mode)
{
ui->widgetPasswdAuth->hide();
ui->btnAuth->hide();
ui->btnLoading->hide();
ui->btnAuth->setText(tr("Authenticate"));
ui->btnAuth->adjustSize();
ui->btnBioAuth->setText(tr("Biometric"));
@ -838,7 +882,14 @@ void MainWindow::switchWidget(Mode mode)
ui->btnCancel->setText(tr("Cancel"));
ui->btnCancel->adjustSize();
ui->returnButton->setText(tr("Use password"));
ui->btnLoading->setDisabled(true);
ui->returnButton->adjustSize();
if(is_Mavis){
ui->cmbUsers->setFixedHeight(48);
ui->lePassword->setFixedHeight(48);
ui->btnAuth->setFixedHeight(48);
ui->btnCancel->setFixedHeight(48);
}
switch(mode){
case PASSWORD:
{
@ -878,15 +929,17 @@ void MainWindow::switchWidget(Mode mode)
+ ui->cmbUsers->height() + ui->lePassword->height() + ui->lblMessage->height()
+ ui->btnAuth->height();
}
if (m_loginOptsWidget->isHidden()) {
height -= 20 ;
}
unsigned uOptsWidgetHeight = m_loginOptsWidget->height();
if (m_loginOptsWidget->isHidden()) {
uOptsWidgetHeight = 0;
height -= 20 ;
}
ui->lblContent->adjustSize();
ui->lblHeader->adjustSize();
setMinimumHeight(height + uOptsWidgetHeight);
setMaximumHeight(height + uOptsWidgetHeight);
setMinimumHeight(height + uOptsWidgetHeight + 10);
setMaximumHeight(height + uOptsWidgetHeight + 10);
//m_loginOptsWidget->updateUIStatus();
ui->btnBioAuth->setStyleSheet("QPushButton{font-size:14px;}QPushButton:hover{border:none;color:#3E6CE5;}QPushButton:pressed{border:none;}");
ui->btnBioAuth->setFlat(true);
@ -895,10 +948,19 @@ void MainWindow::switchWidget(Mode mode)
ui->btnBioAuth->adjustSize();
ui->widgetPasswdAuth->show();
ui->lePassword->setFocus();
ui->lePassword->setContextMenuPolicy(Qt::NoContextMenu); //禁用右键菜单
ui->lePassword->setAttribute(Qt::WA_InputMethodEnabled, false);
ui->lePassword->setEchoMode(QLineEdit::Password);
//ui->lePassword->setAttribute(Qt::WA_InputMethodEnabled, false);
if (m_modeButton && m_modeButton->isShowPwd()) {
ui->lePassword->setEchoMode(QLineEdit::Normal);
} else {
ui->lePassword->setEchoMode(QLineEdit::Password);
}
ui->btnAuth->show();
ui->btnLoading->hide();
ui->lePassword->setDisabled(false);
if(w_timer && w_timer->isActive())
{
w_timer->stop();
}
ui->btnCancel->show();
//ui->lblContent->show();
ui->returnButton->hide();
@ -909,11 +971,10 @@ void MainWindow::switchWidget(Mode mode)
case BIOMETRIC:
setMinimumWidth(420);
setMaximumWidth(420);
if(bioDevices.count()<1||bioDevices.count()==1){
if(m_loginOptsWidget->getLoginOptCount() <= 1){
setMinimumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height());
setMaximumHeight(392+ui->cmbUsers->height()+ui->lblHeader->height());
}
if(bioDevices.count()>1){
} else {
setMinimumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height());
setMaximumHeight(482+ui->cmbUsers->height()+ui->lblHeader->height());
}
@ -934,7 +995,7 @@ void MainWindow::switchWidget(Mode mode)
default:
break;
}
adjustSize();
// adjustSize();
}
void MainWindow::unlock_countdown()
@ -1107,6 +1168,7 @@ void MainWindow::switchLoginOptType(unsigned uLoginOptType)
QImage imgFailed;
m_loginOptsWidget->setFaceImg(imgFailed, 1);
}
no_changes = true;
if (m_deviceInfo->biotype == REMOTE_QRCODE_TYPE) {
setLoginTypeTip(tr("Failed to verify %1, please enter password to unlock").arg(BioDevices::bioTypeToString_tr(m_deviceInfo->biotype)));
} else {
@ -1114,6 +1176,7 @@ void MainWindow::switchLoginOptType(unsigned uLoginOptType)
}
m_loginOptsWidget->setDeviceDisable(m_deviceInfo->device_id, true);
} else {
no_changes = false;
if (uLoginOptType != m_uCurLoginOptType || (m_deviceInfo && m_deviceInfo->device_id != m_nLastDeviceId)) {
switch(uLoginOptType) {
case LOGINOPT_TYPE_PASSWORD:
@ -1171,22 +1234,21 @@ void MainWindow::setLoginTypeTip(QString strLoginTypeTip)
if (m_strLoginTypeTip.isEmpty()) {
m_labelTip->hide();
} else {
QFontMetrics font(m_labelTip->font());
//返回字符串末尾带省略号的字符串
QString strDisplay = font.elidedText(m_strLoginTypeTip, Qt::ElideRight, m_labelTip->width()-8);
QPalette pe;
pe.setColor(QPalette::WindowText,Qt::blue);
if(no_changes)
pe.setColor(QPalette::WindowText,Qt::red);
else
pe.setColor(QPalette::WindowText,QColor(55, 144, 250, 255));
m_labelTip->setPalette(pe);
m_labelTip->setText(strDisplay);
m_labelTip->setToolTip(m_strLoginTypeTip);
m_labelTip->setText(m_strLoginTypeTip);
m_labelTip->show();
}
}
void MainWindow::startBioAuthDelay()
{
m_loginOptsWidget->startAuth(m_deviceInfo, getUid(userName));
if (m_deviceInfo) {
m_loginOptsWidget->startAuth(m_deviceInfo, getUid(userName));
switchLoginOptType(m_loginOptsWidget->convertDeviceType(m_deviceInfo->biotype));
} else {
switchLoginOptType(LOGINOPT_TYPE_PASSWORD);
@ -1211,6 +1273,17 @@ void MainWindow::onUpdateBioAuthMsg(QString strMsg)
setMessage(strMsg, TRUE);
}
void MainWindow::updatePixmap()
{
ui->btnAuth->hide();
ui->btnLoading->show();
ui->lePassword->setDisabled(true);
QMatrix matrix;
matrix.rotate(90.0);
m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation);
ui->btnLoading->setIcon(m_waitingPixmap);
}
void MainWindow::onUpdateWndSize(unsigned uLoginOptType, unsigned uLoginOptSize)
{
ui->lblContent->hide();
@ -1230,7 +1303,7 @@ void MainWindow::onUpdateWndSize(unsigned uLoginOptType, unsigned uLoginOptSize)
uOptsWidgetHeight = m_loginOptsWidget->height() + 10 ;
}
// ui->lblContent->adjustSize();
ui->lblHeader->adjustSize();
// ui->lblHeader->adjustSize();
int height;
if(fontSize = 10){
height = 120 + ui->lblHeader->height() /*+ ui->lblContent->height()*/
@ -1264,4 +1337,19 @@ void MainWindow::onUpdateWndSize(unsigned uLoginOptType, unsigned uLoginOptSize)
setMaximumHeight(height + uOptsWidgetHeight);
}
void MainWindow::setEditInputMethod(bool bEnable)
{
qDebug()<<"setEditInputMethod:"<<bEnable;
if (bEnable) {
ui->lePassword->setAttribute(Qt::WA_InputMethodEnabled, true);
} else {
ui->lePassword->setAttribute(Qt::WA_InputMethodEnabled, false);
}
}
void MainWindow::setCurProject(bool isMavis)
{
is_Mavis = isMavis;
}
/*** end of private member ***/

View File

@ -30,6 +30,7 @@
#include "bioauthwidget.h"
#include "loginoptionswidget.h"
#include "modeButton.h"
#include "kalabel.h"
namespace Ui {
class MainWindow;
}
@ -61,6 +62,8 @@ public:
void stopDoubleAuth();
QString check_is_pam_message(QString text);
void switchLoginOptType(unsigned uLoginOptType);
void setEditInputMethod(bool bEnable);
void setCurProject(bool isMavis);
private:
uid_t getUid(const QString &userName);
@ -75,6 +78,8 @@ private:
void unlock_countdown();
void editIcon();
void setLoginTypeTip(QString strLoginTypeTip);
void setMavisSheel();
void updatePixmap();
public slots:
void onUpdateBioAuthMsg(QString strMsg);
@ -91,6 +96,8 @@ private slots:
void restart_bio_identify();
void startBioAuthDelay();
void onConfigurationChanged(QString key);
void onLockStatus();
void onUnlockStatus();
signals:
void accept(const QString &text);
@ -123,13 +130,12 @@ private:
bool isLockingFlg; //判断当前是否正在锁定倒计时
int m_nCurLockMin; //当前锁定的分钟数
// 登录选项
QLabel *m_labelTip = nullptr;
KALabel *m_labelTip = nullptr;
LoginOptionsWidget *m_loginOptsWidget = nullptr;
unsigned m_uCurLoginOptType = LOGINOPT_TYPE_PASSWORD; // 当前登录验证方式
QString m_strLoginTypeTip = "";
QTimer *m_bioTimer = nullptr;
DeviceInfoPtr m_deviceInfo = nullptr;
bool useFirstDevice;
bool m_isNetworkErr = false;
//标题栏
QHBoxLayout *headerLayout;
@ -142,6 +148,12 @@ private:
QString app_IconName;
int m_nLastDeviceId = -1;
bool no_changes = false;
bool is_Mavis = false;
QTimer *w_timer;
QPixmap m_waitingPixmap;
};
#endif // MAINWINDOW_H

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>459</width>
<height>419</height>
<height>432</height>
</rect>
</property>
<property name="sizePolicy">
@ -96,6 +96,9 @@
</item>
<item row="5" column="1">
<widget class="QComboBox" name="cmbUsers">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
@ -172,7 +175,7 @@
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="lblMessage">
<widget class="KALabel" name="lblMessage">
<property name="minimumSize">
<size>
<width>0</width>
@ -351,6 +354,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnLoading">
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="returnButton">
<property name="styleSheet">
@ -365,6 +378,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KALabel</class>
<extends>QLabel</extends>
<header>./src/kalabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -147,3 +147,8 @@ QPixmap ModeButton::drawSymbolicColoredPixmap(QPixmap &source, QString cgColor)
}
return QPixmap::fromImage(img);
}
bool ModeButton::isShowPwd()
{
return pwdShow;
}

View File

@ -17,6 +17,7 @@ public:
QPixmap drawSymbolicColoredPixmap(QPixmap &source, QString cgColor);
void initUI();
void setModeIcon();
bool isShowPwd();
protected:
bool eventFilter(QObject *obj, QEvent *event) override; //事件过滤

View File

@ -357,13 +357,19 @@ pam_modutil_read(int fd, char *buffer, int count)
void get_tally(uid_t uid, int *tfile, struct tallylog *tally)
{
char filename[50]={0};
sprintf(filename,"%s","/tmp/.tallylog");
char filename[50]={0};
sprintf(filename,"/tmp/.tallylog.d/.%d",uid);
fprintf(stderr,"new_filename = :%s \n",filename);
void *void_tally = tally;
void *void_tally = tally;
if ((*tfile = open(filename, O_RDONLY)) == -1){
fprintf(stderr, "open tallylog failed \n");
return ;
if ((*tfile = open(filename, O_RDONLY)) == -1){
fprintf(stderr, "lseek tallylog failed,Re-open the new file, uid = %d \n",uid);
sprintf(filename,"/tmp/.tallylog");
fprintf(stderr,"old_filename = :%s \n",filename);
if ((*tfile = open(filename, O_RDONLY)) == -1){
fprintf(stderr, "open tallylog failed \n");
return ;
}
}
if (lseek(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET) == (off_t)-1) {

View File

@ -0,0 +1,26 @@
project(uniauth-backend)
set(CMAKE_AUTOMOC ON)
include_directories(
${Qt5Core_INCLUDE_DIRS}
${Qt5DBus_INCLUDE_DIRS}
)
set(bin_SRCS
${bin_SRCS}
src/main.cpp
src/biodeviceinfo.h
src/biodeviceinfo.cpp
src/serviceinterface.h
src/serviceinterface.cpp
src/servicemanager.h
src/servicemanager.cpp
)
add_executable(uniauth-backend ${bin_SRCS})
target_link_libraries(uniauth-backend Qt5::Core Qt5::DBus)
install(TARGETS uniauth-backend DESTINATION bin)
install(FILES org.ukui.UniauthBackend.conf DESTINATION /etc/dbus-1/system.d/)
install(FILES org.ukui.UniauthBackend.service DESTINATION /usr/share/dbus-1/system-services/)

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root can own the service -->
<policy user="root">
<allow own="org.ukui.UniauthBackend"/>
<allow send_interface="org.ukui.UniauthBackend"/>
</policy>
<!-- Allow anyone to invoke methods on the interfaces -->
<policy context="default">
<allow send_destination="org.ukui.UniauthBackend"
send_interface="org.ukui.UniauthBackend"/>
<allow send_destination="org.ukui.UniauthBackend"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.ukui.UniauthBackend"
send_interface="org.freedesktop.DBus.Properties"/>
</policy>
</busconfig>

View File

@ -0,0 +1,4 @@
[D-BUS Service]
Name=org.ukui.UniauthBackend
Exec=/usr/bin/uniauth-backend
User=root

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include "biodeviceinfo.h"
void registerCustomTypes()
{
qDBusRegisterMetaType<DeviceInfo>();
qDBusRegisterMetaType<QList<QDBusVariant> >();
}
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo)
{
argument.beginStructure();
argument << deviceInfo.device_id << deviceInfo.device_shortname
<< deviceInfo.device_fullname << deviceInfo.driver_enable
<< deviceInfo.device_available
<< deviceInfo.biotype << deviceInfo.stotype
<< deviceInfo.eigtype << deviceInfo.vertype
<< deviceInfo.idtype << deviceInfo.bustype
<< deviceInfo.dev_status << deviceInfo.ops_status;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo)
{
argument.beginStructure();
argument >> deviceInfo.device_id >> deviceInfo.device_shortname
>> deviceInfo.device_fullname >> deviceInfo.driver_enable
>> deviceInfo.device_available
>> deviceInfo.biotype >> deviceInfo.stotype
>> deviceInfo.eigtype >> deviceInfo.vertype
>> deviceInfo.idtype >> deviceInfo.bustype
>> deviceInfo.dev_status >> deviceInfo.ops_status;
argument.endStructure();
return argument;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#ifndef BIODEVICEINFO_H
#define BIODEVICEINFO_H
#include <QDBusInterface>
#include <QDBusArgument>
#include <QDBusMetaType>
struct DeviceInfo {
int device_id;
QString device_shortname; /* aka driverName */
QString device_fullname;
int driver_enable; /* The corresponding driver is enabled/disabled */
int device_available; /* The driver is enabled and the device is connected */
int biotype;
int stotype;
int eigtype;
int vertype;
int idtype;
int bustype;
int dev_status;
int ops_status;
};
enum BioType {
BIOTYPE_FINGERPRINT,
BIOTYPE_FINGERVEIN,
BIOTYPE_IRIS,
BIOTYPE_FACE,
BIOTYPE_VOICEPRINT,
__MAX_NR_BIOTYPES
};
#define REMOTE_QRCODE_TYPE (8)
Q_DECLARE_METATYPE(DeviceInfo)
Q_DECLARE_METATYPE(QList<QDBusVariant>)
void registerCustomTypes();
QDBusArgument &operator<<(QDBusArgument &argument, const DeviceInfo &deviceInfo);
const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceInfo &deviceInfo);
#endif // BIODEVICEINFO_H

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include <QCoreApplication>
#include "serviceinterface.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ServiceInterface serviveInterface;
Q_UNUSED(serviveInterface);
return a.exec();
}

View File

@ -0,0 +1,766 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include "serviceinterface.h"
#include <QDBusConnection>
#include <QSettings>
#include <QDir>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <QFileSystemWatcher>
#include <QDebug>
#include <QProcess>
#include <QDBusPendingReply>
#include <QDBusMetaType>
#include <QDBusConnectionInterface>
#include <QDBusContext>
#include <QDBusMessage>
#include "servicemanager.h"
#define COMM_CONFIG_PATH "/etc/biometric-auth/ukui-biometric.conf"
#define USER_CONFIG_PATH "/home/%1/.biometric_auth/ukui_biometric.conf"
ServiceInterface::ServiceInterface()
{
bool res = QDBusConnection::systemBus().registerService("org.ukui.UniauthBackend");
if(!res){
qInfo()<<"registerService org.ukui.UniauthBackend failed!!";
exit(0);
}
res = QDBusConnection::systemBus().registerObject("/org/ukui/UniauthBackend", "org.ukui.UniauthBackend",
this, QDBusConnection::ExportAllSlots|QDBusConnection::ExportAllSignals);
if(!res){
qInfo()<<"registerObject /org/ukui/UniauthBackend failed!!";
exit(0);
}
registerCustomTypes();
m_serviceInterface = new QDBusInterface(DBUS_SERVICE, DBUS_PATH,
DBUS_INTERFACE,
QDBusConnection::systemBus());
m_serviceInterface->setTimeout(2147483647);
connect(m_serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)),
this, SLOT(onUSBDeviceHotPlug(int,int,int)));
updateCommDefaultDevice(-1);
initData();
ServiceManager *sm = ServiceManager::instance();
connect(sm, &ServiceManager::serviceStatusChanged,
this, &ServiceInterface::onBiometricDbusChanged);
}
void ServiceInterface::setDefaultDevice(QString userName, int bioDevType, QString deviceName)
{
QString configPath = QString(USER_CONFIG_PATH).arg(userName);
qDebug() << configPath << bioDevType ;
QSettings settings(configPath, QSettings::IniFormat);
switch (bioDevType) {
case BIOTYPE_FACE:
settings.setValue("FC_DefaultDevice", deviceName);
break;
case BIOTYPE_FINGERPRINT:
settings.setValue("FP_DefaultDevice", deviceName);
break;
case BIOTYPE_FINGERVEIN:
settings.setValue("FV_DefaultDevice", deviceName);
break;
case BIOTYPE_IRIS:
settings.setValue("IR_DefaultDevice", deviceName);
break;
case BIOTYPE_VOICEPRINT:
settings.setValue("VP_DefaultDevice", deviceName);
break;
case REMOTE_QRCODE_TYPE:
settings.setValue("WC_DefaultDevice", deviceName);
break;
default:
break;
}
settings.sync();
qDebug()<<"setDefaultDevice:"<<userName<<","<<bioDevType<<","<<deviceName;
emit defaultDeviceChanged(userName, bioDevType, deviceName);
}
void ServiceInterface::setDefaultDevice(int bioDevType, QString deviceName)
{
QDBusConnection conn = connection();
QDBusMessage msg = message();
int uid = conn.interface()->serviceUid(msg.service()).value();
struct passwd *pwinfo = getpwuid(uid);
if (pwinfo && pwinfo->pw_name) {
setDefaultDevice(pwinfo->pw_name, bioDevType, deviceName);
} else {
qInfo()<<"GetPWInfo failed!!";
}
}
QString ServiceInterface::getDefaultDevice(QString userName, int bioDevType)
{
QString defaultDevice = "";
QString configPath = QString(USER_CONFIG_PATH).arg(userName);
QSettings settings(configPath, QSettings::IniFormat);
// 获取用户旧的默认设备
if (settings.contains("DefaultDevice")) {
QString strOldDefDev = settings.value("DefaultDevice").toString();
if (!strOldDefDev.isEmpty()) {
for (auto devInfo : m_listDeviceInfos) {
if (devInfo && devInfo->device_shortname == strOldDefDev) {
QString strBioDefType = "";
switch(devInfo->biotype) {
case BIOTYPE_FINGERPRINT:
strBioDefType = "FP_DefaultDevice";
break;
case BIOTYPE_FINGERVEIN:
strBioDefType = "FV_DefaultDevice";
break;
case BIOTYPE_IRIS:
strBioDefType = "IR_DefaultDevice";
break;
case BIOTYPE_FACE:
strBioDefType = "FC_DefaultDevice";
break;
case BIOTYPE_VOICEPRINT:
strBioDefType = "VP_DefaultDevice";
break;
case REMOTE_QRCODE_TYPE:
strBioDefType = "WC_DefaultDevice";
break;
default:
break;
}
if (!strBioDefType.isEmpty() && !settings.contains(strBioDefType)) {
settings.setValue(strBioDefType, strOldDefDev);
settings.setValue("DefaultDevice", "");
settings.sync();
}
if (bioDevType == devInfo->biotype) {
return strOldDefDev;
}
break;
}
}
}
}
switch (bioDevType) {
case BIOTYPE_FACE:
defaultDevice = settings.value("FC_DefaultDevice").toString();
break;
case BIOTYPE_FINGERPRINT:
defaultDevice = settings.value("FP_DefaultDevice").toString();
break;
case BIOTYPE_FINGERVEIN:
defaultDevice = settings.value("FV_DefaultDevice").toString();
break;
case BIOTYPE_IRIS:
defaultDevice = settings.value("IR_DefaultDevice").toString();
break;
case BIOTYPE_VOICEPRINT:
defaultDevice = settings.value("VP_DefaultDevice").toString();
break;
case REMOTE_QRCODE_TYPE:
defaultDevice = settings.value("WC_DefaultDevice").toString();
break;
default:
defaultDevice = settings.value("DefaultDevice").toString();
break;
}
if(defaultDevice.isEmpty()) {
QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
switch (bioDevType) {
case BIOTYPE_FACE:
defaultDevice = settings2.value("FC_DefaultDevice").toString();
break;
case BIOTYPE_FINGERPRINT:
defaultDevice = settings2.value("FP_DefaultDevice").toString();
break;
case BIOTYPE_FINGERVEIN:
defaultDevice = settings2.value("FV_DefaultDevice").toString();
break;
case BIOTYPE_IRIS:
defaultDevice = settings2.value("IR_DefaultDevice").toString();
break;
case BIOTYPE_VOICEPRINT:
defaultDevice = settings2.value("VP_DefaultDevice").toString();
break;
case REMOTE_QRCODE_TYPE:
defaultDevice = settings2.value("WC_DefaultDevice").toString();
break;
default:
defaultDevice = settings2.value("DefaultDevice").toString();
break;
}
}
return defaultDevice;
}
QStringList ServiceInterface::getAllDefaultDevice(QString userName)
{
QStringList listDefDevice;
QString configPath = QString(USER_CONFIG_PATH).arg(userName);
QSettings settings(configPath, QSettings::IniFormat);
int nOldDefType = -1;
// 获取用户旧的默认设备
if (settings.contains("DefaultDevice")) {
QString strOldDefDev = settings.value("DefaultDevice").toString();
if (!strOldDefDev.isEmpty()) {
for (auto devInfo : m_listDeviceInfos) {
if (devInfo && devInfo->device_shortname == strOldDefDev) {
QString strBioDefType = "";
switch(devInfo->biotype) {
case BIOTYPE_FINGERPRINT:
strBioDefType = "FP_DefaultDevice";
break;
case BIOTYPE_FINGERVEIN:
strBioDefType = "FV_DefaultDevice";
break;
case BIOTYPE_IRIS:
strBioDefType = "IR_DefaultDevice";
break;
case BIOTYPE_FACE:
strBioDefType = "FC_DefaultDevice";
break;
case BIOTYPE_VOICEPRINT:
strBioDefType = "VP_DefaultDevice";
break;
case REMOTE_QRCODE_TYPE:
strBioDefType = "WC_DefaultDevice";
break;
default:
break;
}
if (!strBioDefType.isEmpty() && !settings.contains(strBioDefType)) {
nOldDefType = devInfo->biotype;
listDefDevice.push_back(strOldDefDev);
settings.setValue(strBioDefType, strOldDefDev);
settings.setValue("DefaultDevice", "");
settings.sync();
}
break;
}
}
}
}
QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
for (int nBioType = 0; nBioType <= REMOTE_QRCODE_TYPE; nBioType++) {
QString defaultDevice = "";
if (nBioType == nOldDefType)
continue;
switch (nBioType) {
case BIOTYPE_FACE:
defaultDevice = settings.value("FC_DefaultDevice").toString();
break;
case BIOTYPE_FINGERPRINT:
defaultDevice = settings.value("FP_DefaultDevice").toString();
break;
case BIOTYPE_FINGERVEIN:
defaultDevice = settings.value("FV_DefaultDevice").toString();
break;
case BIOTYPE_IRIS:
defaultDevice = settings.value("IR_DefaultDevice").toString();
break;
case BIOTYPE_VOICEPRINT:
defaultDevice = settings.value("VP_DefaultDevice").toString();
break;
case REMOTE_QRCODE_TYPE:
defaultDevice = settings.value("WC_DefaultDevice").toString();
break;
default:
break;
}
if(defaultDevice.isEmpty()) {
switch (nBioType) {
case BIOTYPE_FACE:
defaultDevice = settings2.value("FC_DefaultDevice").toString();
break;
case BIOTYPE_FINGERPRINT:
defaultDevice = settings2.value("FP_DefaultDevice").toString();
break;
case BIOTYPE_FINGERVEIN:
defaultDevice = settings2.value("FV_DefaultDevice").toString();
break;
case BIOTYPE_IRIS:
defaultDevice = settings2.value("IR_DefaultDevice").toString();
break;
case BIOTYPE_VOICEPRINT:
defaultDevice = settings2.value("VP_DefaultDevice").toString();
break;
case REMOTE_QRCODE_TYPE:
defaultDevice = settings2.value("WC_DefaultDevice").toString();
break;
default:
break;
}
}
if (!defaultDevice.isEmpty()) {
listDefDevice.push_back(defaultDevice);
}
}
return listDefDevice;
}
//设置通用默认设备
void ServiceInterface::setCommDefaultDevice(int bioDevType, QString deviceName)
{
QSettings settings(COMM_CONFIG_PATH, QSettings::IniFormat);
switch (bioDevType) {
case BIOTYPE_FACE:
settings.setValue("FC_DefaultDevice", deviceName);
break;
case BIOTYPE_FINGERPRINT:
settings.setValue("FP_DefaultDevice", deviceName);
break;
case BIOTYPE_FINGERVEIN:
settings.setValue("FV_DefaultDevice", deviceName);
break;
case BIOTYPE_IRIS:
settings.setValue("IR_DefaultDevice", deviceName);
break;
case BIOTYPE_VOICEPRINT:
settings.setValue("VP_DefaultDevice", deviceName);
break;
case REMOTE_QRCODE_TYPE:
settings.setValue("WC_DefaultDevice", deviceName);
break;
default:
break;
}
settings.sync();
qDebug()<<"setCommDefaultDevice:"<<bioDevType<<","<<deviceName;
emit defaultDeviceChanged("", bioDevType, deviceName);
}
//获取通用默认设备
QString ServiceInterface::getCommDefaultDevice(int bioDevType)
{
QString defaultDevice = "";
QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
switch (bioDevType) {
case BIOTYPE_FACE:
defaultDevice = settings2.value("FC_DefaultDevice").toString();
break;
case BIOTYPE_FINGERPRINT:
defaultDevice = settings2.value("FP_DefaultDevice").toString();
break;
case BIOTYPE_FINGERVEIN:
defaultDevice = settings2.value("FV_DefaultDevice").toString();
break;
case BIOTYPE_IRIS:
defaultDevice = settings2.value("IR_DefaultDevice").toString();
break;
case BIOTYPE_VOICEPRINT:
defaultDevice = settings2.value("VP_DefaultDevice").toString();
break;
case REMOTE_QRCODE_TYPE:
defaultDevice = settings2.value("WC_DefaultDevice").toString();
break;
default:
defaultDevice = settings2.value("DefaultDevice").toString();
break;
}
return defaultDevice;
}
void ServiceInterface::setBioAuthStatus(int bioAuthType, bool status)
{
QDBusConnection conn = connection();
QDBusMessage msg = message();
int uid = conn.interface()->serviceUid(msg.service()).value();
struct passwd *pwinfo = getpwuid(uid);
if (pwinfo && pwinfo->pw_name) {
QString configPath = QString(USER_CONFIG_PATH).arg(pwinfo->pw_name);
QSettings settings(configPath, QSettings::IniFormat);
switch (bioAuthType) {
case ENABLETYPE_BIO:
settings.setValue("EnableAuth", status);
break;
case ENABLETYPE_SAVER:
settings.setValue("SaverEnable", status);
break;
case ENABLETYPE_GREETER:
settings.setValue("GreeterEnable", status);
break;
case ENABLETYPE_POLKIT:
settings.setValue("PolkitEnable", status);
break;
case ENABLETYPE_SU:
settings.setValue("SuEnable", status);
break;
case ENABLETYPE_SUDO:
settings.setValue("SudoEnable", status);
break;
case ENABLETYPE_LOGIN:
settings.setValue("LoginEnable", status);
break;
default:
break;
}
settings.sync();
emit bioAuthStatusChanged(pwinfo->pw_name, bioAuthType, status);
qDebug()<<"setBioAuthStatus:"<<pwinfo->pw_name<<","<<bioAuthType<<","<<status;
} else {
qInfo()<<"GetPWInfo failed!!";
}
}
bool ServiceInterface::getBioAuthStatus(QString userName, int bioAuthType)
{
QString configPath = QString(USER_CONFIG_PATH).arg(userName);
QSettings settings(configPath, QSettings::IniFormat);
QString strBioAuthType = "";
switch (bioAuthType) {
case ENABLETYPE_BIO:
strBioAuthType = "EnableAuth";
break;
case ENABLETYPE_SAVER:
strBioAuthType = "SaverEnable";
break;
case ENABLETYPE_GREETER:
strBioAuthType = "GreeterEnable";
break;
case ENABLETYPE_POLKIT:
strBioAuthType = "PolkitEnable";
break;
case ENABLETYPE_SU:
strBioAuthType = "SuEnable";
break;
case ENABLETYPE_SUDO:
strBioAuthType = "SudoEnable";
break;
case ENABLETYPE_LOGIN:
strBioAuthType = "LoginEnable";
break;
default:
return false;
}
if (settings.contains(strBioAuthType)) {
return settings.value(strBioAuthType).toBool();
} else {
QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
if (settings2.contains(strBioAuthType)) {
return settings2.value(strBioAuthType).toBool();
} else {
return true;
}
}
}
int ServiceInterface::getMaxFailedTimes()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("MaxFailedTimes"))
return sysSettings.value("MaxFailedTimes").toInt();
else
return 3;
}
bool ServiceInterface::getQRCodeEnable()
{
bool isEnable = false;
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
sysSettings.beginGroup("Functions");
if (sysSettings.allKeys().contains("EnableQRCode")) {
isEnable = sysSettings.value("EnableQRCode").toBool();
}
sysSettings.endGroup();
return isEnable;
}
// 获取是否双认证
bool ServiceInterface::getDoubleAuth()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("DoubleAuth"))
return sysSettings.value("DoubleAuth").toBool();
else
return false;
}
// 获取用户绑定
bool ServiceInterface::getUserBind()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("UserBind"))
return sysSettings.value("UserBind").toBool();
else
return false;
}
// 获取是否在控制面板显示
bool ServiceInterface::getIsShownInControlCenter()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("isShownInControlCenter"))
return sysSettings.value("isShownInControlCenter").toBool();
else
return false;
}
// 获取是否使用第一个设备
bool ServiceInterface::getUseFirstDevice()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("UseFirstDevice"))
return sysSettings.value("UseFirstDevice").toBool();
else
return false;
}
// 获取是否隐藏切换按钮
bool ServiceInterface::getHiddenSwitchButton()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("HiddenSwitchButton"))
return sysSettings.value("HiddenSwitchButton").toBool();
else
return false;
}
// 获取旧版app使能值
int ServiceInterface::getOldAppStatus()
{
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("EnableAuthApp"))
return sysSettings.value("EnableAuthApp").toInt();
else
return 63;
}
void ServiceInterface::onUSBDeviceHotPlug(int drvid, int action, int deviceNum)
{
if (action > 0) {
qDebug()<<"onUSBDeviceHotPlug in:"<<drvid;
updateCommDefaultDevice(drvid);
}
}
void ServiceInterface::waitBiometricServiceStatus()
{
qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` get biometric status";
QDBusInterface iface("org.freedesktop.systemd1", "/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",QDBusConnection::systemBus());
QDBusReply<QDBusObjectPath> bioPath = iface.call("GetUnit","biometric-authentication.service");
if(!bioPath.isValid()){
return ;
}
QDBusInterface bioface("org.freedesktop.systemd1", bioPath.value().path(),
"org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
QDBusReply<QDBusVariant> sessionReply = bioface.call("Get", "org.freedesktop.systemd1.Unit", "UnitFileState");
if(!sessionReply.isValid())
qWarning() << sessionReply.error();
else {
QString res = sessionReply.value().variant().toString();
if(res == "disable")
return;
}
qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ get activeState";
int times = 0;
while(times<20){
QDBusReply<QDBusVariant> sessionReply = bioface.call("Get", "org.freedesktop.systemd1.Unit", "ActiveState");
if(!sessionReply.isValid()){
qWarning() << sessionReply.error();
return ;
}
else {
QString res = sessionReply.value().variant().toString();
if(res == "activating"){
times ++;
usleep(100000);
}else{
break;
}
}
}
qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ times = "<<times;
}
void ServiceInterface::updateCommDefaultDevice(int nDriId)
{
if (!m_serviceInterface) {
return ;
}
QVariant variant;
QDBusArgument argument;
QList<QDBusVariant> qlist;
QDBusVariant item;
DeviceInfo *deviceInfo;
/* 返回值为 i -- int 和 av -- array of variant */
QDBusPendingReply<int, QList<QDBusVariant> > reply = m_serviceInterface->call("GetDrvList");
reply.waitForFinished();
if (reply.isError()) {
qDebug() << "GUI:" << reply.error();
deviceCount = 0;
return;
}
/* 解析 DBus 返回值reply 有两个返回值,都是 QVariant 类型 */
variant = reply.argumentAt(0); /* 得到第一个返回值 */
deviceCount = variant.value<int>(); /* 解封装得到设备个数 */
variant = reply.argumentAt(1); /* 得到第二个返回值 */
argument = variant.value<QDBusArgument>(); /* 解封装获取QDBusArgument对象 */
argument >> qlist; /* 使用运算符重载提取 argument 对象里面存储的列表对象 */
if (nDriId != -1) { // 指定设备接入
for (int i = 0; i < deviceCount; i++) {
item = qlist[i]; /* 取出一个元素 */
variant = item.variant(); /* 转为普通QVariant对象 */
/* 解封装得到 QDBusArgument 对象 */
argument = variant.value<QDBusArgument>();
deviceInfo = new DeviceInfo();
argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
if (nDriId == deviceInfo->device_id) {
if (getCommDefaultDevice(deviceInfo->biotype).isEmpty()) {
setCommDefaultDevice(deviceInfo->biotype, deviceInfo->device_shortname);
}
break;
}
}
} 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();
argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
m_listDeviceInfos.push_back(deviceInfo);
}
}
}
void ServiceInterface::initData()
{
// 沿用旧app enable
QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
if(sysSettings.contains("EnableAuthApp") || sysSettings.contains("Functions/EnableAuthApp")) {
int nAppOldStatus = 0;
if (sysSettings.contains("Functions/EnableAuthApp")) {
nAppOldStatus = sysSettings.value("Functions/EnableAuthApp").toInt();
} else {
nAppOldStatus = sysSettings.value("EnableAuthApp").toInt();
}
if ((nAppOldStatus&0x01) && !sysSettings.contains("GreeterEnable")) { // greeter
sysSettings.setValue("GreeterEnable", true);
}
if ((nAppOldStatus&0x02) && !sysSettings.contains("SaverEnable")) { // saver
sysSettings.setValue("SaverEnable", true);
}
if ((nAppOldStatus&0x04) && !sysSettings.contains("PolkitEnable")) { // polkit
sysSettings.setValue("PolkitEnable", true);
}
if ((nAppOldStatus&0x08) && !sysSettings.contains("SudoEnable")) { // sudo
sysSettings.setValue("SudoEnable", true);
}
if ((nAppOldStatus&0x10) && !sysSettings.contains("SuEnable")) { // su
sysSettings.setValue("SuEnable", true);
}
if ((nAppOldStatus&0x20) && !sysSettings.contains("LoginEnable")) { // login
sysSettings.setValue("LoginEnable", true);
}
}
// 沿用旧的默认设备
if(sysSettings.contains("DefaultDevice")) {
QString strOldDefDev = sysSettings.value("DefaultDevice").toString();
if (!strOldDefDev.isEmpty()) {
for (auto devInfo : m_listDeviceInfos) {
if (devInfo && devInfo->device_shortname == strOldDefDev) {
QString strBioDefType = "";
switch(devInfo->biotype) {
case BIOTYPE_FINGERPRINT:
strBioDefType = "FP_DefaultDevice";
break;
case BIOTYPE_FINGERVEIN:
strBioDefType = "FV_DefaultDevice";
break;
case BIOTYPE_IRIS:
strBioDefType = "IR_DefaultDevice";
break;
case BIOTYPE_FACE:
strBioDefType = "FC_DefaultDevice";
break;
case BIOTYPE_VOICEPRINT:
strBioDefType = "VP_DefaultDevice";
break;
case REMOTE_QRCODE_TYPE:
strBioDefType = "WC_DefaultDevice";
break;
default:
break;
}
if (!strBioDefType.isEmpty() && !sysSettings.contains(strBioDefType)) {
sysSettings.setValue(strBioDefType, strOldDefDev);
sysSettings.setValue("DefaultDevice", "");
}
break;
}
}
}
}
// 设置未设置过默认设备的类型,如果驱动已打开且已连接
for (auto devInfo : m_listDeviceInfos) {
if (devInfo && devInfo->device_available > 0 && devInfo->driver_enable > 0) {
QString strBioDefType = "";
switch(devInfo->biotype) {
case BIOTYPE_FINGERPRINT:
strBioDefType = "FP_DefaultDevice";
break;
case BIOTYPE_FINGERVEIN:
strBioDefType = "FV_DefaultDevice";
break;
case BIOTYPE_IRIS:
strBioDefType = "IR_DefaultDevice";
break;
case BIOTYPE_FACE:
strBioDefType = "FC_DefaultDevice";
break;
case BIOTYPE_VOICEPRINT:
strBioDefType = "VP_DefaultDevice";
break;
case REMOTE_QRCODE_TYPE:
strBioDefType = "WC_DefaultDevice";
break;
default:
break;
}
if (!strBioDefType.isEmpty() && !sysSettings.contains(strBioDefType)) {
sysSettings.setValue(strBioDefType, devInfo->device_shortname);
}
}
}
sysSettings.sync();
}
void ServiceInterface::onBiometricDbusChanged(bool bActive)
{
qDebug()<<"BiometricDbus:"<<bActive;
if (bActive) {
updateCommDefaultDevice(-1);
initData();
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#ifndef SERVICEINTERFACE_H
#define SERVICEINTERFACE_H
#include "biodeviceinfo.h"
#include <QCoreApplication>
#include <QDBusContext>
#include <QObject>
#include <QFileSystemWatcher>
#define DBUS_SERVICE "org.ukui.Biometric"
#define DBUS_PATH "/org/ukui/Biometric"
#define DBUS_INTERFACE "org.ukui.Biometric"
enum authEnableType {
ENABLETYPE_BIO, // 全局总使能
ENABLETYPE_SAVER, // 锁屏
ENABLETYPE_GREETER, // 登录
ENABLETYPE_POLKIT, // 授权
ENABLETYPE_SU, // 暂保留
ENABLETYPE_SUDO, // 暂保留
ENABLETYPE_LOGIN, // 暂保留
};
class ServiceInterface : public QObject, protected QDBusContext
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.ukui.UniauthBackend")
public:
ServiceInterface();
public slots:
// 设置默认设备
void setDefaultDevice(int bioDevType, QString deviceName);
// 获取默认设备
QString getDefaultDevice(QString userName, int bioDevType);
// 获取所有默认设备
QStringList getAllDefaultDevice(QString userName);
//生物特征开关接口
bool getBioAuthStatus(QString userName, int bioAuthType);
void setBioAuthStatus(int bioAuthType, bool status);
// 获取最大失败次数
int getMaxFailedTimes();
// 获取是否使能微信扫码登录
bool getQRCodeEnable();
// 获取是否双认证
bool getDoubleAuth();
// 获取用户绑定
bool getUserBind();
// 获取是否在控制面板显示
bool getIsShownInControlCenter();
// 获取是否使用第一个设备
bool getUseFirstDevice();
// 获取是否隐藏切换按钮
bool getHiddenSwitchButton();
private slots:
void onUSBDeviceHotPlug(int drvid, int action, int deviceNum);
void onBiometricDbusChanged(bool bActive);
signals:
//默认设备改变
void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName);
//开关状态改变
void bioAuthStatusChanged(QString userName, int type, bool status);
private:
//设置默认设备
void setDefaultDevice(QString userName, int bioDevType, QString deviceName);
//设置通用默认设备
void setCommDefaultDevice(int bioDevType, QString deviceName);
//获取通用默认设备
QString getCommDefaultDevice(int bioDevType);
// 获取旧版app使能值
int getOldAppStatus();
// 初始化数据
void initData();
// 更新通用默认设备
void updateCommDefaultDevice(int nDriId);
// 等待生物识别服务
void waitBiometricServiceStatus();
private:
QDBusInterface *m_serviceInterface = nullptr;
QList<DeviceInfo *> m_listDeviceInfos;
int deviceCount = 0;
};
#endif // SERVICEINTERFACE_H

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include "servicemanager.h"
#include <QDebug>
#include <QDBusReply>
#define SERVICE "biometric-authentication.service"
#define DBUS_SERVICE "org.ukui.Biometric"
#define DBUS_PATH "/org/ukui/Biometric"
#define DBUS_INTERFACE "org.ukui.Biometric"
#define FD_DBUS_SERVICE "org.freedesktop.DBus"
#define FD_DBUS_PATH "/org/freedesktop/DBus"
#define FD_DBUS_INTERFACE "org.freedesktop.DBus"
ServiceManager *ServiceManager::instance_ = nullptr;
ServiceManager::ServiceManager(QObject *parent)
: QObject(parent),
dbusService(nullptr),
bioService(nullptr)
{
init();
}
void ServiceManager::init()
{
if(!dbusService)
{
dbusService = new QDBusInterface(FD_DBUS_SERVICE,
FD_DBUS_PATH,
FD_DBUS_INTERFACE,
QDBusConnection::systemBus());
connect(dbusService, SIGNAL(NameOwnerChanged(QString, QString, QString)),
this, SLOT(onDBusNameOwnerChanged(QString,QString,QString)));
}
}
ServiceManager *ServiceManager::instance()
{
if(!instance_)
{
instance_ = new ServiceManager;
}
return instance_;
}
bool ServiceManager::connectToService()
{
if(!bioService)
{
bioService = new QDBusInterface(DBUS_SERVICE,
DBUS_PATH,
DBUS_INTERFACE,
QDBusConnection::systemBus());
}
return bioService->isValid();
}
void ServiceManager::onDBusNameOwnerChanged(const QString &name,
const QString &oldOwner,
const QString &newOwner)
{
if(name == DBUS_SERVICE)
{
qDebug() << "service status changed:"
<< (newOwner.isEmpty() ? "inactivate" : "activate");
Q_EMIT serviceStatusChanged(!newOwner.isEmpty());
}
}
/*!
* \brief checkServiceExist
*
*/
bool ServiceManager::serviceExists()
{
QDBusReply<bool> reply = dbusService->call("NameHasOwner", DBUS_SERVICE);
if(!reply.isValid())
{
qDebug() << "check service exists error:" << reply.error();
return false;
}
return reply.value();
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#ifndef SERVICEMANAGER_H
#define SERVICEMANAGER_H
#include <QObject>
#include <QDBusInterface>
class ServiceManager : public QObject
{
Q_OBJECT
public:
static ServiceManager *instance();
bool serviceExists();
private:
explicit ServiceManager(QObject *parent = nullptr);
void init();
bool connectToService();
Q_SIGNALS:
void serviceStatusChanged(bool activate);
public Q_SLOTS:
void onDBusNameOwnerChanged(const QString &name,
const QString &oldOwner,
const QString &newOwner);
private:
static ServiceManager *instance_;
QDBusInterface *dbusService;
QDBusInterface *bioService;
bool serviceStatus;
};
#endif // SERVICEMANAGER_H