Mercurial > crates > nonstick
diff testharness/src/lib.rs @ 166:2f5913131295
Separate flag/action flags into flags and action.
This also individualizes the type of flag for each PAM function,
so that you can only call a function with the right flags and values.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 15 Jul 2025 00:32:24 -0400 |
parents | a75a66cb4181 |
children | 0cabe7b94a4f |
line wrap: on
line diff
--- a/testharness/src/lib.rs Mon Jul 14 18:56:55 2025 -0400 +++ b/testharness/src/lib.rs Tue Jul 15 00:32:24 2025 -0400 @@ -5,14 +5,17 @@ extern crate nonstick; use nonstick::conv::{ErrorMsg, InfoMsg, MaskedQAndA, QAndA}; -use nonstick::{error, info, pam_hooks, ErrorCode, Flags, ModuleClient, PamModule}; +use nonstick::{ + error, info, pam_hooks, AuthnFlags, AuthtokAction, AuthtokFlags, ErrorCode, 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) -> nonstick::Result<()> { + fn authenticate(handle: &mut M, args: Vec<&CStr>, _: AuthnFlags) -> 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); @@ -51,7 +54,7 @@ } } - fn account_management(handle: &mut M, _: Vec<&CStr>, _: Flags) -> nonstick::Result<()> { + fn account_management(handle: &mut M, _: Vec<&CStr>, _: AuthnFlags) -> 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"), @@ -77,26 +80,31 @@ } } - 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); + fn change_authtok( + handle: &mut M, + _: Vec<&CStr>, + action: AuthtokAction, + _flags: AuthtokFlags, + ) -> nonstick::Result<()> { + match action { + AuthtokAction::PreliminaryCheck => { + let password = handle.authtok(None)?; + if password.as_bytes() != b"acceptable" { + return Err(ErrorCode::PermissionDenied); + } + handle.set_module_data("checked_pass", password) } - 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); + AuthtokAction::Update => { + 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(()) } - Ok(()) - } else { - error!(handle, "invalid flag state: {flags:?}"); - Err(ErrorCode::SystemError) } } }