Mercurial > crates > nonstick
comparison src/pam_ffi/memory.rs @ 72:47eb242a4f88
Fill out the PamHandle trait.
This updates the PamHandle trait to have methods for each Item,
and implements them on the LibPamHandle.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Wed, 04 Jun 2025 03:53:36 -0400 |
parents | 58f9d2a4df38 |
children | ac6881304c78 |
comparison
equal
deleted
inserted
replaced
71:58f9d2a4df38 | 72:47eb242a4f88 |
---|---|
26 } | 26 } |
27 } | 27 } |
28 | 28 |
29 /// Creates an owned copy of a string that is returned from a | 29 /// Creates an owned copy of a string that is returned from a |
30 /// <code>pam_get_<var>whatever</var></code> function. | 30 /// <code>pam_get_<var>whatever</var></code> function. |
31 /// | |
32 /// # Safety | |
33 /// | |
34 /// It's on you to provide a valid string. | |
31 pub unsafe fn copy_pam_string(result_ptr: *const libc::c_char) -> Result<String> { | 35 pub unsafe fn copy_pam_string(result_ptr: *const libc::c_char) -> Result<String> { |
32 // We really shouldn't get a null pointer back here, but if we do, return nothing. | 36 // We really shouldn't get a null pointer back here, but if we do, return nothing. |
33 if result_ptr.is_null() { | 37 if result_ptr.is_null() { |
34 return Ok(String::new()); | 38 return Ok(String::new()); |
35 } | 39 } |
36 let bytes = unsafe { CStr::from_ptr(result_ptr) }; | 40 let bytes = unsafe { CStr::from_ptr(result_ptr) }; |
37 bytes | 41 bytes |
38 .to_str() | 42 .to_str() |
39 .map(String::from) | 43 .map(String::from) |
40 .map_err(|_| ErrorCode::ConversationError) | 44 .map_err(|_| ErrorCode::ConversationError) |
45 } | |
46 | |
47 /// Wraps a string returned from PAM as an `Option<&str>`. | |
48 pub unsafe fn wrap_string<'a>(data: *const libc::c_char) -> Result<Option<&'a str>> { | |
49 let ret = if data.is_null() { | |
50 None | |
51 } else { | |
52 Some( | |
53 CStr::from_ptr(data) | |
54 .to_str() | |
55 .map_err(|_| ErrorCode::ConversationError)?, | |
56 ) | |
57 }; | |
58 Ok(ret) | |
41 } | 59 } |
42 | 60 |
43 /// Allocates a string with the given contents on the C heap. | 61 /// Allocates a string with the given contents on the C heap. |
44 /// | 62 /// |
45 /// This is like [`CString::new`](std::ffi::CString::new), but: | 63 /// This is like [`CString::new`](std::ffi::CString::new), but: |
145 pub max: usize, | 163 pub max: usize, |
146 } | 164 } |
147 | 165 |
148 #[cfg(test)] | 166 #[cfg(test)] |
149 mod tests { | 167 mod tests { |
168 use super::{copy_pam_string, malloc_str, option_cstr, prompt_ptr, zero_c_string}; | |
169 use crate::ErrorCode; | |
150 use std::ffi::CString; | 170 use std::ffi::CString; |
151 use crate::ErrorCode; | |
152 use super::{copy_pam_string, malloc_str, option_cstr, prompt_ptr, zero_c_string}; | |
153 #[test] | 171 #[test] |
154 fn test_strings() { | 172 fn test_strings() { |
155 let str = malloc_str("hello there").unwrap(); | 173 let str = malloc_str("hello there").unwrap(); |
156 malloc_str("hell\0 there").unwrap_err(); | 174 malloc_str("hell\0 there").unwrap_err(); |
157 unsafe { | 175 unsafe { |
163 let zeroed = copy_pam_string(str.cast()).unwrap(); | 181 let zeroed = copy_pam_string(str.cast()).unwrap(); |
164 assert!(zeroed.is_empty()); | 182 assert!(zeroed.is_empty()); |
165 libc::free(str.cast()); | 183 libc::free(str.cast()); |
166 } | 184 } |
167 } | 185 } |
168 | 186 |
169 #[test] | 187 #[test] |
170 fn test_option_str() { | 188 fn test_option_str() { |
171 let good = option_cstr(Some("whatever")).unwrap(); | 189 let good = option_cstr(Some("whatever")).unwrap(); |
172 assert_eq!("whatever", good.unwrap().to_str().unwrap()); | 190 assert_eq!("whatever", good.unwrap().to_str().unwrap()); |
173 let no_str = option_cstr(None).unwrap(); | 191 let no_str = option_cstr(None).unwrap(); |
174 assert!(no_str.is_none()); | 192 assert!(no_str.is_none()); |
175 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); | 193 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); |
176 assert_eq!(ErrorCode::ConversationError, bad_str); | 194 assert_eq!(ErrorCode::ConversationError, bad_str); |
177 } | 195 } |
178 | 196 |
179 #[test] | 197 #[test] |
180 fn test_prompt() { | 198 fn test_prompt() { |
181 let prompt_cstr = CString::new("good").ok(); | 199 let prompt_cstr = CString::new("good").ok(); |
182 let prompt = prompt_ptr(prompt_cstr.as_ref()); | 200 let prompt = prompt_ptr(prompt_cstr.as_ref()); |
183 assert!(!prompt.is_null()); | 201 assert!(!prompt.is_null()); |