diff libpam-sys/src/helpers.rs @ 109:bb465393621f

Minor cleanup and reorg. - Use those nice new macros we just implemented. - Straighten out the macro file. - Move the `BinaryPayload` into `structs.rs`, leaving helpers behind.
author Paul Fisher <paul@pfish.zone>
date Sat, 28 Jun 2025 02:49:35 -0400
parents 49d9e2b5c189
children 2346fd501b7a
line wrap: on
line diff
--- a/libpam-sys/src/helpers.rs	Sat Jun 28 00:34:45 2025 -0400
+++ b/libpam-sys/src/helpers.rs	Sat Jun 28 02:49:35 2025 -0400
@@ -1,12 +1,10 @@
 //! This module contains a few non-required helpers to deal with some of the
-//! more annoying memory-twiddling in the PAM API.
-//!
-//! Using these is optional but you might find it useful.
+//! more annoying memory management in the PAM API.
+use crate::structs::BinaryPayload;
+use std::fmt;
+use std::ptr::NonNull;
 use std::error::Error;
-use std::marker::{PhantomData, PhantomPinned};
 use std::mem::ManuallyDrop;
-use std::ptr::NonNull;
-use std::{fmt, slice};
 
 /// Error returned when attempting to allocate a buffer that is too big.
 ///
@@ -123,7 +121,7 @@
         let total_len = total_len as usize;
         let mut buf = O::allocate(total_len);
         // SAFETY: We just allocated this exact size.
-        BinaryPayload::fill(unsafe { &mut buf.as_mut_slice(total_len) }, data_type, data);
+        BinaryPayload::fill(unsafe { buf.as_mut_slice(total_len) }, data_type, data);
         Ok(Self(buf))
     }
 
@@ -171,66 +169,7 @@
     /// allocated by) [`Self::new`]. For instance, passing a pointer allocated
     /// by `malloc` to `OwnedBinaryPayload::<Vec<u8>>::from_ptr` is not allowed.
     pub unsafe fn from_ptr(ptr: NonNull<BinaryPayload>) -> Self {
-        Self(O::from_ptr(ptr.cast(), ptr.as_ref().total_bytes() as usize))
-    }
-}
-
-/// The structure of the "binary message" payload for the `PAM_BINARY_PROMPT`
-/// extension from Linux-PAM.
-pub struct BinaryPayload {
-    /// The total length of the message, including this header,
-    /// as a u32 in network byte order (big endian).
-    total_length: [u8; 4],
-    /// A tag used to provide some kind of hint as to what the data is.
-    /// This is not defined by PAM.
-    data_type: u8,
-    /// Where the data itself would start, used as a marker to make this
-    /// not [`Unpin`] (since it is effectively an intrusive data structure
-    /// pointing to immediately after itself).
-    _marker: PhantomData<PhantomPinned>,
-}
-
-impl BinaryPayload {
-    /// The most data it's possible to put into a [`BinaryPayload`].
-    pub const MAX_SIZE: usize = (u32::MAX - 5) as usize;
-
-    /// Fills in the provided buffer with the given data.
-    ///
-    /// This uses [`copy_from_slice`](slice::copy_from_slice) internally,
-    /// so `buf` must be exactly 5 bytes longer than `data`, or this function
-    /// will panic.
-    pub fn fill(buf: &mut [u8], data_type: u8, data: &[u8]) {
-        let ptr: *mut Self = buf.as_mut_ptr().cast();
-        // SAFETY: We're given a slice, which always has a nonzero pointer.
-        let me = unsafe { ptr.as_mut().unwrap_unchecked() };
-        me.total_length = u32::to_be_bytes(buf.len() as u32);
-        me.data_type = data_type;
-        buf[5..].copy_from_slice(data)
-    }
-
-    /// The size of the message contained in the buffer.
-    fn len(&self) -> usize {
-        self.total_bytes().saturating_sub(5)
-    }
-
-    /// The total storage needed for the message, including header.
-    pub fn total_bytes(&self) -> usize {
-        u32::from_be_bytes(self.total_length) as usize
-    }
-
-    /// Gets the contents of the BinaryMessage starting at the given location.
-    ///
-    /// # Safety
-    ///
-    /// You must pass in a valid pointer, and ensure that the pointer passed in
-    /// outlives your borrow lifetime `'a`.
-    unsafe fn contents<'a>(ptr: *const Self) -> (u8, &'a [u8]) {
-        let header: &Self = ptr.as_ref().unwrap_unchecked();
-        let typ = header.data_type;
-        (
-            typ,
-            slice::from_raw_parts(ptr.cast::<u8>().offset(5), header.len()),
-        )
+        Self(O::from_ptr(ptr.cast(), ptr.as_ref().total_bytes()))
     }
 }