diff src/handle.rs @ 70:9f8381a1c09c

Implement low-level conversation primitives. This change does two primary things: 1. Introduces new Conversation traits, to be implemented both by the library and by PAM client applications. 2. Builds the memory-management infrastructure for passing messages through the conversation. ...and it adds tests for both of the above, including ASAN tests.
author Paul Fisher <paul@pfish.zone>
date Tue, 03 Jun 2025 01:21:59 -0400
parents 8f3ae0c7ab92
children 58f9d2a4df38
line wrap: on
line diff
--- a/src/handle.rs	Sun Jun 01 01:15:04 2025 -0400
+++ b/src/handle.rs	Tue Jun 03 01:21:59 2025 -0400
@@ -22,7 +22,7 @@
     ///
     /// ```no_run
     /// # use nonstick::PamHandle;
-    /// # fn _doc(handle: &impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
+    /// # fn _doc(handle: &mut impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
     /// // Get the username using the default prompt.
     /// let user = handle.get_user(None)?;
     /// // Get the username using a custom prompt.
@@ -33,7 +33,7 @@
     ///
     /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_user.3.html
     /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_user
-    fn get_user(&self, prompt: Option<&str>) -> Result<String>;
+    fn get_user(&mut self, prompt: Option<&str>) -> Result<String>;
 
     /// Retrieves the authentication token from the user.
     ///
@@ -46,7 +46,7 @@
     ///
     /// ```no_run
     /// # use nonstick::PamHandle;
-    /// # fn _doc(handle: &impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
+    /// # fn _doc(handle: &mut impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
     /// // Get the user's password using the default prompt.
     /// let pass = handle.get_authtok(None)?;
     /// // Get the user's password using a custom prompt.
@@ -57,7 +57,7 @@
     ///
     /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_authtok.3.html
     /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_item
-    fn get_authtok(&self, prompt: Option<&str>) -> Result<SecureString>;
+    fn get_authtok(&mut self, prompt: Option<&str>) -> Result<SecureString>;
 
     /// Retrieves an [Item] that has been set, possibly by the PAM client.
     ///
@@ -74,7 +74,7 @@
     /// # use nonstick::PamHandle;
     /// use nonstick::items::Service;
     ///
-    /// # fn _doc(pam_handle: &impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
+    /// # fn _doc(pam_handle: &mut impl PamHandle) -> Result<(), Box<dyn std::error::Error>> {
     /// let svc: Option<Service> = pam_handle.get_item()?;
     /// match svc {
     ///     Some(name) => eprintln!("The calling service name is {:?}", name.to_string_lossy()),
@@ -86,7 +86,7 @@
     ///
     /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_item.3.html
     /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_item
-    fn get_item<T: Item>(&self) -> Result<Option<T>>;
+    fn get_item<T: Item>(&mut self) -> Result<Option<T>>;
 
     /// Sets an item in the PAM context. It can be retrieved using [`get_item`](Self::get_item).
     ///
@@ -154,7 +154,7 @@
     ///
     /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_data.3.html
     /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_data
-    unsafe fn get_data<T>(&self, key: &str) -> Result<Option<&T>>;
+    unsafe fn get_data<T>(&mut self, key: &str) -> Result<Option<&T>>;
 
     /// Stores a pointer that can be retrieved later with [`get_data`](Self::get_data).
     ///
@@ -201,7 +201,7 @@
 }
 
 impl PamHandle for LibPamHandle {
-    fn get_user(&self, prompt: Option<&str>) -> crate::Result<String> {
+    fn get_user(&mut self, prompt: Option<&str>) -> crate::Result<String> {
         let prompt = memory::option_cstr(prompt)?;
         let mut output: *const c_char = std::ptr::null_mut();
         let ret = unsafe {
@@ -211,7 +211,7 @@
         memory::copy_pam_string(output)
     }
 
-    fn get_authtok(&self, prompt: Option<&str>) -> crate::Result<SecureString> {
+    fn get_authtok(&mut self, prompt: Option<&str>) -> crate::Result<SecureString> {
         let prompt = memory::option_cstr(prompt)?;
         let mut output: *const c_char = std::ptr::null_mut();
         let res = unsafe {
@@ -226,7 +226,7 @@
         memory::copy_pam_string(output).map(SecureString::from)
     }
 
-    fn get_item<T: Item>(&self) -> crate::Result<Option<T>> {
+    fn get_item<T: Item>(&mut self) -> crate::Result<Option<T>> {
         let mut ptr: *const libc::c_void = std::ptr::null();
         let out = unsafe {
             let ret = pam_ffi::pam_get_item(&self.0, T::type_id().into(), &mut ptr);
@@ -259,7 +259,7 @@
 }
 
 impl PamModuleHandle for LibPamHandle {
-    unsafe fn get_data<T>(&self, key: &str) -> crate::Result<Option<&T>> {
+    unsafe fn get_data<T>(&mut self, key: &str) -> crate::Result<Option<&T>> {
         let c_key = CString::new(key).map_err(|_| ErrorCode::ConversationError)?;
         let mut ptr: *const libc::c_void = std::ptr::null();
         ErrorCode::result_from(pam_ffi::pam_get_data(&self.0, c_key.as_ptr(), &mut ptr))?;