Mercurial > crates > nonstick
comparison libpam-sys/src/structs.rs @ 118:39760dfc9b3b
Detect PAM library based only on system lib; rename minimal lib to XSso.
Also formats and assorted other cleanup.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sun, 29 Jun 2025 20:13:03 -0400 |
| parents | 20f7712a6857 |
| children | 476a22db8639 |
comparison
equal
deleted
inserted
replaced
| 117:20f7712a6857 | 118:39760dfc9b3b |
|---|---|
| 1 use core::marker::{PhantomData, PhantomPinned}; | 1 use std::ffi::{c_int, c_void}; |
| 2 use core::slice; | 2 use std::fmt; |
| 3 use std::marker::{PhantomData, PhantomPinned}; | |
| 3 | 4 |
| 4 /// The structure of the "binary message" payload for the `PAM_BINARY_PROMPT` | 5 /// A marker struct to make whatever it's in `!Sync`, `!Send`, and `!Unpin`. |
| 5 /// extension from Linux-PAM. | 6 #[derive(Default, PartialOrd, PartialEq, Ord, Eq)] |
| 6 pub struct BinaryPayload { | 7 #[repr(transparent)] |
| 7 /// The total byte size of the message, including this header, | 8 struct ExtremelyUnsafe(PhantomData<(PhantomPinned, *mut c_void)>); |
| 8 /// as a u32 in network byte order (big endian). | 9 |
| 9 pub total_bytes_u32be: [u8; 4], | 10 impl fmt::Debug for ExtremelyUnsafe { |
| 10 /// A tag used to provide some kind of hint as to what the data is. | 11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 11 /// Its meaning is undefined. | 12 f.write_str("ExtremelyUnsafe") |
| 12 pub data_type: u8, | 13 } |
| 13 /// Where the data itself would start, used as a marker to make this | |
| 14 /// not [`Unpin`] (since it is effectively an intrusive data structure | |
| 15 /// pointing to immediately after itself). | |
| 16 pub _marker: PhantomData<PhantomPinned>, | |
| 17 } | 14 } |
| 18 | 15 |
| 19 impl BinaryPayload { | 16 /// An opaque structure that PAM uses to communicate. |
| 20 /// The most data it's possible to put into a [`BinaryPayload`]. | 17 /// |
| 21 pub const MAX_SIZE: usize = (u32::MAX - 5) as usize; | 18 /// This is only ever returned in pointer form and cannot be constructed. |
| 19 #[repr(C)] | |
| 20 pub struct PamHandle { | |
| 21 _marker: ExtremelyUnsafe, | |
| 22 } | |
| 22 | 23 |
| 23 /// Fills in the provided buffer with the given data. | 24 impl fmt::Debug for PamHandle { |
| 24 /// | 25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 25 /// This uses [`copy_from_slice`](slice::copy_from_slice) internally, | 26 write!(f, "PamHandle({self:p}") |
| 26 /// so `buf` must be exactly 5 bytes longer than `data`, or this function | |
| 27 /// will panic. | |
| 28 pub fn fill(buf: &mut [u8], data_type: u8, data: &[u8]) { | |
| 29 let ptr: *mut Self = buf.as_mut_ptr().cast(); | |
| 30 // SAFETY: We're given a slice, which always has a nonzero pointer. | |
| 31 let me = unsafe { ptr.as_mut().unwrap_unchecked() }; | |
| 32 me.total_bytes_u32be = u32::to_be_bytes(buf.len() as u32); | |
| 33 me.data_type = data_type; | |
| 34 buf[5..].copy_from_slice(data) | |
| 35 } | |
| 36 | |
| 37 /// The total storage needed for the message, including header. | |
| 38 pub fn total_bytes(&self) -> usize { | |
| 39 u32::from_be_bytes(self.total_bytes_u32be) as usize | |
| 40 } | |
| 41 | |
| 42 /// Gets the total byte buffer of the BinaryMessage stored at the pointer. | |
| 43 /// | |
| 44 /// The returned data slice is borrowed from where the pointer points to. | |
| 45 /// | |
| 46 /// # Safety | |
| 47 /// | |
| 48 /// - The pointer must point to a valid `BinaryPayload`. | |
| 49 /// - The borrowed data must not outlive the pointer's validity. | |
| 50 pub unsafe fn buffer_of<'a>(ptr: *const Self) -> &'a [u8] { | |
| 51 let header: &Self = ptr.as_ref().unwrap_unchecked(); | |
| 52 slice::from_raw_parts(ptr.cast(), header.total_bytes().max(5)) | |
| 53 } | |
| 54 | |
| 55 /// Gets the contents of the BinaryMessage stored at the given pointer. | |
| 56 /// | |
| 57 /// The returned data slice is borrowed from where the pointer points to. | |
| 58 /// This is a cheap operation and doesn't do *any* copying. | |
| 59 /// | |
| 60 /// We don't take a `&self` reference here because accessing beyond | |
| 61 /// the range of the `Self` data (i.e., beyond the 5 bytes of `self`) | |
| 62 /// is undefined behavior. Instead, you have to pass a raw pointer | |
| 63 /// directly to the data. | |
| 64 /// | |
| 65 /// # Safety | |
| 66 /// | |
| 67 /// - The pointer must point to a valid `BinaryPayload`. | |
| 68 /// - The borrowed data must not outlive the pointer's validity. | |
| 69 pub unsafe fn contents<'a>(ptr: *const Self) -> (u8, &'a [u8]) { | |
| 70 let header: &Self = ptr.as_ref().unwrap_unchecked(); | |
| 71 ( | |
| 72 header.data_type, | |
| 73 &Self::buffer_of(ptr)[5..] | |
| 74 ) | |
| 75 } | 27 } |
| 76 } | 28 } |
| 29 | |
| 30 /// An opaque structure that is passed through PAM in a conversation. | |
| 31 pub struct AppData { | |
| 32 _marker: ExtremelyUnsafe, | |
| 33 } | |
| 34 | |
| 35 impl fmt::Debug for AppData { | |
| 36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 37 write!(f, "AppData({self:p}") | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 /// The callback that PAM uses to get information in a conversation. | |
| 42 /// | |
| 43 /// For important details about the format of `messages`, | |
| 44 /// see the [`helpers`](crate::helpers) module. | |
| 45 pub type ConversationCallback = unsafe extern "C" fn( | |
| 46 num_msg: c_int, | |
| 47 messages: *const *const Message, | |
| 48 responses: &mut *mut Response, | |
| 49 appdata: *const AppData, | |
| 50 ) -> c_int; | |
| 51 | |
| 52 /// Used by PAM to communicate between the module and the application. | |
| 53 #[repr(C)] | |
| 54 pub struct Conversation { | |
| 55 pub callback: ConversationCallback, | |
| 56 pub appdata: *const AppData, | |
| 57 } | |
| 58 | |
| 59 /// A message sent into a PAM conversation. | |
| 60 #[repr(C)] | |
| 61 pub struct Message { | |
| 62 pub style: c_int, | |
| 63 pub data: *const c_void, | |
| 64 } | |
| 65 | |
| 66 /// A response returned from a PAM conversation. | |
| 67 #[repr(C)] | |
| 68 pub struct Response { | |
| 69 pub data: *mut c_void, | |
| 70 pub _unused: c_int, | |
| 71 } |
