Mercurial > crates > nonstick
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())) } }