annotate src/libpam/message.rs @ 75:c30811b4afae

rename pam_ffi submodule to libpam.
author Paul Fisher <paul@pfish.zone>
date Fri, 06 Jun 2025 22:35:08 -0400
parents src/pam_ffi/message.rs@c7c596e6388f
children 351bdc13005e
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
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
3 use crate::constants::InvalidEnum;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
4 use crate::conv::Message;
75
c30811b4afae rename pam_ffi submodule to libpam.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
5 use crate::libpam::memory;
c30811b4afae rename pam_ffi submodule to libpam.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
6 use crate::libpam::memory::{CBinaryData, Immovable, NulError, TooBigError};
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
7 use num_derive::FromPrimitive;
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
8 use num_traits::FromPrimitive;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
9 use std::ffi::{c_int, c_void, CStr};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
10 use std::result::Result as StdResult;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
11 use std::str::Utf8Error;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
12 use std::{ptr, slice};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
13
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
14 #[derive(Debug, thiserror::Error)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
15 #[error("error creating PAM message: {0}")]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
16 pub enum ConversionError {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
17 InvalidEnum(#[from] InvalidEnum<Style>),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
18 Utf8Error(#[from] Utf8Error),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
19 NulError(#[from] NulError),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
20 TooBigError(#[from] TooBigError),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
21 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
22
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
23 /// The C enum values for messages shown to the user.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
24 #[derive(Debug, PartialEq, FromPrimitive)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
25 pub enum Style {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
26 /// Requests information from the user; will be masked when typing.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
27 PromptEchoOff = 1,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
28 /// Requests information from the user; will not be masked.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
29 PromptEchoOn = 2,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
30 /// An error message.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
31 ErrorMsg = 3,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
32 /// An informational message.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
33 TextInfo = 4,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
34 /// Yes/No/Maybe conditionals. A Linux-PAM extension.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
35 RadioType = 5,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
36 /// For server–client non-human interaction.
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
37 ///
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
38 /// NOT part of the X/Open PAM specification.
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
39 /// A Linux-PAM extension.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
40 BinaryPrompt = 7,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
41 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
42
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
43 impl TryFrom<c_int> for Style {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
44 type Error = InvalidEnum<Self>;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
45 fn try_from(value: c_int) -> StdResult<Self, Self::Error> {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
46 Self::from_i32(value).ok_or(value.into())
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
47 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
48 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
49
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
50 impl From<Style> for c_int {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
51 fn from(val: Style) -> Self {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
52 val as Self
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
53 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
54 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
55
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
56 /// A message sent by PAM or a module to an application.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
57 /// This message, and its internal data, is owned by the creator
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
58 /// (either the module or PAM itself).
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
59 #[repr(C)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
60 pub struct RawMessage {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
61 /// The style of message to request.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
62 style: c_int,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
63 /// A description of the data requested.
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
64 ///
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
65 /// For most requests, this will be an owned [`CStr`], but for requests
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
66 /// with [`Style::BinaryPrompt`], this will be [`CBinaryData`]
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
67 /// (a Linux-PAM extension).
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
68 data: *mut c_void,
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
69 _marker: Immovable,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
70 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
71
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
72 impl RawMessage {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
73 pub fn set(&mut self, msg: Message) -> StdResult<(), ConversionError> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
74 let (style, data) = copy_to_heap(msg)?;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
75 self.clear();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
76 // SAFETY: We allocated this ourselves or were given it by PAM.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
77 // Otherwise, it's null, but free(null) is fine.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
78 unsafe { libc::free(self.data) };
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
79 self.style = style as c_int;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
80 self.data = data;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
81 Ok(())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
82 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
83
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
84 /// 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
85 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
86 /// # Safety
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
87 ///
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
88 /// It's up to you to pass this only on types with a string value.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
89 unsafe fn string_data(&self) -> StdResult<&str, Utf8Error> {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
90 if self.data.is_null() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
91 Ok("")
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
92 } else {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
93 CStr::from_ptr(self.data.cast()).to_str()
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
94 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
95 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
96
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
97 /// Zeroes out the data stored here.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
98 fn clear(&mut self) {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
99 // 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
100 // 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
101 unsafe {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
102 if let Ok(style) = Style::try_from(self.style) {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
103 match style {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
104 Style::BinaryPrompt => {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
105 if let Some(d) = self.data.cast::<CBinaryData>().as_mut() {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
106 d.zero_contents()
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
107 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
108 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
109 Style::TextInfo
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
110 | Style::RadioType
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
111 | Style::ErrorMsg
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
112 | Style::PromptEchoOff
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
113 | Style::PromptEchoOn => memory::zero_c_string(self.data),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
114 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
115 };
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
116 libc::free(self.data);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
117 self.data = ptr::null_mut();
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
118 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
119 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
120 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
121
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
122 /// Copies the contents of this message to the C heap.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
123 fn copy_to_heap(msg: Message) -> StdResult<(Style, *mut c_void), ConversionError> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
124 let alloc = |style, text| Ok((style, memory::malloc_str(text)?.cast()));
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
125 match msg {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
126 Message::MaskedPrompt(text) => alloc(Style::PromptEchoOff, text),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
127 Message::Prompt(text) => alloc(Style::PromptEchoOn, text),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
128 Message::RadioPrompt(text) => alloc(Style::RadioType, text),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
129 Message::ErrorMsg(text) => alloc(Style::ErrorMsg, text),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
130 Message::InfoMsg(text) => alloc(Style::TextInfo, text),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
131 Message::BinaryPrompt { data, data_type } => Ok((
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
132 Style::BinaryPrompt,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
133 (CBinaryData::alloc(data, data_type)?).cast(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
134 )),
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 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
137
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
138 /// Abstraction of a list-of-messages to be sent in a PAM conversation.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
139 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
140 /// On Linux-PAM and other compatible implementations, `messages`
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
141 /// is treated as a pointer-to-pointers, like `int argc, char **argv`.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
142 /// (In this situation, the value of `OwnedMessages.indirect` is
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
143 /// the pointer passed to `pam_conv`.)
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
144 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
145 /// ```text
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
146 /// ╔═ OwnedMsgs ═╗ points to ┌─ Indirect ─┐ ╔═ Message ═╗
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
147 /// ║ indirect ┄┄┄╫┄┄┄┄┄┄┄┄┄┄┄> │ base[0] ┄┄┄┼┄┄┄┄┄> ║ style ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
148 /// ║ count ║ │ base[1] ┄┄┄┼┄┄┄╮ ║ data ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
149 /// ╚═════════════╝ │ ... │ ┆ ╚═══════════╝
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
150 /// ┆
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
151 /// ┆ ╔═ Message ═╗
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
152 /// ╰┄┄> ║ style ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
153 /// ║ data ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
154 /// ╚═══════════╝
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
155 /// ```
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
156 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
157 /// On OpenPAM and other compatible implementations (like Solaris),
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
158 /// `messages` is a pointer-to-pointer-to-array. This appears to be
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
159 /// the correct implementation as required by the XSSO specification.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
160 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
161 /// ```text
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
162 /// ╔═ OwnedMsgs ═╗ points to ┌─ Indirect ─┐ ╔═ Message[] ═╗
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
163 /// ║ indirect ┄┄┄╫┄┄┄┄┄┄┄┄┄┄┄> │ base ┄┄┄┄┄┄┼┄┄┄┄┄> ║ style ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
164 /// ║ count ║ └────────────┘ ║ data ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
165 /// ╚═════════════╝ ╟─────────────╢
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
166 /// ║ style ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
167 /// ║ data ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
168 /// ╟─────────────╢
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
169 /// ║ ... ║
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
170 /// ```
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
171 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
172 /// ***THIS LIBRARY CURRENTLY SUPPORTS ONLY LINUX-PAM.***
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
173 pub struct OwnedMessages {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
174 /// An indirection to the messages themselves, stored on the C heap.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
175 indirect: *mut MessageIndirector,
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
176 /// The number of messages in the list.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
177 count: usize,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
178 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
179
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
180 impl OwnedMessages {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
181 /// Allocates data to store messages on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
182 pub fn alloc(count: usize) -> Self {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
183 Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
184 indirect: MessageIndirector::alloc(count),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
185 count,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
186 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
187 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
188
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
189 /// The pointer to the thing with the actual list.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
190 pub fn indirector(&self) -> *const MessageIndirector {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
191 self.indirect
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
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
194 pub fn iter(&self) -> impl Iterator<Item = &RawMessage> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
195 // SAFETY: we're iterating over an amount we know.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
196 unsafe { (*self.indirect).iter(self.count) }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
197 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
198
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
199 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut RawMessage> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
200 // SAFETY: we're iterating over an amount we know.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
201 unsafe { (*self.indirect).iter_mut(self.count) }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
202 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
203 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
204
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
205 impl Drop for OwnedMessages {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
206 fn drop(&mut self) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
207 // SAFETY: We are valid and have a valid pointer.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
208 // Once we're done, everything will be safe.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
209 unsafe {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
210 if let Some(indirect) = self.indirect.as_mut() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
211 indirect.free(self.count)
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
212 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
213 libc::free(self.indirect.cast());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
214 self.indirect = ptr::null_mut();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
215 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
216 }
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
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
219 /// An indirect reference to messages.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
220 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
221 /// This is kept separate to provide a place where we can separate
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
222 /// the pointer-to-pointer-to-list from pointer-to-list-of-pointers.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
223 #[repr(transparent)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
224 pub struct MessageIndirector {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
225 base: [*mut RawMessage; 0],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
226 _marker: Immovable,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
227 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
228
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
229 impl MessageIndirector {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
230 /// Allocates memory for this indirector and all its members.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
231 fn alloc(count: usize) -> *mut Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
232 // SAFETY: We're only allocating, and when we're done,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
233 // everything will be in a known-good state.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
234 unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
235 let me_ptr: *mut MessageIndirector =
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
236 libc::calloc(count, size_of::<*mut RawMessage>()).cast();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
237 let me = &mut *me_ptr;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
238 let ptr_list = slice::from_raw_parts_mut(me.base.as_mut_ptr(), count);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
239 for entry in ptr_list {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
240 *entry = libc::calloc(1, size_of::<RawMessage>()).cast();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
241 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
242 me
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
243 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
244 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
245
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
246 /// Returns an iterator yielding the given number of messages.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
247 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
248 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
249 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
250 /// You have to provide the right count.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
251 pub unsafe fn iter(&self, count: usize) -> impl Iterator<Item = &RawMessage> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
252 (0..count).map(|idx| &**self.base.as_ptr().add(idx))
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
253 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
254
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
255 /// Returns a mutable iterator yielding the given number of messages.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
256 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
257 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
258 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
259 /// You have to provide the right count.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
260 pub unsafe fn iter_mut(&mut self, count: usize) -> impl Iterator<Item = &mut RawMessage> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
261 (0..count).map(|idx| &mut **self.base.as_mut_ptr().add(idx))
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
262 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
263
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
264 /// Frees this and everything it points to.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
265 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
266 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
267 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
268 /// You have to pass the right size.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
269 unsafe fn free(&mut self, count: usize) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
270 let msgs = slice::from_raw_parts_mut(self.base.as_mut_ptr(), count);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
271 for msg in msgs {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
272 if let Some(msg) = msg.as_mut() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
273 msg.clear();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
274 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
275 libc::free(msg.cast());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
276 *msg = ptr::null_mut();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
277 }
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
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
281 impl<'a> TryFrom<&'a RawMessage> for Message<'a> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
282 type Error = ConversionError;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
283
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
284 /// Retrieves the data stored in this message.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
285 fn try_from(input: &RawMessage) -> StdResult<Message, ConversionError> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
286 let style: Style = input.style.try_into()?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
287 // SAFETY: We either allocated this message ourselves or were provided it by PAM.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
288 let result = unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
289 match style {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
290 Style::PromptEchoOff => Message::MaskedPrompt(input.string_data()?),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
291 Style::PromptEchoOn => Message::Prompt(input.string_data()?),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
292 Style::TextInfo => Message::InfoMsg(input.string_data()?),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
293 Style::ErrorMsg => Message::ErrorMsg(input.string_data()?),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
294 Style::RadioType => Message::ErrorMsg(input.string_data()?),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
295 Style::BinaryPrompt => input.data.cast::<CBinaryData>().as_ref().map_or_else(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
296 || Message::BinaryPrompt {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
297 data_type: 0,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
298 data: &[],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
299 },
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
300 |data| Message::BinaryPrompt {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
301 data_type: data.data_type(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
302 data: data.contents(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
303 },
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 }
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 Ok(result)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
308 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
309 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
310
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
311 #[cfg(test)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
312 mod tests {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
313 use crate::conv::Message;
75
c30811b4afae rename pam_ffi submodule to libpam.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
314 use crate::libpam::message::OwnedMessages;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
315
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
316 #[test]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
317 fn test_owned_messages() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
318 let mut tons_of_messages = OwnedMessages::alloc(10);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
319 let mut msgs: Vec<_> = tons_of_messages.iter_mut().collect();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
320 assert!(msgs.get(10).is_none());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
321 let last_msg = &mut msgs[9];
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
322 last_msg.set(Message::MaskedPrompt("hocus pocus")).unwrap();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
323 let another_msg = &mut msgs[0];
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
324 another_msg
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
325 .set(Message::BinaryPrompt {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
326 data: &[5, 4, 3, 2, 1],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
327 data_type: 99,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
328 })
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
329 .unwrap();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
330 let overwrite = &mut msgs[3];
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
331 overwrite.set(Message::Prompt("what")).unwrap();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
332 overwrite.set(Message::Prompt("who")).unwrap();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
333 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
334 }