annotate src/libpam/answer.rs @ 143:ebb71a412b58

Turn everything into OsString and Just Walk Out! for strings with nul. To reduce the hazard surface of the API, this replaces most uses of &str with &OsStr (and likewise with String/OsString). Also, I've decided that instead of dealing with callers putting `\0` in their parameters, I'm going to follow the example of std::env and Just Walk Out! (i.e., panic!()). This makes things a lot less annoying for both me and (hopefully) users.
author Paul Fisher <paul@pfish.zone>
date Sat, 05 Jul 2025 22:12:46 -0400
parents 33b9622ed6d2
children 8f964b701652
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
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
3 use crate::libpam::conversation::OwnedExchange;
75
c30811b4afae rename pam_ffi submodule to libpam.
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
4 use crate::libpam::memory;
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
5 use crate::libpam::memory::{CHeapBox, CHeapPayload, CHeapString, Immovable};
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
6 use crate::{ErrorCode, Result};
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
7 use libpam_sys_helpers::memory::BinaryPayload;
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
8 use std::ffi::{c_int, c_void, CStr, OsStr};
101
94b51fa4f797 Fix memory soundness issues:
Paul Fisher <paul@pfish.zone>
parents: 100
diff changeset
9 use std::mem::ManuallyDrop;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
10 use std::ops::{Deref, DerefMut};
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
11 use std::os::unix::ffi::OsStrExt;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
12 use std::ptr::NonNull;
101
94b51fa4f797 Fix memory soundness issues:
Paul Fisher <paul@pfish.zone>
parents: 100
diff changeset
13 use std::{iter, ptr, slice};
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
14
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
15 /// 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
16 #[derive(Debug)]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
17 pub struct Answers {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
18 /// 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
19 /// 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
20 base: NonNull<Answer>,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
21 count: usize,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
22 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
23
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
24 impl Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
25 /// Builds an Answers out of the given answered Message Q&As.
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
26 pub fn build(value: Vec<OwnedExchange>) -> Result<Self> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
27 let mut outputs = Self {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
28 base: memory::calloc(value.len()),
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
29 count: value.len(),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
30 };
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
31 // 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
32 // all allocated answer memory.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
33 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
34 match input {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
35 OwnedExchange::MaskedPrompt(p) => TextAnswer::fill(output, &p.answer()?)?,
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
36 OwnedExchange::Prompt(p) => TextAnswer::fill(output, &p.answer()?)?,
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
37 OwnedExchange::Error(p) => {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
38 TextAnswer::fill(output, p.answer().map(|_| "".as_ref())?)?
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
39 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
40 OwnedExchange::Info(p) => {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
41 TextAnswer::fill(output, p.answer().map(|_| "".as_ref())?)?
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
42 }
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
43 // 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
44 // question from PAM, so we're OK to answer it.
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
45 OwnedExchange::RadioPrompt(p) => TextAnswer::fill(output, &(p.answer()?))?,
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
46 OwnedExchange::BinaryPrompt(p) => {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
47 BinaryAnswer::fill(output, (&p.answer()?).into())?
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
48 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
49 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
50 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
51 Ok(outputs)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
52 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
53
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
54 /// 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
55 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
56 /// 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
57 /// It can be recreated with [`Self::from_c_heap`].
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
58 pub fn into_ptr(self) -> *mut libpam_sys::pam_response {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
59 ManuallyDrop::new(self).base.as_ptr().cast()
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
60 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
61
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
62 /// 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
63 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
64 /// # Safety
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 /// 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
67 /// like one that you got from PAM, or maybe [`Self::into_ptr`].
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
68 pub unsafe fn from_c_heap(base: NonNull<libpam_sys::pam_response>, count: usize) -> Self {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
69 Answers {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
70 base: NonNull::new_unchecked(base.as_ptr().cast()),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
71 count,
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
72 }
78
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
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76 impl Deref for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
77 type Target = [Answer];
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
78 fn deref(&self) -> &Self::Target {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
79 // 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
80 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
81 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
82 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
83
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
84 impl DerefMut for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
85 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
86 // 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
87 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
88 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
89 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
90
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
91 impl Drop for Answers {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
92 fn drop(&mut self) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
93 // 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
94 // 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
95 unsafe {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
96 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
97 ptr::drop_in_place(answer)
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
98 }
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
99 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
100 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
101 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
102 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
103
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
104 /// Generic version of answer data.
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
105 ///
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
106 /// This has the same structure as [`BinaryAnswer`] and [`TextAnswer`].
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
107 #[repr(C)]
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
108 #[derive(Debug, Default)]
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
109 pub struct Answer {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
110 /// Owned pointer to the data returned in an answer.
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
111 /// For most answers, this will be a
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
112 /// [`CHeapString`](CHeapString), but for
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
113 /// [`BinaryQAndA`](crate::conv::BinaryQAndA)s (a Linux-PAM extension),
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
114 /// this will be a [`CHeapBox`] of
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
115 /// [`CBinaryData`](crate::libpam::memory::CBinaryData).
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
116 pub data: Option<CHeapBox<c_void>>,
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
117 /// Unused. Just here for the padding.
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
118 return_code: c_int,
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
119 _marker: Immovable,
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
120 }
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
121
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
122 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
123 #[derive(Debug)]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
124 pub struct TextAnswer(Answer);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
125
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
126 impl TextAnswer {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
127 /// 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
128 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
129 /// # Safety
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
130 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
131 /// 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
132 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
133 // 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
134 &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
135 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
136
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
137 /// Converts the `Answer` to a `TextAnswer` with the given text.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
138 fn fill(dest: &mut Answer, text: &OsStr) -> Result<()> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
139 let allocated = CHeapString::new(text.as_bytes());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
140 let _ = dest
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
141 .data
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
142 .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
143 Ok(())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
144 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
145
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
146 /// 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
147 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
148 match self.0.data.as_ref() {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
149 None => Ok(""),
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
150 Some(data) => {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
151 // 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
152 // 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
153 // 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
154 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
155 .to_str()
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
156 .map_err(|_| ErrorCode::ConversationError)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
157 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
158 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
159 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
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 /// 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
162 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
163 /// 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
164 /// 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
165 /// 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
166 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
167 // 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
168 // 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
169 // 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
170 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
171 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
172 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
173 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
174 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
175 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
176 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
177
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
178 /// A [`Answer`] with [`CBinaryData`] in it.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
179 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
180 #[derive(Debug)]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
181 pub struct BinaryAnswer(Answer);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
182
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
183 impl BinaryAnswer {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
184 /// 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
185 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
186 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
187 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
188 /// 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
189 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
190 // 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
191 &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
192 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
193
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
194 /// 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
195 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
196 /// 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
197 /// It is passed through PAM unchanged.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
198 ///
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
199 /// 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
200 /// We do not take ownership of the original data.
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
201 pub fn fill(dest: &mut Answer, (data, type_): (&[u8], u8)) -> Result<()> {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
202 let payload = CHeapPayload::new(data, type_).map_err(|_| ErrorCode::BufferError)?;
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
203 let _ = dest
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
204 .data
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
205 .replace(unsafe { CHeapBox::cast(payload.into_inner()) });
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
206 Ok(())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
207 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
208
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
209 /// Gets the binary data in this answer.
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
210 pub fn contents(&self) -> Option<(&[u8], u8)> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
211 // 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
212 // 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
213 self.0
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
214 .data
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
215 .as_ref()
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
216 .map(|data| unsafe { BinaryPayload::contents(CHeapBox::as_ptr(data).cast().as_ptr()) })
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
217 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
218
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
219 /// 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
220 ///
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
221 /// 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
222 /// 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
223 /// 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
224 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
225 // SAFETY: We know that our data pointer is either valid or null.
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
226 if let Some(data) = self.0.data.as_mut() {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
227 unsafe {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
228 let total = BinaryPayload::total_bytes(CHeapBox::as_ptr(data).cast().as_ref());
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
229 let data: &mut [u8] =
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
230 slice::from_raw_parts_mut(CHeapBox::as_raw_ptr(data).cast(), total);
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
231 data.fill(0)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
232 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
233 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
234 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
235 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
236
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
237 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
238 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
239 use super::*;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
240 use crate::conv::{ErrorMsg, InfoMsg, MaskedQAndA, QAndA};
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 macro_rules! answered {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
243 ($typ:ty, $msg:path, $data:expr) => {{
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
244 let qa = <$typ>::new("".as_ref());
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
245 qa.set_answer(Ok($data));
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
246 $msg(qa)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
247 }};
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
248 }
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 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
251 let up = unsafe { TextAnswer::upcast(answer) };
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
252 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
253 up.zero_contents();
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
254 assert_eq!("", up.contents().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
255 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
256
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
257 fn round_trip(exchanges: Vec<OwnedExchange>) -> Answers {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
258 let n = exchanges.len();
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
259 let sent = Answers::build(exchanges).unwrap();
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
260 unsafe { Answers::from_c_heap(NonNull::new_unchecked(sent.into_ptr()), n) }
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
261 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
262
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
263 #[test]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
264 fn test_round_trip() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
265 let mut answers = round_trip(vec![
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
266 answered!(QAndA, OwnedExchange::Prompt, "whats going on".into()),
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
267 answered!(MaskedQAndA, OwnedExchange::MaskedPrompt, "well then".into()),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
268 answered!(ErrorMsg, OwnedExchange::Error, ()),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
269 answered!(InfoMsg, OwnedExchange::Info, ()),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
270 ]);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
271
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
272 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
273 assert_text_answer("whats going on", going);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
274 assert_text_answer("well then", well);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
275 assert_text_answer("", err);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
276 assert_text_answer("", info);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
277 } else {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
278 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
279 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
280 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
281
108
e97534be35e3 Make some proc macros for doing cfg-like stuff for PAM impls.
Paul Fisher <paul@pfish.zone>
parents: 101
diff changeset
282 #[cfg(feature = "linux-pam-ext")]
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
283 fn test_round_trip_linux() {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
284 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
285 let binary_msg = {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
286 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
287 qa.set_answer(Ok(BinaryData::new(vec![1, 2, 3], 99)));
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 108
diff changeset
288 OwnedExchange::BinaryPrompt(qa)
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
289 };
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
290 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
291 binary_msg,
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
292 answered!(RadioQAndA, OwnedExchange::RadioPrompt, "beep boop".into()),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
293 ]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
294
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
295 if let [bin, radio] = &mut answers[..] {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
296 let up = unsafe { BinaryAnswer::upcast(bin) };
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
297 assert_eq!((&[1, 2, 3][..], 99), up.contents().unwrap());
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
298 up.zero_contents();
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
299 assert_eq!((&[][..], 0), up.contents().unwrap());
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
300
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
301 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
302 } else {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
303 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
304 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
305 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
306
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
307 #[test]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
308 fn test_text_answer() {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
309 let mut answer: CHeapBox<Answer> = CHeapBox::default();
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
310 TextAnswer::fill(&mut answer, "hello".as_ref()).unwrap();
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
311 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
312 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
313 assert_eq!("hello", data);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
314 zeroth_text.zero_contents();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
315 zeroth_text.zero_contents();
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
316 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
317
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
318 #[test]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
319 #[should_panic]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
320 fn test_text_answer_nul() {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
321 TextAnswer::fill(&mut CHeapBox::default(), "hell\0".as_ref())
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
322 .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
323 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
324
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
325 #[test]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
326 fn test_binary_answer() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
327 use crate::conv::BinaryData;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
328 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
329 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
330 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
331 let bin_answer = unsafe { BinaryAnswer::upcast(&mut answer) };
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
332 assert_eq!(real_data, bin_answer.contents().unwrap().into());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
333 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
334
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
335 #[test]
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
336 #[ignore]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
337 fn test_binary_answer_too_big() {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
338 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
339 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
340 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
341 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
342 }