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", ); }