fix: audit fixes — async restart_verify, locale caching, panic safety (v0.5.0)

- restart_verify() now async via spawn_future_local (was blocking main thread)
- stop() uses 3s timeout instead of unbounded
- load_strings() caches locale detection in OnceLock (was reading /etc/locale.conf on every call)
- child_get() replaced with child_value().get() for graceful D-Bus type mismatch handling
- Eliminate redundant password clone in auth path (direct move into spawn_blocking)
- Add on_exhausted callback: hides fp_label after MAX_FP_ATTEMPTS
- Set running=false before on_success callback (prevent double-unlock)
- Add 4 unit tests for on_verify_status state machine
- Document GLib-GString/CString zeroize limitation in CLAUDE.md
This commit is contained in:
2026-03-28 10:16:06 +01:00
parent 13b329cd98
commit 09e0d47a38
6 changed files with 137 additions and 44 deletions
+12 -3
View File
@@ -239,9 +239,8 @@ pub fn create_lockscreen_window(
password_entry,
async move {
let user = username.clone();
let pass = Zeroizing::new((*password).clone());
let result = gio::spawn_blocking(move || {
auth::authenticate(&user, &pass)
auth::authenticate(&user, &password)
}).await;
match result {
@@ -397,10 +396,20 @@ pub fn start_fingerprint(
));
};
let fp_label_exhausted = handles.fp_label.clone();
let on_exhausted = move || {
let label = fp_label_exhausted.clone();
glib::idle_add_local_once(move || {
label.set_visible(false);
});
};
let username = handles.username.clone();
let fp_rc_clone = fp_rc.clone();
glib::spawn_future_local(async move {
FingerprintListener::start_async(&fp_rc_clone, &username, on_success, on_failure).await;
FingerprintListener::start_async(
&fp_rc_clone, &username, on_success, on_failure, on_exhausted,
).await;
});
}