Skip to content

Commit

Permalink
auth: make fingerprint initialization async
Browse files Browse the repository at this point in the history
  • Loading branch information
moggiesir committed Nov 4, 2024
1 parent f225e23 commit 112266a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 73 deletions.
127 changes: 66 additions & 61 deletions src/core/Fingerprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,33 @@ CFingerprint::CFingerprint() {
std::shared_ptr<sdbus::IConnection> CFingerprint::start() {
if (!m_bEnabled)
return {};
m_sDBUSState.connection = sdbus::createSystemBusConnection();
registerSleepHandler();

// When entering sleep, the wake signal will trigger startVerify().
if (m_sDBUSState.sleeping)
return m_sDBUSState.connection;

startVerify();

m_sDBUSState.connection = sdbus::createSystemBusConnection();
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
m_sDBUSState.login->getPropertyAsync("PreparingForSleep").onInterface(LOGIN_MANAGER).uponReplyInvoke([this](std::optional<sdbus::Error> e, sdbus::Variant preparingForSleep) {
if (e) {
Debug::log(WARN, "fprint: Failed getting value for PreparingForSleep: {}", e->what());
return;
}
m_sDBUSState.sleeping = preparingForSleep.get<bool>();
// When entering sleep, the wake signal will trigger startVerify().
if (m_sDBUSState.sleeping)
return;
inhibitSleep();
startVerify();
});
m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) {
Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start);
if (start) {
m_sDBUSState.sleeping = true;
stopVerify();
m_sDBUSState.inhibitLock.reset();
} else {
m_sDBUSState.sleeping = false;
inhibitSleep();
startVerify();
}
});
return m_sDBUSState.connection;
}

Expand All @@ -73,30 +91,17 @@ void CFingerprint::terminate() {
releaseDevice();
}

void CFingerprint::registerSleepHandler() {
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
m_sDBUSState.sleeping = m_sDBUSState.login->getProperty("PreparingForSleep").onInterface(LOGIN_MANAGER).get<bool>();
m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) {
Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start);
if (start) {
m_sDBUSState.sleeping = true;
stopVerify();
m_sDBUSState.inhibitLock.reset();
} else {
m_sDBUSState.sleeping = false;
inhibitSleep();
startVerify();
}
});
if (!m_sDBUSState.sleeping)
inhibitSleep();
}

void CFingerprint::inhibitSleep() {
m_sDBUSState.login->callMethod("Inhibit")
m_sDBUSState.login->callMethodAsync("Inhibit")
.onInterface(LOGIN_MANAGER)
.withArguments("sleep", "hyprlock", "Fingerprint verifcation must be stopped before sleep", "delay")
.storeResultsTo(m_sDBUSState.inhibitLock);
.uponReplyInvoke([this](std::optional<sdbus::Error> e, sdbus::UnixFd fd) {
if (e) {
Debug::log(WARN, "fprint: could not inhibit sleep: {}", e->what());
} else {
m_sDBUSState.inhibitLock = fd;
}
});
}

bool CFingerprint::createDeviceProxy() {
Expand Down Expand Up @@ -145,12 +150,9 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
stopVerify();
if (m_sDBUSState.retries >= 3) {
m_sDBUSState.message = "Fingerprint auth disabled: too many failed attempts";
} else if (startVerify(/* showMessage= */ false)) {
done = false;
m_sDBUSState.retries++;
m_sDBUSState.message = RETRY_MESSAGE;
} else {
m_sDBUSState.message = "Fingerprint auth disabled: could not restart verification";
done = false;
startVerify(/* isRetry= */ true);
}
break;
case MATCH_UNKNOWN_ERROR:
Expand All @@ -173,44 +175,47 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
break;
}
g_pHyprlock->enqueueForceUpdateTimers();
if (done || m_sDBUSState.abort) {
if (done || m_sDBUSState.abort)
m_sDBUSState.done = true;
m_sDBUSState.connection->leaveEventLoop();
}
}

bool CFingerprint::claimDevice() {
try {
const auto currentUser = ""; // Empty string means use the caller's id.
m_sDBUSState.device->callMethod("Claim").onInterface(DEVICE).withArguments(currentUser);
} catch (sdbus::Error& e) {
Debug::log(WARN, "fprint: could not claim device, {}", e.what());
return false;
}
Debug::log(LOG, "fprint: claimed device");
return true;
void CFingerprint::claimDevice() {
const auto currentUser = ""; // Empty string means use the caller's id.
m_sDBUSState.device->callMethodAsync("Claim").onInterface(DEVICE).withArguments(currentUser).uponReplyInvoke([this](std::optional<sdbus::Error> e) {
if (e) {
Debug::log(WARN, "fprint: could not claim device, {}", e->what());
} else {
Debug::log(LOG, "fprint: claimed device");
startVerify();
}
});
}

bool CFingerprint::startVerify(bool updateMessage) {
void CFingerprint::startVerify(bool isRetry) {
if (!m_sDBUSState.device) {
if (!createDeviceProxy())
return false;
return;

claimDevice();
return;
}
try {
auto finger = "any"; // Any finger.
m_sDBUSState.device->callMethod("VerifyStart").onInterface(DEVICE).withArguments(finger);
} catch (sdbus::Error& e) {
Debug::log(WARN, "fprint: could not start verifying, {}", e.what());
return false;
}
Debug::log(LOG, "fprint: started verifying");
if (updateMessage) {
m_sDBUSState.message = m_sFingerprintReady;
auto finger = "any"; // Any finger.
m_sDBUSState.device->callMethodAsync("VerifyStart").onInterface(DEVICE).withArguments(finger).uponReplyInvoke([this, isRetry](std::optional<sdbus::Error> e) {
if (e) {
Debug::log(WARN, "fprint: could not start verifying, {}", e->what());
if (isRetry)
m_sDBUSState.message = "Fingerprint auth disabled: could not restart verification";
} else {
Debug::log(LOG, "fprint: started verifying");
if (isRetry) {
m_sDBUSState.retries++;
m_sDBUSState.message = RETRY_MESSAGE;
} else {
m_sDBUSState.message = m_sFingerprintReady;
}
}
g_pHyprlock->enqueueForceUpdateTimers();
}
return true;
});
}

bool CFingerprint::stopVerify() {
Expand Down
23 changes: 11 additions & 12 deletions src/core/Fingerprint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,20 @@ class CFingerprint {
bool sleeping = false;
} m_sDBUSState;

std::string m_sFingerprintReady;
std::string m_sFingerprintPresent;
bool m_bAuthenticated = false;
bool m_bEnabled = false;
std::string m_sFingerprintReady;
std::string m_sFingerprintPresent;
bool m_bAuthenticated = false;
bool m_bEnabled = false;

void handleVerifyStatus(const std::string& result, const bool done);
void handleVerifyStatus(const std::string& result, const bool done);

void registerSleepHandler();
void inhibitSleep();
void inhibitSleep();

bool createDeviceProxy();
bool claimDevice();
bool startVerify(bool updateMessage = true);
bool stopVerify();
bool releaseDevice();
bool createDeviceProxy();
void claimDevice();
void startVerify(bool isRetry = false);
bool stopVerify();
bool releaseDevice();
};

inline std::unique_ptr<CFingerprint> g_pFingerprint;

0 comments on commit 112266a

Please sign in to comment.