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
+9 -2
View File
@@ -4,9 +4,13 @@
use std::env;
use std::fs;
use std::path::Path;
use std::sync::OnceLock;
const DEFAULT_LOCALE_CONF: &str = "/etc/locale.conf";
/// Cached locale prefix — detected once, reused for all subsequent calls.
static CACHED_LOCALE: OnceLock<String> = OnceLock::new();
#[derive(Debug, Clone)]
pub struct Strings {
pub password_placeholder: &'static str,
@@ -86,8 +90,11 @@ pub fn detect_locale() -> String {
}
pub fn load_strings(locale: Option<&str>) -> &'static Strings {
let locale = match locale { Some(l) => l.to_string(), None => detect_locale() };
match locale.as_str() { "de" => &STRINGS_DE, _ => &STRINGS_EN }
let locale = match locale {
Some(l) => l,
None => CACHED_LOCALE.get_or_init(detect_locale),
};
match locale { "de" => &STRINGS_DE, _ => &STRINGS_EN }
}
pub fn faillock_warning(attempt_count: u32, max_attempts: u32, strings: &Strings) -> Option<String> {