annotate src/libpam/memory.rs @ 80:5aa1a010f1e8

Start using PAM headers; improve owned/borrowed distinction. - Uses bindgen to generate bindings (only if needed). - Gets the story together on owned vs. borrowed handles. - Reduces number of mutable borrows in handle operation (since `PamHandle` is neither `Send` nor `Sync`, we never have to worry about thread safety. - Improves a bunch of macros so we don't have our own special syntax for docs. - Implement question indirection for standard XSSO PAM implementations.
author Paul Fisher <paul@pfish.zone>
date Tue, 10 Jun 2025 01:09:30 -0400
parents 2128123b9406
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
1 //! Things for dealing with memory.
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
2
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
3 use crate::Result;
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
4 use crate::{BinaryData, ErrorCode};
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
5 use std::ffi::{c_char, CStr, CString};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
6 use std::marker::{PhantomData, PhantomPinned};
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
7 use std::{ptr, slice};
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
8
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
9 /// Allocates `count` elements to hold `T`.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
10 #[inline]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
11 pub fn calloc<T>(count: usize) -> *mut T {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
12 // SAFETY: it's always safe to allocate! Leaking memory is fun!
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
13 unsafe { libc::calloc(count, size_of::<T>()) }.cast()
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
14 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
15
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
16 /// Wrapper for [`libc::free`] to make debugging calls/frees easier.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
17 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
18 /// # Safety
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
19 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
20 /// If you double-free, it's all your fault.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
21 #[inline]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
22 pub unsafe fn free<T>(p: *mut T) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
23 libc::free(p.cast())
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
24 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
25
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
26 /// Makes whatever it's in not [`Send`], [`Sync`], or [`Unpin`].
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
27 #[repr(C)]
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
28 #[derive(Debug, Default)]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
29 pub struct Immovable(pub PhantomData<(*mut u8, PhantomPinned)>);
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
30
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
31 /// Safely converts a `&str` option to a `CString` option.
64
bbe84835d6db More organization; add lots of docs.
Paul Fisher <paul@pfish.zone>
parents: 60
diff changeset
32 pub fn option_cstr(prompt: Option<&str>) -> Result<Option<CString>> {
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
33 prompt
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
34 .map(CString::new)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
35 .transpose()
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
36 .map_err(|_| ErrorCode::ConversationError)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
37 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
38
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
39 /// Gets the pointer to the given CString, or a null pointer if absent.
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
40 pub fn prompt_ptr(prompt: Option<&CString>) -> *const c_char {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
41 match prompt {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
42 Some(c_str) => c_str.as_ptr(),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
43 None => ptr::null(),
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
44 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
45 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
46
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
47 /// Creates an owned copy of a string that is returned from a
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
48 /// <code>pam_get_<var>whatever</var></code> function.
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
49 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
50 /// # Safety
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
51 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
52 /// It's on you to provide a valid string.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
53 pub unsafe fn copy_pam_string(result_ptr: *const libc::c_char) -> Result<String> {
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
54 // We really shouldn't get a null pointer back here, but if we do, return nothing.
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
55 if result_ptr.is_null() {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
56 return Ok(String::new());
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
57 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
58 let bytes = unsafe { CStr::from_ptr(result_ptr) };
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
59 bytes
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
60 .to_str()
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
61 .map(String::from)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
62 .map_err(|_| ErrorCode::ConversationError)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
63 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
64
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
65 /// Wraps a string returned from PAM as an `Option<&str>`.
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
66 pub unsafe fn wrap_string<'a>(data: *const libc::c_char) -> Result<Option<&'a str>> {
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
67 let ret = if data.is_null() {
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
68 None
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
69 } else {
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
70 Some(
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
71 CStr::from_ptr(data)
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
72 .to_str()
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
73 .map_err(|_| ErrorCode::ConversationError)?,
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
74 )
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
75 };
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
76 Ok(ret)
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
77 }
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
78
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
79 /// Allocates a string with the given contents on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
80 ///
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
81 /// This is like [`CString::new`], but:
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
82 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
83 /// - it allocates data on the C heap with [`libc::malloc`].
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
84 /// - it doesn't take ownership of the data passed in.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
85 pub fn malloc_str(text: &str) -> Result<*mut c_char> {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
86 let data = text.as_bytes();
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
87 if data.contains(&0) {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
88 return Err(ErrorCode::ConversationError);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
89 }
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
90 // +1 for the null terminator
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
91 let data_alloc: *mut c_char = calloc(data.len() + 1);
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
92 // SAFETY: we just allocated this and we have enough room.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
93 unsafe {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
94 libc::memcpy(data_alloc.cast(), data.as_ptr().cast(), data.len());
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
95 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
96 Ok(data_alloc)
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
97 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
98
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
99 /// Writes zeroes over the contents of a C string.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
100 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
101 /// This won't overwrite a null pointer.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
102 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
103 /// # Safety
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
104 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
105 /// It's up to you to provide a valid C string.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
106 pub unsafe fn zero_c_string(cstr: *mut c_char) {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
107 if !cstr.is_null() {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
108 libc::memset(cstr.cast(), 0, libc::strlen(cstr.cast()));
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
109 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
110 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
111
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
112 /// Binary data used in requests and responses.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
113 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
114 /// This is an unsized data type whose memory goes beyond its data.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
115 /// This must be allocated on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
116 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
117 /// A Linux-PAM extension.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
118 #[repr(C)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
119 pub struct CBinaryData {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
120 /// The total length of the structure; a u32 in network byte order (BE).
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
121 total_length: [u8; 4],
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
122 /// A tag of undefined meaning.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
123 data_type: u8,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
124 /// Pointer to an array of length [`length`](Self::length) − 5
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
125 data: [u8; 0],
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
126 _marker: Immovable,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
127 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
128
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
129 impl CBinaryData {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
130 /// Copies the given data to a new BinaryData on the heap.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
131 pub fn alloc((data, data_type): (&[u8], u8)) -> Result<*mut CBinaryData> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
132 let buffer_size =
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
133 u32::try_from(data.len() + 5).map_err(|_| ErrorCode::ConversationError)?;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
134 // SAFETY: We're only allocating here.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
135 let dest = unsafe {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
136 let dest_buffer: *mut CBinaryData = calloc::<u8>(buffer_size as usize).cast();
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
137 let dest = &mut *dest_buffer;
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
138 dest.total_length = buffer_size.to_be_bytes();
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
139 dest.data_type = data_type;
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
140 let dest = dest.data.as_mut_ptr();
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
141 libc::memcpy(dest.cast(), data.as_ptr().cast(), data.len());
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
142 dest_buffer
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
143 };
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
144 Ok(dest)
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
145 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
146
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
147 fn length(&self) -> usize {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
148 u32::from_be_bytes(self.total_length).saturating_sub(5) as usize
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
149 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
150
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
151 /// Clears this data and frees it.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
152 pub unsafe fn zero_contents(&mut self) {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
153 let contents = slice::from_raw_parts_mut(self.data.as_mut_ptr(), self.length());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
154 for v in contents {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
155 *v = 0
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
156 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
157 self.data_type = 0;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
158 self.total_length = [0; 4];
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
159 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
160 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
161
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
162 impl<'a> From<&'a CBinaryData> for (&'a [u8], u8) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
163 fn from(value: &'a CBinaryData) -> Self {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
164 (
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
165 unsafe { slice::from_raw_parts(value.data.as_ptr(), value.length()) },
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
166 value.data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
167 )
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
168 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
169 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
170
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
171 impl From<&'_ CBinaryData> for BinaryData {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
172 fn from(value: &'_ CBinaryData) -> Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
173 // This is a dumb trick but I like it because it is simply the presence
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
174 // of `.map(|z: (_, _)| z)` in the middle of this that gives
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
175 // type inference the hint it needs to make this work.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
176 let [ret] = [value].map(Into::into).map(|z: (_, _)| z).map(Into::into);
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
177 ret
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
178 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
179 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
180
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
181 impl From<Option<&'_ CBinaryData>> for BinaryData {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
182 fn from(value: Option<&CBinaryData>) -> Self {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
183 value.map(Into::into).unwrap_or_default()
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
184 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
185 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
186
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
187 #[cfg(test)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
188 mod tests {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
189 use super::{
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
190 copy_pam_string, free, malloc_str, option_cstr, prompt_ptr, zero_c_string, CString,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
191 ErrorCode,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
192 };
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
193 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
194 fn test_strings() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
195 let str = malloc_str("hello there").unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
196 malloc_str("hell\0 there").unwrap_err();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
197 unsafe {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
198 let copied = copy_pam_string(str).unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
199 assert_eq!("hello there", copied);
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
200 zero_c_string(str);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
201 let idx_three = str.add(3).as_mut().unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
202 *idx_three = 0x80u8 as i8;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
203 let zeroed = copy_pam_string(str).unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
204 assert!(zeroed.is_empty());
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
205 free(str);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
206 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
207 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
208
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
209 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
210 fn test_option_str() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
211 let good = option_cstr(Some("whatever")).unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
212 assert_eq!("whatever", good.unwrap().to_str().unwrap());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
213 let no_str = option_cstr(None).unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
214 assert!(no_str.is_none());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
215 let bad_str = option_cstr(Some("what\0ever")).unwrap_err();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
216 assert_eq!(ErrorCode::ConversationError, bad_str);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
217 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
218
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
219 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
220 fn test_prompt() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
221 let prompt_cstr = CString::new("good").ok();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
222 let prompt = prompt_ptr(prompt_cstr.as_ref());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
223 assert!(!prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
224 let no_prompt = prompt_ptr(None);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
225 assert!(no_prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
226 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
227 }