annotate src/libpam/question.rs @ 95:51c9d7e8261a

Return owned strings rather than borrowed strings. It's going to be irritating to have to work with strings borrowed from the PAM handle rather than just using your own. They're cheap enough to copy.
author Paul Fisher <paul@pfish.zone>
date Mon, 23 Jun 2025 14:03:44 -0400
parents efc2b56c8928
children b87100c5eed4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
1 //! Data and types dealing with PAM messages.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
2
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
3 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
4 use crate::conv::{BinaryQAndA, RadioQAndA};
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
5 use crate::conv::{ErrorMsg, InfoMsg, MaskedQAndA, Message, QAndA};
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
6 use crate::libpam::conversation::OwnedMessage;
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
7 use crate::libpam::memory::{CBinaryData, Immovable};
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
8 pub use crate::libpam::pam_ffi::Question;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
9 use crate::libpam::{memory, pam_ffi};
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
10 use crate::ErrorCode;
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
11 use crate::Result;
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
12 use num_enum::{IntoPrimitive, TryFromPrimitive};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
13 use std::ffi::{c_void, CStr};
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
14 use std::ptr::NonNull;
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
15 use std::{ptr, slice};
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
16
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
17 /// Abstraction of a collection of questions to be sent in a PAM conversation.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
18 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
19 /// The PAM C API conversation function looks like this:
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 /// ```c
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
22 /// int pam_conv(
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
23 /// int count,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
24 /// const struct pam_message **questions,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
25 /// struct pam_response **answers,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
26 /// void *appdata_ptr,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
27 /// )
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 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
30 /// On Linux-PAM and other compatible implementations, `questions`
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
31 /// is treated as a pointer-to-pointers, like `int argc, char **argv`.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
32 /// (In this situation, the value of `Questions.indirect` is
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
33 /// the pointer passed to `pam_conv`.)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
34 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
35 /// ```text
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
36 /// points to ┌───────────────┐ ╔═ Question ═╗
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
37 /// questions ┄┄┄┄┄┄┄┄┄┄> │ questions[0] ┄┼┄┄┄┄> ║ style ║
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
38 /// │ questions[1] ┄┼┄┄┄╮ ║ data ┄┄┄┄┄┄╫┄┄> ...
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
39 /// │ ... │ ┆ ╚════════════╝
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
40 /// ┆
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
41 /// ┆ ╔═ Question ═╗
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
42 /// ╰┄┄> ║ style ║
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
43 /// ║ data ┄┄┄┄┄┄╫┄┄> ...
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
44 /// ╚════════════╝
78
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 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
47 /// On OpenPAM and other compatible implementations (like Solaris),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
48 /// `messages` is a pointer-to-pointer-to-array. This appears to be
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
49 /// the correct implementation as required by the XSSO specification.
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 /// ```text
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
52 /// points to ┌─────────────┐ ╔═ Question[] ═╗
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
53 /// questions ┄┄┄┄┄┄┄┄┄┄> │ *questions ┄┼┄┄┄┄┄> ║ style ║
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
54 /// └─────────────┘ ║ data ┄┄┄┄┄┄┄┄╫┄┄> ...
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
55 /// ╟──────────────╢
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
56 /// ║ style ║
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
57 /// ║ data ┄┄┄┄┄┄┄┄╫┄┄> ...
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
58 /// ╟──────────────╢
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
59 /// ║ ... ║
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
60 /// ```
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
61 pub trait QuestionsTrait {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
62 /// Allocates memory for this indirector and all its members.
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
63 fn new(messages: &[Message]) -> Result<Self>
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
64 where
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
65 Self: Sized;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
66
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
67 /// Gets the pointer that is passed .
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
68 fn ptr(&self) -> *const *const Question;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
69
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
70 /// Converts a pointer into a borrowed list of Questions.
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
71 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
72 /// # Safety
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
73 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
74 /// You have to provide a valid pointer.
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
75 unsafe fn borrow_ptr<'a>(
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
76 ptr: *const *const Question,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
77 count: usize,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
78 ) -> impl Iterator<Item = &'a Question>;
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
79 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
81 #[cfg(pam_impl = "linux-pam")]
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
82 pub type Questions = LinuxPamQuestions;
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
83
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
84 #[cfg(not(pam_impl = "linux-pam"))]
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
85 pub type Questions = XSsoQuestions;
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
86
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
87 /// The XSSO standard version of the pointer train to questions.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
88 #[derive(Debug)]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
89 #[repr(C)]
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
90 pub struct XSsoQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
91 /// Points to the memory address where the meat of `questions` is.
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
92 /// **The memory layout of Vec is not specified**, and we need to return
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
93 /// a pointer to the pointer, hence we have to store it here.
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
94 pointer: *const Question,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
95 questions: Vec<Question>,
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
96 _marker: Immovable,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
97 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
98
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
99 impl XSsoQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
100 fn len(&self) -> usize {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
101 self.questions.len()
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
102 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
103 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Question> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
104 self.questions.iter_mut()
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
105 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
106 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
107
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
108 impl QuestionsTrait for XSsoQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
109 fn new(messages: &[Message]) -> Result<Self> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
110 let questions: Result<Vec<_>> = messages.iter().map(Question::try_from).collect();
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
111 let questions = questions?;
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
112 Ok(Self {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
113 pointer: questions.as_ptr(),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
114 questions,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
115 _marker: Default::default(),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
116 })
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
117 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
118
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
119 fn ptr(&self) -> *const *const Question {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
120 &self.pointer as *const *const Question
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
121 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
122
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
123 unsafe fn borrow_ptr<'a>(
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
124 ptr: *const *const Question,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
125 count: usize,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
126 ) -> impl Iterator<Item = &'a Question> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
127 slice::from_raw_parts(*ptr, count).iter()
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
128 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
129 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
130
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
131 /// The Linux version of the pointer train to questions.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
132 #[derive(Debug)]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
133 #[repr(C)]
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
134 pub struct LinuxPamQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
135 #[allow(clippy::vec_box)] // we need to do this.
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
136 /// The place where the questions are.
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
137 questions: Vec<Box<Question>>,
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
138 _marker: Immovable,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
139 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
140
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
141 impl LinuxPamQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
142 fn len(&self) -> usize {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
143 self.questions.len()
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
144 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
145
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
146 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Question> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
147 self.questions.iter_mut().map(AsMut::as_mut)
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
148 }
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
149 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
150
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
151 impl QuestionsTrait for LinuxPamQuestions {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
152 fn new(messages: &[Message]) -> Result<Self> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
153 let questions: Result<_> = messages
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
154 .iter()
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
155 .map(|msg| Question::try_from(msg).map(Box::new))
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
156 .collect();
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
157 Ok(Self {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
158 questions: questions?,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
159 _marker: Default::default(),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
160 })
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
161 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
162
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
163 fn ptr(&self) -> *const *const Question {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
164 self.questions.as_ptr().cast()
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
165 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
166
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
167 unsafe fn borrow_ptr<'a>(
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
168 ptr: *const *const Question,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
169 count: usize,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
170 ) -> impl Iterator<Item = &'a Question> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
171 slice::from_raw_parts(ptr.cast::<&Question>(), count)
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
172 .iter()
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
173 .copied()
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
174 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
175 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
176
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
177 /// The C enum values for messages shown to the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
178 #[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive)]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
179 #[repr(u32)]
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
180 enum Style {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
181 /// Requests information from the user; will be masked when typing.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
182 PromptEchoOff = pam_ffi::PAM_PROMPT_ECHO_OFF,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
183 /// Requests information from the user; will not be masked.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
184 PromptEchoOn = pam_ffi::PAM_PROMPT_ECHO_ON,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
185 /// An error message.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
186 ErrorMsg = pam_ffi::PAM_ERROR_MSG,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
187 /// An informational message.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
188 TextInfo = pam_ffi::PAM_TEXT_INFO,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
189 /// Yes/No/Maybe conditionals. A Linux-PAM extension.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
190 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
191 RadioType = pam_ffi::PAM_RADIO_TYPE,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
192 /// For server–client non-human interaction.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
193 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
194 /// NOT part of the X/Open PAM specification.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
195 /// A Linux-PAM extension.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
196 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
197 BinaryPrompt = pam_ffi::PAM_BINARY_PROMPT,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
198 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
199
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
200 impl Question {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
201 /// Gets this message's data pointer as a string.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
202 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
203 /// # Safety
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
204 ///
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
205 /// It's up to you to pass this only on types with a string value.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
206 unsafe fn string_data(&self) -> Result<&str> {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
207 if self.data.is_null() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
208 Ok("")
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
209 } else {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
210 CStr::from_ptr(self.data.cast())
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
211 .to_str()
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
212 .map_err(|_| ErrorCode::ConversationError)
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
213 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
214 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
215
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
216 /// Gets this message's data pointer as borrowed binary data.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
217 unsafe fn binary_data(&self) -> (&[u8], u8) {
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
218 NonNull::new(self.data)
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
219 .map(|nn| nn.cast())
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
220 .map(|ptr| CBinaryData::data(ptr))
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
221 .unwrap_or_default()
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
222 }
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
223 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
224
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
225 impl TryFrom<&Message<'_>> for Question {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
226 type Error = ErrorCode;
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
227 fn try_from(msg: &Message) -> Result<Self> {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
228 let alloc = |style, text| Ok((style, memory::malloc_str(text)?.cast()));
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
229 // We will only allocate heap data if we have a valid input.
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
230 let (style, data): (_, NonNull<c_void>) = match *msg {
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
231 Message::MaskedPrompt(p) => alloc(Style::PromptEchoOff, p.question()),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
232 Message::Prompt(p) => alloc(Style::PromptEchoOn, p.question()),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
233 Message::Error(p) => alloc(Style::ErrorMsg, p.question()),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
234 Message::Info(p) => alloc(Style::TextInfo, p.question()),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
235 #[cfg(feature = "linux-pam-extensions")]
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
236 Message::RadioPrompt(p) => alloc(Style::RadioType, p.question()),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
237 #[cfg(feature = "linux-pam-extensions")]
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
238 Message::BinaryPrompt(p) => Ok((
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
239 Style::BinaryPrompt,
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
240 CBinaryData::alloc(p.question())?.cast(),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
241 )),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
242 #[cfg(not(feature = "linux-pam-extensions"))]
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
243 Message::RadioPrompt(_) | Message::BinaryPrompt(_) => Err(ErrorCode::ConversationError),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
244 }?;
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
245 Ok(Self {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
246 style: style.into(),
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
247 data: data.as_ptr(),
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
248 _marker: Default::default(),
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
249 })
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
250 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
251 }
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
252
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
253 impl Drop for Question {
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
254 fn drop(&mut self) {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
255 // SAFETY: We either created this data or we got it from PAM.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
256 // After this function is done, it will be zeroed out.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
257 unsafe {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
258 // This is nice-to-have. We'll try to zero out the data
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
259 // in the Question. If it's not a supported format, we skip it.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
260 if let Ok(style) = Style::try_from(self.style) {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
261 match style {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
262 #[cfg(feature = "linux-pam-extensions")]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
263 Style::BinaryPrompt => {
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
264 if let Some(d) = NonNull::new(self.data) {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
265 CBinaryData::zero_contents(d.cast())
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
266 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
267 }
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
268 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
269 Style::RadioType => memory::zero_c_string(self.data.cast()),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
270 Style::TextInfo
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
271 | Style::ErrorMsg
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
272 | Style::PromptEchoOff
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
273 | Style::PromptEchoOn => memory::zero_c_string(self.data.cast()),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
274 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
275 };
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
276 memory::free(self.data);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
277 self.data = ptr::null_mut();
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
278 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
279 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
280 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
281
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
282 impl<'a> TryFrom<&'a Question> for OwnedMessage<'a> {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
283 type Error = ErrorCode;
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
284 fn try_from(question: &'a Question) -> Result<Self> {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
285 let style: Style = question
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
286 .style
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
287 .try_into()
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
288 .map_err(|_| ErrorCode::ConversationError)?;
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
289 // SAFETY: In all cases below, we're creating questions based on
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
290 // known types that we get from PAM and the inner types it should have.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
291 let prompt = unsafe {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
292 match style {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
293 Style::PromptEchoOff => {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
294 Self::MaskedPrompt(MaskedQAndA::new(question.string_data()?))
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
295 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
296 Style::PromptEchoOn => Self::Prompt(QAndA::new(question.string_data()?)),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
297 Style::ErrorMsg => Self::Error(ErrorMsg::new(question.string_data()?)),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
298 Style::TextInfo => Self::Info(InfoMsg::new(question.string_data()?)),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
299 #[cfg(feature = "linux-pam-extensions")]
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
300 Style::RadioType => Self::RadioPrompt(RadioQAndA::new(question.string_data()?)),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
301 #[cfg(feature = "linux-pam-extensions")]
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
302 Style::BinaryPrompt => Self::BinaryPrompt(BinaryQAndA::new(question.binary_data())),
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
303 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
304 };
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
305 Ok(prompt)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
306 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
307 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
308
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
309 #[cfg(test)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
310 mod tests {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
311
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
312 macro_rules! assert_matches {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
313 ($id:ident => $variant:path, $q:expr) => {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
314 if let $variant($id) = $id {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
315 assert_eq!($q, $id.question());
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
316 } else {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
317 panic!("mismatched enum variant {x:?}", x = $id);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
318 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
319 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
320 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
321
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
322 macro_rules! tests { ($fn_name:ident<$typ:ident>) => {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
323 mod $fn_name {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
324 use super::super::*;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
325 #[test]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
326 fn standard() {
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
327 let interrogation = <$typ>::new(&[
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
328 MaskedQAndA::new("hocus pocus").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
329 QAndA::new("what").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
330 QAndA::new("who").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
331 InfoMsg::new("hey").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
332 ErrorMsg::new("gasp").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
333 ])
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
334 .unwrap();
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
335 let indirect = interrogation.ptr();
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
336
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
337 let remade = unsafe { $typ::borrow_ptr(indirect, interrogation.len()) };
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
338 let messages: Vec<OwnedMessage> = remade
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
339 .map(TryInto::try_into)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
340 .collect::<Result<_>>()
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
341 .unwrap();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
342 let [masked, what, who, hey, gasp] = messages.try_into().unwrap();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
343 assert_matches!(masked => OwnedMessage::MaskedPrompt, "hocus pocus");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
344 assert_matches!(what => OwnedMessage::Prompt, "what");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
345 assert_matches!(who => OwnedMessage::Prompt, "who");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
346 assert_matches!(hey => OwnedMessage::Info, "hey");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
347 assert_matches!(gasp => OwnedMessage::Error, "gasp");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
348 }
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
349
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
350 #[test]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
351 #[cfg(not(feature = "linux-pam-extensions"))]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
352 fn no_linux_extensions() {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
353 use crate::conv::{BinaryQAndA, RadioQAndA};
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
354 <$typ>::new(&[
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
355 BinaryQAndA::new((&[5, 4, 3, 2, 1], 66)).message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
356 RadioQAndA::new("you must choose").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
357 ]).unwrap_err();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
358 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
359
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
360 #[test]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
361 #[cfg(feature = "linux-pam-extensions")]
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
362 fn linux_extensions() {
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
363 let interrogation = <$typ>::new(&[
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
364 BinaryQAndA::new((&[5, 4, 3, 2, 1], 66)).message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
365 RadioQAndA::new("you must choose").message(),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
366 ]).unwrap();
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
367 let indirect = interrogation.ptr();
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
368
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
369 let remade = unsafe { $typ::borrow_ptr(indirect, interrogation.len()) };
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 89
diff changeset
370 let messages: Vec<OwnedMessage> = remade
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
371 .map(TryInto::try_into)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
372 .collect::<Result<_>>()
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
373 .unwrap();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
374 let [bin, choose] = messages.try_into().unwrap();
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
375 assert_matches!(bin => OwnedMessage::BinaryPrompt, (&[5, 4, 3, 2, 1][..], 66));
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
376 assert_matches!(choose => OwnedMessage::RadioPrompt, "you must choose");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 85
diff changeset
377 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
378 }
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
379 }}
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
380
89
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
381 tests!(test_xsso<XSsoQuestions>);
dd3e9c4bcde3 Simplify memory management in Questions.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
382 tests!(test_linux<LinuxPamQuestions>);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
383 }