Mercurial > crates > nonstick
annotate src/libpam/memory.rs @ 95:51c9d7e8261a
Return owned strings rather than borrowed strings.
It's going to be irritating to have to work with strings borrowed from the
PAM handle rather than just using your own. They're cheap enough to copy.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 23 Jun 2025 14:03:44 -0400 |
parents | efc2b56c8928 |
children | b87100c5eed4 |
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}; |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
7 use std::mem::offset_of; |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
8 use std::ptr::NonNull; |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
9 use std::{mem, ptr, slice}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
10 |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
11 /// Allocates `count` elements to hold `T`. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
12 #[inline] |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
13 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
|
14 // 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
|
15 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
|
16 } |
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 /// 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
|
19 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
20 /// # Safety |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
21 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
22 /// 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
|
23 #[inline] |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
24 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
|
25 libc::free(p.cast()) |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
26 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
27 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
28 /// 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
|
29 #[repr(C)] |
80
5aa1a010f1e8
Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents:
79
diff
changeset
|
30 #[derive(Debug, Default)] |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
31 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
|
32 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
33 /// 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
|
34 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
|
35 prompt |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
36 .map(CString::new) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
37 .transpose() |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 .map_err(|_| ErrorCode::ConversationError) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
41 /// 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
|
42 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
|
43 match prompt { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
44 Some(c_str) => c_str.as_ptr(), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
45 None => ptr::null(), |
60
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 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
48 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 /// 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
|
50 /// <code>pam_get_<var>whatever</var></code> function. |
72 | 51 /// |
52 /// # Safety | |
53 /// | |
54 /// It's on you to provide a valid string. | |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
55 pub unsafe fn copy_pam_string(result_ptr: *const c_char) -> Result<Option<String>> { |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
56 let borrowed = match NonNull::new(result_ptr.cast_mut()) { |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
57 Some(data) => Some( |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
58 CStr::from_ptr(data.as_ptr()) |
72 | 59 .to_str() |
60 .map_err(|_| ErrorCode::ConversationError)?, | |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
61 ), |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
62 None => return Ok(None), |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
63 }; |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
64 Ok(borrowed.map(String::from)) |
72 | 65 } |
66 | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
67 /// Allocates a string with the given contents on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
68 /// |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
69 /// This is like [`CString::new`], but: |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
70 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
71 /// - it allocates data on the C heap with [`libc::malloc`]. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
72 /// - it doesn't take ownership of the data passed in. |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
73 pub fn malloc_str(text: &str) -> Result<NonNull<c_char>> { |
77
351bdc13005e
Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents:
75
diff
changeset
|
74 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
|
75 if data.contains(&0) { |
351bdc13005e
Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents:
75
diff
changeset
|
76 return Err(ErrorCode::ConversationError); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
77 } |
79
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
78 // +1 for the null terminator |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
79 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
|
80 // SAFETY: we just allocated this and we have enough room. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
81 unsafe { |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
82 libc::memcpy(data_alloc.cast(), data.as_ptr().cast(), data.len()); |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
83 Ok(NonNull::new_unchecked(data_alloc)) |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
84 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
85 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
86 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
87 /// Writes zeroes over the contents of a C string. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
88 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
89 /// This won't overwrite a null pointer. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
90 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
91 /// # Safety |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
92 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
93 /// 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
|
94 pub unsafe fn zero_c_string(cstr: *mut c_char) { |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
95 if !cstr.is_null() { |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
96 let len = libc::strlen(cstr.cast()); |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
97 for x in 0..len { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
98 ptr::write_volatile(cstr.byte_offset(x as isize), mem::zeroed()) |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
99 } |
71
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 } |
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 /// Binary data used in requests and responses. |
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 /// 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
|
106 /// This must be allocated on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
107 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
108 /// A Linux-PAM extension. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
109 #[repr(C)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
110 pub struct CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
111 /// 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
|
112 total_length: [u8; 4], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
113 /// A tag of undefined meaning. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
114 data_type: u8, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
115 /// Pointer to an array of length [`length`](Self::length) − 5 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
116 data: [u8; 0], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
117 _marker: Immovable, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
118 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
119 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
120 impl CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
121 /// Copies the given data to a new BinaryData on the heap. |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
122 pub fn alloc((data, data_type): (&[u8], u8)) -> Result<NonNull<CBinaryData>> { |
77
351bdc13005e
Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents:
75
diff
changeset
|
123 let buffer_size = |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
124 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
|
125 // 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
|
126 let dest = unsafe { |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
127 let mut dest_buffer: NonNull<Self> = |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
128 NonNull::new_unchecked(calloc::<u8>(buffer_size as usize).cast()); |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
129 let dest = dest_buffer.as_mut(); |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
130 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
|
131 dest.data_type = data_type; |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
132 libc::memcpy( |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
133 Self::data_ptr(dest_buffer).cast(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
134 data.as_ptr().cast(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
135 data.len(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
136 ); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
137 dest_buffer |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
138 }; |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
139 Ok(dest) |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
140 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
141 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
142 fn length(&self) -> usize { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
143 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
|
144 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
145 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
146 fn data_ptr(ptr: NonNull<Self>) -> *mut u8 { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
147 unsafe { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
148 ptr.as_ptr() |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
149 .cast::<u8>() |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
150 .byte_offset(offset_of!(Self, data) as isize) |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
151 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
152 } |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
153 |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
154 unsafe fn data_slice<'a>(ptr: NonNull<Self>) -> &'a mut [u8] { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
155 unsafe { slice::from_raw_parts_mut(Self::data_ptr(ptr), ptr.as_ref().length()) } |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
156 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
157 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
158 pub unsafe fn data<'a>(ptr: NonNull<Self>) -> (&'a [u8], u8) { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
159 unsafe { (Self::data_slice(ptr), ptr.as_ref().data_type) } |
79
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
160 } |
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
161 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
162 pub unsafe fn zero_contents(ptr: NonNull<Self>) { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
163 for byte in Self::data_slice(ptr) { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
164 ptr::write_volatile(byte as *mut u8, mem::zeroed()); |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
165 } |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
166 ptr::write_volatile(ptr.as_ptr(), mem::zeroed()); |
77
351bdc13005e
Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents:
75
diff
changeset
|
167 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
168 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
169 #[allow(clippy::wrong_self_convention)] |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
170 pub unsafe fn as_binary_data(ptr: NonNull<Self>) -> BinaryData { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
171 let (data, data_type) = unsafe { (CBinaryData::data_slice(ptr), ptr.as_ref().data_type) }; |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
172 (Vec::from(data), data_type).into() |
77
351bdc13005e
Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents:
75
diff
changeset
|
173 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
174 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
175 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
176 #[cfg(test)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
177 mod tests { |
79
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
178 use super::{ |
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
179 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
|
180 ErrorCode, |
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
181 }; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
182 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
183 fn test_strings() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
184 let str = malloc_str("hello there").unwrap(); |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
185 let str = str.as_ptr(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
186 malloc_str("hell\0 there").unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
187 unsafe { |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
188 let copied = copy_pam_string(str).unwrap(); |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
189 assert_eq!("hello there", copied.unwrap()); |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
190 zero_c_string(str); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
191 let idx_three = str.add(3).as_mut().unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
192 *idx_three = 0x80u8 as i8; |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
193 let zeroed = copy_pam_string(str).unwrap().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
194 assert!(zeroed.is_empty()); |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
195 free(str); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
196 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
197 } |
72 | 198 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
199 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
200 fn test_option_str() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
201 let good = option_cstr(Some("whatever")).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
202 assert_eq!("whatever", good.unwrap().to_str().unwrap()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
203 let no_str = option_cstr(None).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
204 assert!(no_str.is_none()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
205 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
206 assert_eq!(ErrorCode::ConversationError, bad_str); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
207 } |
72 | 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_prompt() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
211 let prompt_cstr = CString::new("good").ok(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
212 let prompt = prompt_ptr(prompt_cstr.as_ref()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
213 assert!(!prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
214 let no_prompt = prompt_ptr(None); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
215 assert!(no_prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
216 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
217 } |