59 lines
1.9 KiB
Rust
59 lines
1.9 KiB
Rust
use std::env;
|
|
|
|
use latchd_auth::AuthService;
|
|
use latchd_core::error::Error;
|
|
|
|
fn fixture_service() -> String {
|
|
env::var("LATCHD_PAM_FIXTURE_SERVICE")
|
|
.expect("LATCHD_PAM_FIXTURE_SERVICE must point at the disposable PAM fixture")
|
|
}
|
|
|
|
fn assert_sanitized_pam_failure(result: Result<(), Error>, secret: &str) {
|
|
let error = result.expect_err("the fault-injection PAM fixture must reject the operation");
|
|
match error {
|
|
Error::Pam {
|
|
status, message, ..
|
|
} => {
|
|
assert_ne!(status, 0);
|
|
assert!(!message.contains(secret));
|
|
}
|
|
_ => panic!("fault-injection fixture returned a non-PAM error"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
#[ignore = "requires the disposable PAM fixture installed by the Docker/VM harness"]
|
|
fn authentication_fault_is_rejected_without_secret_leakage() {
|
|
let service = AuthService::new().expect("PAM worker should start");
|
|
let secret = "fixture-auth-secret";
|
|
let result = service.authenticate("root".into(), secret.as_bytes().to_vec(), fixture_service());
|
|
let error = match result {
|
|
Ok(_) => panic!("pam_deny fixture must reject authentication"),
|
|
Err(error) => error,
|
|
};
|
|
match error {
|
|
Error::Pam {
|
|
status, message, ..
|
|
} => {
|
|
assert_ne!(status, 0);
|
|
assert!(!message.contains(secret));
|
|
}
|
|
_ => panic!("fault-injection fixture returned a non-PAM error"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
#[ignore = "requires the disposable PAM fixture installed by the Docker/VM harness"]
|
|
fn password_change_fault_is_rejected_without_secret_leakage() {
|
|
let service = AuthService::new().expect("PAM worker should start");
|
|
assert_sanitized_pam_failure(
|
|
service.change_password(
|
|
"root".into(),
|
|
b"fixture-old-secret".to_vec(),
|
|
b"fixture-new-secret".to_vec(),
|
|
fixture_service(),
|
|
),
|
|
"fixture-new-secret",
|
|
);
|
|
}
|