Mercurial > crates > nonstick
diff testharness/src/lib.rs @ 163:a75a66cb4181
Add end-to-end tests; fix issues found by tests.
- Create tests and installer/remover shell script
- Fix Pointer/pointee problems
- Add Debug formatting
- Misc cleanup
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 14 Jul 2025 17:40:11 -0400 |
parents | 634cd5f2ac8b |
children | 2f5913131295 |
line wrap: on
line diff
--- a/testharness/src/lib.rs Mon Jul 14 15:07:16 2025 -0400 +++ b/testharness/src/lib.rs Mon Jul 14 17:40:11 2025 -0400 @@ -1,26 +1,103 @@ //! The nonstick library + +use crate::nonstick::items::ItemsMut; +use std::cell::Cell; extern crate nonstick; -use nonstick::{pam_hooks, Flags, ModuleClient, PamModule}; -use std::ffi::CStr; +use nonstick::conv::{ErrorMsg, InfoMsg, MaskedQAndA, QAndA}; +use nonstick::{error, info, pam_hooks, ErrorCode, Flags, ModuleClient, PamModule}; +use std::ffi::{CStr, OsString}; +use std::os::unix::ffi::OsStrExt; struct TestHarness; impl<M: ModuleClient> PamModule<M> for TestHarness { - fn authenticate(_handle: &mut M, _args: Vec<&CStr>, _flags: Flags) -> nonstick::Result<()> { - Ok(()) + fn authenticate(handle: &mut M, args: Vec<&CStr>, _: Flags) -> nonstick::Result<()> { + let strings: Vec<_> = args.iter().map(|&a| Vec::from(a.to_bytes())).collect(); + if strings != vec![Vec::from(b"param"), Vec::from(b"param2")] { + return Err(ErrorCode::SystemError); + } + let username = handle.username(None)?; + if username != "initial" { + return Err(ErrorCode::UserUnknown); + } + handle + .items_mut() + .set_user(Some("updated-in-process".as_ref()))?; + handle.set_module_data("florgus", Cell::new(99))?; + let authtok = handle.authtok(Some("custom".as_ref()))?; + if authtok.as_bytes() != b"valid" { + return Err(ErrorCode::AuthenticationError); + } + let info = InfoMsg::new("Watch out!".as_ref()); + let err = ErrorMsg::new("It's broken!".as_ref()); + let public = QAndA::new("How many?".as_ref()); + let private = MaskedQAndA::new("Where?".as_ref()); + let msgs = &[ + info.exchange(), + err.exchange(), + public.exchange(), + private.exchange(), + ]; + handle.communicate(msgs); + let public = public.answer()?; + info!(handle, "public question: {:?}", public); + let private = private.answer()?; + info!(handle, "private question: {:?}", private); + if public.as_bytes() == b"123" && private.as_bytes() == b"abc" { + Ok(()) + } else { + Err(ErrorCode::Abort) + } } - fn account_management( - _handle: &mut M, - _args: Vec<&CStr>, - _flags: Flags, - ) -> nonstick::Result<()> { - Ok(()) + fn account_management(handle: &mut M, _: Vec<&CStr>, _: Flags) -> nonstick::Result<()> { + let value: &Cell<i32> = match handle.username(None)?.as_bytes() { + b"initial" => return Err(ErrorCode::AccountExpired), + b"updated-in-process" => handle.get_module_data("florgus"), + _ => return Err(ErrorCode::UserUnknown), + } + .ok_or(ErrorCode::SessionError)?; + let florgus_str: Option<&i32> = handle.get_module_data("florgus"); + if let Some(s) = florgus_str { + error!( + handle, + "module_data type mismatch: florgus = <{s}> but should not be set" + ) + } + if value.get() != 99 { + error!(handle, "wrong value! {}", value.get()); + return Err(ErrorCode::AuthTokError); + } + let password = handle.authtok(None)?; + if password.as_bytes() == b"valid" { + Err(ErrorCode::NewAuthTokRequired) + } else { + Ok(()) + } } - fn change_authtok(_handle: &mut M, _args: Vec<&CStr>, _flags: Flags) -> nonstick::Result<()> { - todo!() + fn change_authtok(handle: &mut M, _: Vec<&CStr>, flags: Flags) -> nonstick::Result<()> { + if flags.contains(Flags::PRELIMINARY_CHECK) { + let password = handle.authtok(None)?; + if password.as_bytes() != b"acceptable" { + return Err(ErrorCode::PermissionDenied); + } + handle.set_module_data("checked_pass", password) + } else if flags.contains(Flags::UPDATE_AUTHTOK) { + let password = handle.authtok(None)?; + let checked: &OsString = handle + .get_module_data("checked_pass") + .ok_or(ErrorCode::SystemError)?; + if password != *checked { + error!(handle, "password mismatch? {password:?} {checked:?}"); + return Err(ErrorCode::AuthenticationError); + } + Ok(()) + } else { + error!(handle, "invalid flag state: {flags:?}"); + Err(ErrorCode::SystemError) + } } }