fix: security and correctness audit fixes (v0.4.1)
PAM conv callback: check msg_style (password only for ECHO_OFF), handle strdup OOM with proper cleanup, null-check PAM handle. Fingerprint: self-wire D-Bus g-signal in start() via Rc<RefCell<>> and connect_local — VerifyStatus signals are now actually dispatched. VerifyStop before VerifyStart in restart_verify. Lockscreen: password entry stays active after faillock threshold (PAM decides lockout, not UI), use Zeroizing<String> from GTK entry. Release builds exit(1) without ext-session-lock-v1 support. Config: fingerprint_enabled as Option<bool> so empty user config does not override system config. Dead code: remove unused i18n strings and fingerprint accessors, parameterize faillock_warning max_attempts.
This commit is contained in:
+7
-14
@@ -10,13 +10,11 @@ const DEFAULT_LOCALE_CONF: &str = "/etc/locale.conf";
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Strings {
|
||||
pub password_placeholder: &'static str,
|
||||
pub unlock_button: &'static str,
|
||||
pub reboot_tooltip: &'static str,
|
||||
pub shutdown_tooltip: &'static str,
|
||||
pub fingerprint_prompt: &'static str,
|
||||
pub fingerprint_success: &'static str,
|
||||
pub fingerprint_failed: &'static str,
|
||||
pub auth_failed: &'static str,
|
||||
pub wrong_password: &'static str,
|
||||
pub reboot_failed: &'static str,
|
||||
pub shutdown_failed: &'static str,
|
||||
@@ -30,13 +28,11 @@ pub struct Strings {
|
||||
|
||||
const STRINGS_DE: Strings = Strings {
|
||||
password_placeholder: "Passwort",
|
||||
unlock_button: "Entsperren",
|
||||
reboot_tooltip: "Neustart",
|
||||
shutdown_tooltip: "Herunterfahren",
|
||||
fingerprint_prompt: "Fingerabdruck auflegen zum Entsperren",
|
||||
fingerprint_success: "Fingerabdruck erkannt",
|
||||
fingerprint_failed: "Fingerabdruck nicht erkannt",
|
||||
auth_failed: "Authentifizierung fehlgeschlagen",
|
||||
wrong_password: "Falsches Passwort",
|
||||
reboot_failed: "Neustart fehlgeschlagen",
|
||||
shutdown_failed: "Herunterfahren fehlgeschlagen",
|
||||
@@ -50,13 +46,11 @@ const STRINGS_DE: Strings = Strings {
|
||||
|
||||
const STRINGS_EN: Strings = Strings {
|
||||
password_placeholder: "Password",
|
||||
unlock_button: "Unlock",
|
||||
reboot_tooltip: "Reboot",
|
||||
shutdown_tooltip: "Shut down",
|
||||
fingerprint_prompt: "Place finger on reader to unlock",
|
||||
fingerprint_success: "Fingerprint recognized",
|
||||
fingerprint_failed: "Fingerprint not recognized",
|
||||
auth_failed: "Authentication failed",
|
||||
wrong_password: "Wrong password",
|
||||
reboot_failed: "Reboot failed",
|
||||
shutdown_failed: "Shutdown failed",
|
||||
@@ -96,10 +90,9 @@ pub fn load_strings(locale: Option<&str>) -> &'static Strings {
|
||||
match locale.as_str() { "de" => &STRINGS_DE, _ => &STRINGS_EN }
|
||||
}
|
||||
|
||||
pub fn faillock_warning(attempt_count: u32, strings: &Strings) -> Option<String> {
|
||||
const MAX: u32 = 3;
|
||||
if attempt_count >= MAX { return Some(strings.faillock_locked.to_string()); }
|
||||
let remaining = MAX - attempt_count;
|
||||
pub fn faillock_warning(attempt_count: u32, max_attempts: u32, strings: &Strings) -> Option<String> {
|
||||
if attempt_count >= max_attempts { return Some(strings.faillock_locked.to_string()); }
|
||||
let remaining = max_attempts - attempt_count;
|
||||
if remaining == 1 { return Some(strings.faillock_attempts_remaining.replace("{n}", &remaining.to_string())); }
|
||||
None
|
||||
}
|
||||
@@ -133,8 +126,8 @@ mod tests {
|
||||
assert!(!s.fingerprint_failed.is_empty());
|
||||
}
|
||||
|
||||
#[test] fn faillock_zero() { assert!(faillock_warning(0, load_strings(Some("en"))).is_none()); }
|
||||
#[test] fn faillock_one() { assert!(faillock_warning(1, load_strings(Some("en"))).is_none()); }
|
||||
#[test] fn faillock_two() { assert!(faillock_warning(2, load_strings(Some("en"))).is_some()); }
|
||||
#[test] fn faillock_three() { assert_eq!(faillock_warning(3, load_strings(Some("en"))).unwrap(), "Account may be locked"); }
|
||||
#[test] fn faillock_zero() { assert!(faillock_warning(0, 3, load_strings(Some("en"))).is_none()); }
|
||||
#[test] fn faillock_one() { assert!(faillock_warning(1, 3, load_strings(Some("en"))).is_none()); }
|
||||
#[test] fn faillock_two() { assert!(faillock_warning(2, 3, load_strings(Some("en"))).is_some()); }
|
||||
#[test] fn faillock_three() { assert_eq!(faillock_warning(3, 3, load_strings(Some("en"))).unwrap(), "Account may be locked"); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user