Mercurial > crates > nonstick
diff src/pam_ffi/mod.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 | src/pam_ffi.rs@9f8381a1c09c |
children | 47eb242a4f88 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pam_ffi/mod.rs Tue Jun 03 21:54:58 2025 -0400 @@ -0,0 +1,94 @@ +//! The PAM library FFI and helpers for managing it. +//! +//! This includes the functions provided by PAM and the data structures +//! used by PAM, as well as a few low-level abstractions for dealing with +//! those data structures. +//! +//! Everything in here is hazmat. +//! + +#![allow(dead_code)] + +pub mod memory; +mod message; +mod response; + +use crate::pam_ffi::memory::Immovable; +use crate::pam_ffi::message::OwnedMessages; +pub use message::Message; +pub use response::RawResponse; +use std::ffi::{c_char, c_int, c_void}; + +/// An opaque structure that a PAM handle points to. +#[repr(C)] +pub struct Handle { + _data: (), + _marker: Immovable, +} + +/// An opaque structure that is passed through PAM in a conversation. +#[repr(C)] +pub struct AppData { + _data: (), + _marker: Immovable, +} + +/// The callback that PAM uses to get information in a conversation. +/// +/// - `num_msg` is the number of messages in the `pam_message` array. +/// - `messages` is a pointer to the messages being sent to the user. +/// For details about its structure, see the documentation of +/// [`OwnedMessages`](super::OwnedMessages). +/// - `responses` is a pointer to an array of [`RawResponse`]s, +/// which PAM sets in response to a module's request. +/// This is an array of structs, not an array of pointers to a struct. +/// There should always be exactly as many `responses` as `num_msg`. +/// - `appdata` is the `appdata` field of the [`Conversation`] we were passed. +pub type ConversationCallback = extern "C" fn( + num_msg: c_int, + messages: &OwnedMessages, + responses: &mut *mut RawResponse, + appdata: *const AppData, +) -> c_int; + +/// A callback and the associated [`AppData`] pointer that needs to be passed back to it. +#[repr(C)] +pub struct Conversation { + callback: ConversationCallback, + appdata: *const AppData, +} + +#[link(name = "pam")] +extern "C" { + pub fn pam_get_data( + pamh: *const Handle, + module_data_name: *const c_char, + data: &mut *const c_void, + ) -> c_int; + + pub fn pam_set_data( + pamh: *mut Handle, + module_data_name: *const c_char, + data: *const c_void, + cleanup: extern "C" fn(pamh: *const c_void, data: *mut c_void, error_status: c_int), + ) -> c_int; + + pub fn pam_get_item(pamh: *const Handle, item_type: c_int, item: &mut *const c_void) -> c_int; + + pub fn pam_set_item(pamh: *mut Handle, item_type: c_int, item: *const c_void) -> c_int; + + pub fn pam_get_user( + pamh: *const Handle, + user: &mut *const c_char, + prompt: *const c_char, + ) -> c_int; + + pub fn pam_get_authtok( + pamh: *const Handle, + item_type: c_int, + data: &mut *const c_char, + prompt: *const c_char, + ) -> c_int; + + pub fn pam_end(pamh: *mut Handle, status: c_int) -> c_int; +}