annotate src/libpam/answer.rs @ 98:b87100c5eed4

Start on environment variables, and make pointers nicer. This starts work on the PAM environment handling, and in so doing, introduces the CHeapBox and CHeapString structs. These are analogous to Box and CString, but they're located on the C heap rather than being Rust-managed memory. This is because environment variables deal with even more pointers and it turns out we can lose a lot of manual freeing using homemade smart pointers.
author Paul Fisher <paul@pfish.zone>
date Tue, 24 Jun 2025 04:25:25 -0400
parents efc2b56c8928
children 3f11b8d30f63
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
1 //! Types used to communicate data from the application to the module.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
2
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
3 use crate::libpam::conversation::OwnedMessage;
75
c30811b4afae rename pam_ffi submodule to libpam.
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
4 use crate::libpam::memory;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
5 use crate::libpam::memory::{CBinaryData, CHeapBox, CHeapString};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
6 pub use crate::libpam::pam_ffi::Answer;
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
7 use crate::{ErrorCode, Result};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
8 use std::ffi::CStr;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
9 use std::ops::{Deref, DerefMut};
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
10 use std::ptr::NonNull;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
11 use std::{iter, mem, ptr, slice};
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
12
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
13 /// The corridor via which the answer to Messages navigate through PAM.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
14 #[derive(Debug)]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
15 pub struct Answers {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
16 /// The actual list of answers. This can't be a [`CHeapBox`] because
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
17 /// this is the pointer to the start of an array, not a single Answer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
18 base: NonNull<Answer>,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
19 count: usize,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
20 }
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 impl Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
23 /// Builds an Answers out of the given answered Message Q&As.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
24 pub fn build(value: Vec<OwnedMessage>) -> Result<Self> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
25 let mut outputs = Self {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
26 base: memory::calloc(value.len())?,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
27 count: value.len(),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
28 };
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
29 // Even if we fail during this process, we still end up freeing
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
30 // all allocated answer memory.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
31 for (input, output) in iter::zip(value, outputs.iter_mut()) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
32 match input {
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
33 OwnedMessage::MaskedPrompt(p) => TextAnswer::fill(output, p.answer()?.as_ref())?,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
34 OwnedMessage::Prompt(p) => TextAnswer::fill(output, &(p.answer()?))?,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
35 OwnedMessage::Error(p) => TextAnswer::fill(output, p.answer().map(|_| "")?)?,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
36 OwnedMessage::Info(p) => TextAnswer::fill(output, p.answer().map(|_| "")?)?,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
37 // If we're here, that means that we *got* a Linux-PAM
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
38 // question from PAM, so we're OK to answer it.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
39 OwnedMessage::RadioPrompt(p) => TextAnswer::fill(output, &(p.answer()?))?,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
40 OwnedMessage::BinaryPrompt(p) => BinaryAnswer::fill(output, (&p.answer()?).into())?,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
41 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
42 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
43 Ok(outputs)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
44 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
45
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
46 /// Converts this into a `*Answer` for passing to PAM.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
47 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
48 /// This object is consumed and the `Answer` pointer now owns its data.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
49 /// It can be recreated with [`Self::from_c_heap`].
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
50 pub fn into_ptr(self) -> NonNull<Answer> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
51 let ret = self.base;
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
52 mem::forget(self);
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
53 ret
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
54 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
55
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
56 /// Takes ownership of a list of answers allocated on the C heap.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
57 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
58 /// # Safety
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
59 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
60 /// It's up to you to make sure you pass a valid pointer,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
61 /// like one that you got from PAM, or maybe [`Self::into_ptr`].
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
62 pub unsafe fn from_c_heap(base: NonNull<Answer>, count: usize) -> Self {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
63 Answers { base, count }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
64 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
65 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
66
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
67 impl Deref for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
68 type Target = [Answer];
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
69 fn deref(&self) -> &Self::Target {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
70 // SAFETY: This is the memory we manage ourselves.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
71 unsafe { slice::from_raw_parts(self.base.as_ptr(), self.count) }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
72 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
73 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
74
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
75 impl DerefMut for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76 fn deref_mut(&mut self) -> &mut Self::Target {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
77 // SAFETY: This is the memory we manage ourselves.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
78 unsafe { slice::from_raw_parts_mut(self.base.as_ptr(), self.count) }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
79 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
80 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
81
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
82 impl Drop for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
83 fn drop(&mut self) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
84 // SAFETY: We allocated this ourselves, or it was provided to us by PAM.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
85 // We own these pointers, and they will never be used after this.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
86 unsafe {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
87 for answer in self.iter_mut() {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
88 ptr::drop_in_place(answer)
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
89 }
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
90 memory::free(self.base.as_ptr())
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
91 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
92 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
93 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
94
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
95 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
96 #[derive(Debug)]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
97 pub struct TextAnswer(Answer);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
98
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
99 impl TextAnswer {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
100 /// Interprets the provided `Answer` as a text answer.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
101 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
102 /// # Safety
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
103 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
104 /// It's up to you to provide an answer that is a `TextAnswer`.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
105 pub unsafe fn upcast(from: &mut Answer) -> &mut Self {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
106 // SAFETY: We're provided a valid reference.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
107 &mut *(from as *mut Answer).cast::<Self>()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
108 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
109
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
110 /// Converts the `Answer` to a `TextAnswer` with the given text.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
111 fn fill(dest: &mut Answer, text: &str) -> Result<()> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
112 let allocated = CHeapString::new(text)?;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
113 let _ = dest
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
114 .data
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
115 .replace(unsafe { CHeapBox::cast(allocated.into_box()) });
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
116 Ok(())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
117 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
118
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
119 /// Gets the string stored in this answer.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
120 pub fn contents(&self) -> Result<&str> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
121 match self.0.data.as_ref() {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
122 None => Ok(""),
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
123 Some(data) => {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
124 // SAFETY: This data is either passed from PAM (so we are forced
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
125 // to trust it) or was created by us in TextAnswerInner::alloc.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
126 // In either case, it's going to be a valid null-terminated string.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
127 unsafe { CStr::from_ptr(CHeapBox::as_ptr(data).as_ptr().cast()) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
128 .to_str()
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
129 .map_err(|_| ErrorCode::ConversationError)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
130 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
131 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
132 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
133
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
134 /// Zeroes out the answer data, frees it, and points our data to `null`.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
135 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
136 /// When this `TextAnswer` is part of an [`Answers`],
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
137 /// this is optional (since that will perform the `free`),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
138 /// but it will clear potentially sensitive data.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
139 pub fn zero_contents(&mut self) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
140 // SAFETY: We own this data and know it's valid.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
141 // If it's null, this is a no-op.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
142 // After we're done, it will be null.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
143 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
144 if let Some(ptr) = self.0.data.as_ref() {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
145 CHeapString::zero(CHeapBox::as_ptr(ptr).cast());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
146 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
147 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
148 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
149 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
150
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
151 /// A [`Answer`] with [`CBinaryData`] in it.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
152 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
153 #[derive(Debug)]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
154 pub struct BinaryAnswer(Answer);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
155
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
156 impl BinaryAnswer {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
157 /// Interprets the provided [`Answer`] as a binary answer.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
158 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
159 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
160 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
161 /// It's up to you to provide an answer that is a `BinaryAnswer`.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
162 pub unsafe fn upcast(from: &mut Answer) -> &mut Self {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
163 // SAFETY: We're provided a valid reference.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
164 &mut *(from as *mut Answer).cast::<Self>()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
165 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
166
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
167 /// Fills in a [`Answer`] with the provided binary data.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
168 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
169 /// The `data_type` is a tag you can use for whatever.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
170 /// It is passed through PAM unchanged.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
171 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
172 /// The referenced data is copied to the C heap.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
173 /// We do not take ownership of the original data.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
174 pub fn fill(dest: &mut Answer, data_and_type: (&[u8], u8)) -> Result<()> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
175 let allocated = CBinaryData::alloc(data_and_type)?;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
176 let _ = dest.data.replace(unsafe { CHeapBox::cast(allocated) });
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
177 Ok(())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
178 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
179
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
180 /// Gets the binary data in this answer.
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
181 pub fn data(&self) -> Option<NonNull<CBinaryData>> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
182 // SAFETY: We either got this data from PAM or allocated it ourselves.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
183 // Either way, we trust that it is either valid data or null.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
184 self.0
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
185 .data
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
186 .as_ref()
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
187 .map(CHeapBox::as_ptr)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
188 .map(NonNull::cast)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
189 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
190
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
191 /// Zeroes out the answer data, frees it, and points our data to `null`.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
192 ///
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
193 /// When this `BinaryAnswer` is part of an [`Answers`],
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
194 /// this is optional (since that will perform the `free`),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
195 /// but it will clear potentially sensitive data.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
196 pub fn zero_contents(&mut self) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
197 // SAFETY: We know that our data pointer is either valid or null.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
198 // Once we're done, it's null and the answer is safe.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
199 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
200 if let Some(ptr) = self.0.data.as_ref() {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
201 CBinaryData::zero_contents(CHeapBox::as_ptr(ptr).cast())
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
202 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
203 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
204 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
205 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
206
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
207 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
208 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
209 use super::*;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
210 use crate::conv::{ErrorMsg, InfoMsg, MaskedQAndA, QAndA};
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
211
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
212 macro_rules! answered {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
213 ($typ:ty, $msg:path, $data:expr) => {{
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
214 let qa = <$typ>::new("");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
215 qa.set_answer(Ok($data));
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
216 $msg(qa)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
217 }};
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
218 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
219
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
220 fn assert_text_answer(want: &str, answer: &mut Answer) {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
221 let up = unsafe { TextAnswer::upcast(answer) };
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
222 assert_eq!(want, up.contents().unwrap());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
223 up.zero_contents();
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
224 assert_eq!("", up.contents().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
225 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
226
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
227 fn round_trip(msgs: Vec<OwnedMessage>) -> Answers {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
228 let n = msgs.len();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
229 let sent = Answers::build(msgs).unwrap();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
230 unsafe { Answers::from_c_heap(sent.into_ptr(), n) }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
231 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
232
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
233 #[test]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
234 fn test_round_trip() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
235 let mut answers = round_trip(vec![
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
236 answered!(QAndA, OwnedMessage::Prompt, "whats going on".to_owned()),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
237 answered!(MaskedQAndA, OwnedMessage::MaskedPrompt, "well then".into()),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
238 answered!(ErrorMsg, OwnedMessage::Error, ()),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
239 answered!(InfoMsg, OwnedMessage::Info, ()),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
240 ]);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
241
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
242 if let [going, well, err, info] = &mut answers[..] {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
243 assert_text_answer("whats going on", going);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
244 assert_text_answer("well then", well);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
245 assert_text_answer("", err);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
246 assert_text_answer("", info);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
247 } else {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
248 panic!("received wrong size {len}!", len = answers.len())
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
249 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
250 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
251
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
252 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
253 fn test_round_trip_linux() {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
254 use crate::conv::{BinaryData, BinaryQAndA, RadioQAndA};
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
255 let binary_msg = {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
256 let qa = BinaryQAndA::new((&[][..], 0));
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
257 qa.set_answer(Ok(BinaryData::new(vec![1, 2, 3], 99)));
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
258 OwnedMessage::BinaryPrompt(qa)
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
259 };
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
260 let mut answers = round_trip(vec![
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
261 binary_msg,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
262 answered!(
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
263 RadioQAndA,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
264 OwnedMessage::RadioPrompt,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
265 "beep boop".to_owned()
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
266 ),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
267 ]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
268
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
269 if let [bin, radio] = &mut answers[..] {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
270 let up = unsafe { BinaryAnswer::upcast(bin) };
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
271 assert_eq!(BinaryData::from((&[1, 2, 3][..], 99)), unsafe {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
272 CBinaryData::as_binary_data(up.data().unwrap())
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
273 });
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
274 up.zero_contents();
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
275 assert_eq!(BinaryData::default(), unsafe {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
276 CBinaryData::as_binary_data(up.data().unwrap())
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
277 });
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
278
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
279 assert_text_answer("beep boop", radio);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
280 } else {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
281 panic!("received wrong size {len}!", len = answers.len())
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
282 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
283 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
284
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
285 #[test]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
286 fn test_text_answer() {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
287 let mut answer: CHeapBox<Answer> = CHeapBox::default();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
288 TextAnswer::fill(&mut answer, "hello").unwrap();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
289 let zeroth_text = unsafe { TextAnswer::upcast(&mut answer) };
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
290 let data = zeroth_text.contents().expect("valid");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
291 assert_eq!("hello", data);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
292 zeroth_text.zero_contents();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
293 zeroth_text.zero_contents();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
294 TextAnswer::fill(&mut answer, "hell\0").expect_err("should error; contains nul");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
295 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
296
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
297 #[test]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
298 fn test_binary_answer() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
299 use crate::conv::BinaryData;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
300 let mut answer: CHeapBox<Answer> = CHeapBox::default();
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
301 let real_data = BinaryData::new([1, 2, 3, 4, 5, 6, 7, 8], 9);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
302 BinaryAnswer::fill(&mut answer, (&real_data).into()).expect("alloc should succeed");
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
303 let bin_answer = unsafe { BinaryAnswer::upcast(&mut answer) };
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
304 assert_eq!(real_data, unsafe {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
305 CBinaryData::as_binary_data(bin_answer.data().unwrap())
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
306 });
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
307 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
308
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
309 #[test]
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
310 #[ignore]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
311 fn test_binary_answer_too_big() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
312 let big_data: Vec<u8> = vec![0xFFu8; 0x1_0000_0001];
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
313 let mut answer: CHeapBox<Answer> = CHeapBox::default();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
314 BinaryAnswer::fill(&mut answer, (&big_data, 100)).expect_err("this is too big!");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
315 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
316 }