diff src/conv.rs @ 56:daa2cde64601

Big big refactor. Probably should have been multiple changes. - Makes FFI safer by explicitly specifying c_int in calls. - Uses ToPrimitive/FromPrimitive to make this easier. - Pulls PamFlag variables into a bitflags! struct. - Pulls PamMessageStyle variables into an enum. - Renames ResultCode to ErrorCode. - Switches from PAM_SUCCESS to using a Result<(), ErrorCode>. - Uses thiserror to make ErrorCode into an Error. - Gets rid of pam_try! because now we have Results. - Expands some names (e.g. Conv to Conversation). - Adds more doc comments. - Returns passwords as a SecureString, to avoid unnecessarily keeping it around in memory.
author Paul Fisher <paul@pfish.zone>
date Sun, 04 May 2025 02:56:55 -0400
parents 9d1160b02d2c
children 3f4a77aa88be
line wrap: on
line diff
--- a/src/conv.rs	Sun May 04 00:58:04 2025 -0400
+++ b/src/conv.rs	Sun May 04 02:56:55 2025 -0400
@@ -2,19 +2,19 @@
 use std::ffi::{CStr, CString};
 use std::ptr;
 
-use crate::constants::PamMessageStyle;
-use crate::constants::PamResultCode;
+use crate::constants::MessageStyle;
+use crate::constants::PamResult;
+use crate::constants::ErrorCode;
 use crate::items::Item;
-use crate::module::PamResult;
 
 #[repr(C)]
-struct PamMessage {
-    msg_style: PamMessageStyle,
+struct Message {
+    msg_style: MessageStyle,
     msg: *const c_char,
 }
 
 #[repr(C)]
-struct PamResponse {
+struct Response {
     resp: *const c_char,
     resp_retcode: libc::c_int, // Unused - always zero
 }
@@ -23,10 +23,10 @@
 pub struct Inner {
     conv: extern "C" fn(
         num_msg: c_int,
-        pam_message: &&PamMessage,
-        pam_response: &mut *const PamResponse,
+        pam_message: &&Message,
+        pam_response: &mut *const Response,
         appdata_ptr: *const libc::c_void,
-    ) -> PamResultCode,
+    ) -> c_int,
     appdata_ptr: *const libc::c_void,
 }
 
@@ -53,27 +53,23 @@
     /// Note that the user experience will depend on how the client implements
     /// these message styles - and not all applications implement all message
     /// styles.
-    pub fn send(&self, style: PamMessageStyle, msg: &str) -> PamResult<Option<&CStr>> {
-        let mut resp_ptr: *const PamResponse = ptr::null();
+    pub fn send(&self, style: MessageStyle, msg: &str) -> PamResult<Option<&CStr>> {
+        let mut resp_ptr: *const Response = ptr::null();
         let msg_cstr = CString::new(msg).unwrap();
-        let msg = PamMessage {
+        let msg = Message {
             msg_style: style,
             msg: msg_cstr.as_ptr(),
         };
-
         let ret = (self.0.conv)(1, &&msg, &mut resp_ptr, self.0.appdata_ptr);
+        ErrorCode::result_from(ret)?;
 
-        if PamResultCode::PAM_SUCCESS == ret {
-            // PamResponse.resp is null for styles that don't return user input like PAM_TEXT_INFO
-            let response = unsafe { (*resp_ptr).resp };
-            if response.is_null() {
-                Ok(None)
-            } else {
-                Ok(Some(unsafe { CStr::from_ptr(response) }))
+        let result = unsafe {
+            match (*resp_ptr).resp {
+                p if p.is_null() => None,
+                p => Some(CStr::from_ptr(p)),
             }
-        } else {
-            Err(ret)
-        }
+        };
+        Ok(result)
     }
 }
 
@@ -81,7 +77,7 @@
     type Raw = Inner;
 
     fn type_id() -> crate::items::ItemType {
-        crate::items::ItemType::Conv
+        crate::items::ItemType::Conversation
     }
 
     unsafe fn from_raw(raw: *const Self::Raw) -> Self {