comparison 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
comparison
equal deleted inserted replaced
70:9f8381a1c09c 71:58f9d2a4df38
1 //! The PAM library FFI and helpers for managing it.
2 //!
3 //! This includes the functions provided by PAM and the data structures
4 //! used by PAM, as well as a few low-level abstractions for dealing with
5 //! those data structures.
6 //!
7 //! Everything in here is hazmat.
8 //!
9
10 #![allow(dead_code)]
11
12 pub mod memory;
13 mod message;
14 mod response;
15
16 use crate::pam_ffi::memory::Immovable;
17 use crate::pam_ffi::message::OwnedMessages;
18 pub use message::Message;
19 pub use response::RawResponse;
20 use std::ffi::{c_char, c_int, c_void};
21
22 /// An opaque structure that a PAM handle points to.
23 #[repr(C)]
24 pub struct Handle {
25 _data: (),
26 _marker: Immovable,
27 }
28
29 /// An opaque structure that is passed through PAM in a conversation.
30 #[repr(C)]
31 pub struct AppData {
32 _data: (),
33 _marker: Immovable,
34 }
35
36 /// The callback that PAM uses to get information in a conversation.
37 ///
38 /// - `num_msg` is the number of messages in the `pam_message` array.
39 /// - `messages` is a pointer to the messages being sent to the user.
40 /// For details about its structure, see the documentation of
41 /// [`OwnedMessages`](super::OwnedMessages).
42 /// - `responses` is a pointer to an array of [`RawResponse`]s,
43 /// which PAM sets in response to a module's request.
44 /// This is an array of structs, not an array of pointers to a struct.
45 /// There should always be exactly as many `responses` as `num_msg`.
46 /// - `appdata` is the `appdata` field of the [`Conversation`] we were passed.
47 pub type ConversationCallback = extern "C" fn(
48 num_msg: c_int,
49 messages: &OwnedMessages,
50 responses: &mut *mut RawResponse,
51 appdata: *const AppData,
52 ) -> c_int;
53
54 /// A callback and the associated [`AppData`] pointer that needs to be passed back to it.
55 #[repr(C)]
56 pub struct Conversation {
57 callback: ConversationCallback,
58 appdata: *const AppData,
59 }
60
61 #[link(name = "pam")]
62 extern "C" {
63 pub fn pam_get_data(
64 pamh: *const Handle,
65 module_data_name: *const c_char,
66 data: &mut *const c_void,
67 ) -> c_int;
68
69 pub fn pam_set_data(
70 pamh: *mut Handle,
71 module_data_name: *const c_char,
72 data: *const c_void,
73 cleanup: extern "C" fn(pamh: *const c_void, data: *mut c_void, error_status: c_int),
74 ) -> c_int;
75
76 pub fn pam_get_item(pamh: *const Handle, item_type: c_int, item: &mut *const c_void) -> c_int;
77
78 pub fn pam_set_item(pamh: *mut Handle, item_type: c_int, item: *const c_void) -> c_int;
79
80 pub fn pam_get_user(
81 pamh: *const Handle,
82 user: &mut *const c_char,
83 prompt: *const c_char,
84 ) -> c_int;
85
86 pub fn pam_get_authtok(
87 pamh: *const Handle,
88 item_type: c_int,
89 data: &mut *const c_char,
90 prompt: *const c_char,
91 ) -> c_int;
92
93 pub fn pam_end(pamh: *mut Handle, status: c_int) -> c_int;
94 }