Mercurial > crates > nonstick
comparison src/libpam/question.rs @ 141:a508a69c068a
Remove a lot of Results from functions.
Many functions are documented to only return failing Results when given
improper inputs or when there is a memory allocation failure (which
can be verified by looking at the source). In cases where we know our
input is correct, we don't need to check for memory allocation errors
for the same reason that Rust doesn't do so when you, e.g., create a
new Vec.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sat, 05 Jul 2025 17:16:56 -0400 |
parents | 33b9622ed6d2 |
children | ebb71a412b58 |
comparison
equal
deleted
inserted
replaced
140:add7228adb2f | 141:a508a69c068a |
---|---|
1 //! Data and types dealing with PAM messages. | 1 //! Data and types dealing with PAM messages. |
2 | 2 |
3 #[cfg(feature = "linux-pam-ext")] | |
4 use crate::conv::{BinaryQAndA, RadioQAndA}; | |
5 use libpam_sys_helpers::memory::{BinaryPayload, TooBigError}; | |
6 use crate::conv::{ErrorMsg, Exchange, InfoMsg, MaskedQAndA, QAndA}; | 3 use crate::conv::{ErrorMsg, Exchange, InfoMsg, MaskedQAndA, QAndA}; |
7 use crate::libpam::conversation::OwnedExchange; | 4 use crate::libpam::conversation::OwnedExchange; |
8 use crate::libpam::memory::{CHeapBox, CHeapPayload, CHeapString}; | 5 use crate::libpam::memory; |
9 use crate::ErrorCode; | 6 use crate::ErrorCode; |
10 use crate::Result; | 7 use crate::Result; |
8 use libpam_sys_helpers::memory as pammem; | |
11 use num_enum::{IntoPrimitive, TryFromPrimitive}; | 9 use num_enum::{IntoPrimitive, TryFromPrimitive}; |
12 use std::ffi::{c_int, c_void, CStr}; | 10 use std::ffi::{c_int, c_void, CStr}; |
13 use std::ptr::NonNull; | 11 use std::ptr::NonNull; |
14 | 12 |
15 mod style_const { | 13 mod style_const { |
82 | 80 |
83 /// Gets this message's data pointer as borrowed binary data. | 81 /// Gets this message's data pointer as borrowed binary data. |
84 unsafe fn binary_data(&self) -> (&[u8], u8) { | 82 unsafe fn binary_data(&self) -> (&[u8], u8) { |
85 self.data | 83 self.data |
86 .as_ref() | 84 .as_ref() |
87 .map(|data| BinaryPayload::contents(data.as_ptr().cast())) | 85 .map(|data| pammem::BinaryPayload::contents(data.as_ptr().cast())) |
88 .unwrap_or_default() | 86 .unwrap_or_default() |
89 } | 87 } |
90 } | 88 } |
91 | 89 |
92 impl TryFrom<&Exchange<'_>> for Question { | 90 impl TryFrom<&Exchange<'_>> for Question { |
93 type Error = ErrorCode; | 91 type Error = ErrorCode; |
94 fn try_from(msg: &Exchange) -> Result<Self> { | 92 fn try_from(msg: &Exchange) -> Result<Self> { |
95 let alloc = |style, text| -> Result<_> { | 93 let alloc = |style, text| -> Result<_> { |
96 Ok((style, unsafe { | 94 Ok((style, unsafe { |
97 CHeapBox::cast(CHeapString::new(text)?.into_box()) | 95 memory::CHeapBox::cast(memory::CHeapString::new(text)?.into_box()) |
98 })) | 96 })) |
99 }; | 97 }; |
100 // We will only allocate heap data if we have a valid input. | 98 // We will only allocate heap data if we have a valid input. |
101 let (style, data): (_, CHeapBox<c_void>) = match *msg { | 99 let (style, data): (_, memory::CHeapBox<c_void>) = match *msg { |
102 Exchange::MaskedPrompt(p) => alloc(Style::PromptEchoOff, p.question()), | 100 Exchange::MaskedPrompt(p) => alloc(Style::PromptEchoOff, p.question()), |
103 Exchange::Prompt(p) => alloc(Style::PromptEchoOn, p.question()), | 101 Exchange::Prompt(p) => alloc(Style::PromptEchoOn, p.question()), |
104 Exchange::Error(p) => alloc(Style::ErrorMsg, p.question()), | 102 Exchange::Error(p) => alloc(Style::ErrorMsg, p.question()), |
105 Exchange::Info(p) => alloc(Style::TextInfo, p.question()), | 103 Exchange::Info(p) => alloc(Style::TextInfo, p.question()), |
106 #[cfg(feature = "linux-pam-ext")] | 104 #[cfg(feature = "linux-pam-ext")] |
107 Exchange::RadioPrompt(p) => alloc(Style::RadioType, p.question()), | 105 Exchange::RadioPrompt(p) => alloc(Style::RadioType, p.question()), |
108 #[cfg(feature = "linux-pam-ext")] | 106 #[cfg(feature = "linux-pam-ext")] |
109 Exchange::BinaryPrompt(p) => { | 107 Exchange::BinaryPrompt(p) => { |
110 let (data, typ) = p.question(); | 108 let (data, typ) = p.question(); |
111 let payload = CHeapPayload::new(data, typ)?.into_inner(); | 109 let payload = memory::CHeapPayload::new(data, typ)?.into_inner(); |
112 Ok((Style::BinaryPrompt, unsafe { CHeapBox::cast(payload) })) | 110 Ok((Style::BinaryPrompt, unsafe { |
113 }, | 111 memory::CHeapBox::cast(payload) |
112 })) | |
113 } | |
114 #[cfg(not(feature = "linux-pam-ext"))] | 114 #[cfg(not(feature = "linux-pam-ext"))] |
115 Exchange::RadioPrompt(_) | Exchange::BinaryPrompt(_) => { | 115 Exchange::RadioPrompt(_) | Exchange::BinaryPrompt(_) => { |
116 Err(ErrorCode::ConversationError) | 116 Err(ErrorCode::ConversationError) |
117 } | 117 } |
118 }?; | 118 }?; |
119 Ok(Self { | 119 Ok(Self { |
120 style: style.into(), | 120 style: style.into(), |
121 data: Some(CHeapBox::into_ptr(data)), | 121 data: Some(memory::CHeapBox::into_ptr(data)), |
122 }) | 122 }) |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 impl Drop for Question { | 126 impl Drop for Question { |
134 let _ = match style { | 134 let _ = match style { |
135 #[cfg(feature = "linux-pam-ext")] | 135 #[cfg(feature = "linux-pam-ext")] |
136 Style::BinaryPrompt => self | 136 Style::BinaryPrompt => self |
137 .data | 137 .data |
138 .as_mut() | 138 .as_mut() |
139 .map(|p| BinaryPayload::zero(p.as_ptr().cast())), | 139 .map(|p| pammem::BinaryPayload::zero(p.as_ptr().cast())), |
140 #[cfg(feature = "linux-pam-ext")] | 140 #[cfg(feature = "linux-pam-ext")] |
141 Style::RadioType => self | 141 Style::RadioType => self |
142 .data | 142 .data |
143 .as_mut() | 143 .as_mut() |
144 .map(|p| CHeapString::zero(p.cast())), | 144 .map(|p| memory::CHeapString::zero(p.cast())), |
145 Style::TextInfo | 145 Style::TextInfo |
146 | Style::ErrorMsg | 146 | Style::ErrorMsg |
147 | Style::PromptEchoOff | 147 | Style::PromptEchoOff |
148 | Style::PromptEchoOn => { | 148 | Style::PromptEchoOn => self |
149 self.data.as_mut().map(|p| CHeapString::zero(p.cast())) | 149 .data |
150 } | 150 .as_mut() |
151 .map(|p| memory::CHeapString::zero(p.cast())), | |
151 }; | 152 }; |
152 }; | 153 }; |
153 let _ = self.data.map(|p| CHeapBox::from_ptr(p)); | 154 let _ = self.data.map(|p| memory::CHeapBox::from_ptr(p)); |
154 } | 155 } |
155 } | 156 } |
156 } | 157 } |
157 | 158 |
158 impl<'a> TryFrom<&'a Question> for OwnedExchange<'a> { | 159 impl<'a> TryFrom<&'a Question> for OwnedExchange<'a> { |
171 } | 172 } |
172 Style::PromptEchoOn => Self::Prompt(QAndA::new(question.string_data()?)), | 173 Style::PromptEchoOn => Self::Prompt(QAndA::new(question.string_data()?)), |
173 Style::ErrorMsg => Self::Error(ErrorMsg::new(question.string_data()?)), | 174 Style::ErrorMsg => Self::Error(ErrorMsg::new(question.string_data()?)), |
174 Style::TextInfo => Self::Info(InfoMsg::new(question.string_data()?)), | 175 Style::TextInfo => Self::Info(InfoMsg::new(question.string_data()?)), |
175 #[cfg(feature = "linux-pam-ext")] | 176 #[cfg(feature = "linux-pam-ext")] |
176 Style::RadioType => Self::RadioPrompt(RadioQAndA::new(question.string_data()?)), | 177 Style::RadioType => { |
178 Self::RadioPrompt(crate::conv::RadioQAndA::new(question.string_data()?)) | |
179 } | |
177 #[cfg(feature = "linux-pam-ext")] | 180 #[cfg(feature = "linux-pam-ext")] |
178 Style::BinaryPrompt => Self::BinaryPrompt(BinaryQAndA::new(question.binary_data())), | 181 Style::BinaryPrompt => { |
182 Self::BinaryPrompt(crate::conv::BinaryQAndA::new(question.binary_data())) | |
183 } | |
179 } | 184 } |
180 }; | 185 }; |
181 Ok(prompt) | 186 Ok(prompt) |
182 } | 187 } |
183 } | 188 } |
184 | 189 |
185 #[cfg(feature = "linux-pam-ext")] | 190 #[cfg(feature = "linux-pam-ext")] |
186 impl From<TooBigError> for ErrorCode { | 191 impl From<pammem::TooBigError> for ErrorCode { |
187 fn from(_: TooBigError) -> Self { | 192 fn from(_: pammem::TooBigError) -> Self { |
188 ErrorCode::BufferError | 193 ErrorCode::BufferError |
189 } | 194 } |
190 } | 195 } |
191 | 196 |
192 #[cfg(test)] | 197 #[cfg(test)] |
223 } | 228 } |
224 | 229 |
225 #[test] | 230 #[test] |
226 #[cfg(feature = "linux-pam-ext")] | 231 #[cfg(feature = "linux-pam-ext")] |
227 fn linux_extensions() { | 232 fn linux_extensions() { |
233 use crate::conv::{BinaryQAndA, RadioQAndA}; | |
228 assert_matches!( | 234 assert_matches!( |
229 (Exchange::BinaryPrompt, (&[5, 4, 3, 2, 1][..], 66)), | 235 (Exchange::BinaryPrompt, (&[5, 4, 3, 2, 1][..], 66)), |
230 BinaryQAndA::new((&[5, 4, 3, 2, 1], 66)) | 236 BinaryQAndA::new((&[5, 4, 3, 2, 1], 66)) |
231 ); | 237 ); |
232 assert_matches!( | 238 assert_matches!( |