diff src/handle.rs @ 71:58f9d2a4df38

Reorganize everything again??? - Splits ffi/memory stuff into a bunch of stuff in the pam_ffi module. - Builds infrastructure for passing Messages and Responses. - Adds tests for some things at least.
author Paul Fisher <paul@pfish.zone>
date Tue, 03 Jun 2025 21:54:58 -0400
parents 9f8381a1c09c
children 47eb242a4f88
line wrap: on
line diff
--- a/src/handle.rs	Tue Jun 03 01:21:59 2025 -0400
+++ b/src/handle.rs	Tue Jun 03 21:54:58 2025 -0400
@@ -1,11 +1,11 @@
 //! The wrapper types and traits for handles into the PAM library.
 use crate::constants::{ErrorCode, Result};
 use crate::items::{Item, ItemType};
-use crate::{memory, pam_ffi};
-use libc::c_char;
+use crate::pam_ffi;
+use crate::pam_ffi::memory;
 use secure_string::SecureString;
-use std::ffi::{c_int, CString};
-use std::mem;
+use std::ffi::{c_char, c_int, c_void, CString};
+use std::{mem, ptr};
 
 /// Features of a PAM handle that are available to applications and modules.
 ///
@@ -178,17 +178,6 @@
 #[repr(C)]
 pub struct LibPamHandle(pam_ffi::Handle);
 
-impl LibPamHandle {
-    /// Converts a pointer passed from PAM into a borrowed handle.
-    ///
-    /// # Safety
-    ///
-    /// It is your responsibility to provide a valid pointer.
-    pub unsafe fn from_ptr<'a>(ptr: *mut libc::c_void) -> &'a mut LibPamHandle {
-        &mut *(ptr as *mut LibPamHandle)
-    }
-}
-
 impl Drop for LibPamHandle {
     /// Ends the PAM session with a zero error code.
     /// You probably want to call [`close`](Self::close) instead of
@@ -203,17 +192,17 @@
 impl PamHandle for LibPamHandle {
     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 mut output: *const c_char = ptr::null_mut();
         let ret = unsafe {
             pam_ffi::pam_get_user(&self.0, &mut output, memory::prompt_ptr(prompt.as_ref()))
         };
         ErrorCode::result_from(ret)?;
-        memory::copy_pam_string(output)
+        unsafe {memory::copy_pam_string(output)}
     }
 
     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 mut output: *const c_char = ptr::null_mut();
         let res = unsafe {
             pam_ffi::pam_get_authtok(
                 &self.0,
@@ -223,24 +212,20 @@
             )
         };
         ErrorCode::result_from(res)?;
-        memory::copy_pam_string(output).map(SecureString::from)
+        unsafe {memory::copy_pam_string(output)}.map(SecureString::from)
     }
 
-    fn get_item<T: Item>(&mut self) -> crate::Result<Option<T>> {
-        let mut ptr: *const libc::c_void = std::ptr::null();
+    fn get_item<T: Item>(&mut self) -> Result<Option<T>> {
+        let mut ptr: *const c_void = ptr::null();
         let out = unsafe {
             let ret = pam_ffi::pam_get_item(&self.0, T::type_id().into(), &mut ptr);
             ErrorCode::result_from(ret)?;
-            let typed_ptr: *const T::Raw = ptr.cast();
-            match typed_ptr.is_null() {
-                true => None,
-                false => Some(T::from_raw(typed_ptr)),
-            }
+            (ptr as *const T::Raw).as_ref().map(|p| T::from_raw(p))
         };
         Ok(out)
     }
 
-    fn set_item<T: Item>(&mut self, item: T) -> crate::Result<()> {
+    fn set_item<T: Item>(&mut self, item: T) -> Result<()> {
         let ret = unsafe {
             pam_ffi::pam_set_item(&mut self.0, T::type_id().into(), item.into_raw().cast())
         };
@@ -261,15 +246,9 @@
 impl PamModuleHandle for LibPamHandle {
     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();
+        let mut ptr: *const c_void = ptr::null();
         ErrorCode::result_from(pam_ffi::pam_get_data(&self.0, c_key.as_ptr(), &mut ptr))?;
-        match ptr.is_null() {
-            true => Ok(None),
-            false => {
-                let typed_ptr = ptr.cast();
-                Ok(Some(&*typed_ptr))
-            }
-        }
+        Ok((ptr as *const T).as_ref())
     }
 
     fn set_data<T>(&mut self, key: &str, data: Box<T>) -> crate::Result<()> {