Changes of Revision 2
[-] [+] | Changed | _service:tar_git:sailfish-fpd-community.spec |
[-] [+] | Changed | _service:tar_git:sailfish-fpd-community-1.0.0.tar.bz2/src/androidfp.cpp ^ |
@@ -1,7 +1,11 @@ #include "androidfp.h" #include "util/property_store.h" + #include <QDebug> +#include <limits.h> +#include <cstring> + std::string IntToStringFingerprintError(int error, int vendorCode){ switch(error) { case ERROR_NO_ERROR: return "ERROR_NO_ERROR"; @@ -40,18 +44,6 @@ AndroidFP::AndroidFP(QObject *parent) : QObject(parent), m_biometry(u_hardware_biometry_new()) { - util::AndroidPropertyStore store; - UHardwareBiometryRequestStatus ret = SYS_OK; - std::string api_level = store.get("ro.product.first_api_level"); - if (api_level.empty()) - api_level = store.get("ro.build.version.sdk"); - if (atoi(api_level.c_str()) <= 27) - ret = u_hardware_biometry_setActiveGroup(m_biometry, 0, (char*)"/data/system/users/0/fpdata/"); - else - ret = u_hardware_biometry_setActiveGroup(m_biometry, 0, (char*)"/data/vendor_de/0/fpdata/"); - if (ret != SYS_OK) - printf("setActiveGroup failed: %s\n", IntToStringRequestStatus(ret).c_str()); - //Set up the callbacks fp_params.enrollresult_cb = enrollresult_cb; fp_params.acquired_cb = acquired_cb; @@ -63,6 +55,43 @@ u_hardware_biometry_setNotify(m_biometry, &fp_params); } +QString AndroidFP::getDefaultGroupPath(uint32_t uid) +{ + util::AndroidPropertyStore store; + std::string api_level = store.get("ro.product.first_api_level"); + if (api_level.empty()) { + api_level = store.get("ro.build.version.sdk"); + } + if (atoi(api_level.c_str()) <= 27) { + return QStringLiteral("/data/system/users/%1/fpdata").arg(uid); + } + return QStringLiteral("/data/vendor_de/%1/fpdata").arg(uid); +} + +void AndroidFP::setGroup(uint32_t gid, const QString &storePath) +{ + qDebug() << Q_FUNC_INFO << gid << storePath; + UHardwareBiometryRequestStatus ret = SYS_OK; + char path[PATH_MAX]; + + if (storePath.isEmpty()) { + qWarning() << "Cannot set empty active group path"; + failed(QStringLiteral("Cannot set empty active group path")); + return; + } + + std::strncpy(path, storePath.toLocal8Bit().data(), sizeof(path)); + path[ sizeof(path)-1 ] = 0; + ret = u_hardware_biometry_setActiveGroup(m_biometry, gid, path); + + if (ret != SYS_OK) { + qWarning() << "setActiveGroup failed: " << IntToStringRequestStatus(ret).c_str(); + failed(QStringLiteral("setActiveGroup failed: %1").arg(IntToStringRequestStatus(ret).c_str())); + } else { + qInfo() << "setActiveGroup to" << path; + } +} + void AndroidFP::enroll(uid_t user_id) { qDebug() << Q_FUNC_INFO << user_id; | ||
[-] [+] | Changed | _service:tar_git:sailfish-fpd-community-1.0.0.tar.bz2/src/androidfp.h ^ |
@@ -3,6 +3,7 @@ #include <QObject> #include <QList> +#include <QString> #include "biometry.h" @@ -11,6 +12,7 @@ Q_OBJECT public: explicit AndroidFP(QObject *parent = nullptr); + void setGroup(uint32_t gid, const QString &storePath); void enroll(uid_t user_id); void remove(uid_t finger); void cancel(); @@ -19,6 +21,8 @@ void clear(); QList<uint32_t> fingerprints() const; + static QString getDefaultGroupPath(uint32_t uid); + signals: void failed(const QString& message); void succeeded(uint32_t fingerId); //After enrollment | ||
[-] [+] | Changed | _service:tar_git:sailfish-fpd-community-1.0.0.tar.bz2/src/fpdcommunity.cpp ^ |
@@ -7,6 +7,12 @@ #include <QDir> #include <QDataStream> #include <QFile> + +#include <unistd.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> + #define FINGERPRINT_PATH "/var/lib/sailfish-fpd-community/" #define FINGERPRINT_FILE "fingerprints.db" @@ -27,13 +33,8 @@ m_cancelTimer.setInterval(30000); connect(&m_cancelTimer, &QTimer::timeout, this, &FPDCommunity::slot_cancelIdentify); - //Create folder to store fingerprint names - if (!(QDir().mkpath(FINGERPRINT_PATH))) { - qWarning() << "Unable to create " << FINGERPRINT_PATH; - } - - // fingers are enumerated and loaded after that - enumerate(); + // set current user - nemo for now + setUser(100000); registerDBus(); } @@ -65,15 +66,105 @@ } } +// Code from https://stackoverflow.com/a/37489754/11848012 +// with minor modifications +bool do_chown(const char *file_path, const char *user_name, + const char *group_name) +{ + uid_t uid; + gid_t gid; + struct passwd *pwd; + struct group *grp; + + pwd = getpwnam(user_name); + if (pwd == nullptr) { + qWarning() << "Failed to get user id for" << user_name; + return false; + } + uid = pwd->pw_uid; + + grp = getgrnam(group_name); + if (grp == nullptr) { + qWarning() << "Failed to get group id for" << group_name; + return false; + } + gid = grp->gr_gid; + + if (chown(file_path, uid, gid) == -1) { + qWarning() << "Failed to chown for" << file_path; + return false; + } + return true; +} + +static bool makePath(const char* path, const char* user = nullptr, const char* group = nullptr, + QFileDevice::Permissions permissions = QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner) +{ + qDebug() << Q_FUNC_INFO << path << user << group << permissions; + + QFileInfo fi(path); + if (fi.exists()) { + return true; + } + + QString leaf = fi.fileName(); + QDir dir = fi.absoluteDir(); + if (!makePath(dir.path().toLocal8Bit().data(), user, group, permissions)) { + return false; + } + + if (!dir.mkdir(leaf)) { + qWarning() << "Failed to create directory" << path; + return false; + } + + if (!QFile::setPermissions(path, permissions)) { + qWarning() << "Failed to set permissions" << path; + return false; + } + + if (user != nullptr && group != nullptr) { + return do_chown(path, user, group); + } + + return true; +} + +void FPDCommunity::setUser(uint32_t uid) +{ + qDebug() << Q_FUNC_INFO << uid; + + // path for android store + QString andrPath = AndroidFP::getDefaultGroupPath(uid); + + // create path if missing and set expected permissions / ownership + if (!makePath(andrPath.toLocal8Bit().data(), "system", "system")) { + qWarning() << "Unable to create Android store" << andrPath; + } + + // path for storing string<->uint fp id map + QDir fpDir(QStringLiteral(FINGERPRINT_PATH "/%1").arg(uid)); + if (!makePath(fpDir.absolutePath().toLocal8Bit().data())) { + qWarning() << "Unable to create FPD store" << fpDir.absolutePath(); + } + + m_fingerDatabasePath = fpDir.absoluteFilePath(FINGERPRINT_FILE); + + // always setting group id to 0 + m_androidFP.setGroup(0, andrPath); + + // fingers are enumerated and loaded after that + enumerate(); +} + void FPDCommunity::saveFingers() { qDebug() << Q_FUNC_INFO; - QString filename = FINGERPRINT_PATH FINGERPRINT_FILE; - QFile fingerprintFile(filename); + QFile fingerprintFile(m_fingerDatabasePath); - if (!fingerprintFile.open(QIODevice::WriteOnly)){ - qWarning() << "Could not write " << filename; + if (!fingerprintFile.open(QIODevice::WriteOnly)) { + qWarning() << "Could not write " << m_fingerDatabasePath; return; } @@ -86,13 +177,12 @@ { qDebug() << Q_FUNC_INFO; - QString filename = FINGERPRINT_PATH FINGERPRINT_FILE; - QFile fingerprintFile(filename); + QFile fingerprintFile(m_fingerDatabasePath); QDataStream in(&fingerprintFile); in.setVersion(QDataStream::Qt_5_6); if (!fingerprintFile.open(QIODevice::ReadOnly)) { - qInfo() << "Could not read the file:" << filename << "Error string:" << fingerprintFile.errorString(); + qInfo() << "Could not read the file:" << m_fingerDatabasePath << "Error string:" << fingerprintFile.errorString(); qInfo() << "Assuming empty fingerprint map"; m_fingerMap.clear(); } else { | ||
[-] [+] | Changed | _service:tar_git:sailfish-fpd-community-1.0.0.tar.bz2/src/fpdcommunity.h ^ |
@@ -138,16 +138,21 @@ private: void abort(); void enumerate(); + void setUser(uint32_t uid); private: AndroidFP m_androidFP; + QTimer m_cancelTimer; + bool m_dbusRegistered = false; QString m_dbusCaller; + + QString m_fingerDatabasePath; + QMap<uint32_t, QString> m_fingerMap; + State m_state = FPSTATE_IDLE; AcquiredState m_acquired = FPACQUIRED_UNSPECIFIED; QString m_addingFinger; - QMap<uint32_t, QString> m_fingerMap; - QTimer m_cancelTimer; void setState(State newState); void registerDBus(); |