annotate src/conv.rs @ 155:ab8020566cd9

Only use real PAM constants for logging within `nonstick/libpam`.
author Paul Fisher <paul@pfish.zone>
date Tue, 08 Jul 2025 00:49:38 -0400
parents 1bc52025156b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
1 //! The PAM conversation and associated Stuff.
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents: 59
diff changeset
2
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
3 // Temporarily allowed until we get the actual conversation functions hooked up.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
4 #![allow(dead_code)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
5
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
6 use crate::constants::{ErrorCode, Result};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
7 use std::cell::Cell;
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
8 use std::ffi::{OsStr, OsString};
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
9 use std::fmt;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
10 use std::fmt::Debug;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
11 use std::result::Result as StdResult;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
12
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
13 /// An individual pair of request/response to be sent to the user.
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
14 #[derive(Debug)]
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
15 #[non_exhaustive]
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
16 pub enum Exchange<'a> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
17 Prompt(&'a QAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
18 MaskedPrompt(&'a MaskedQAndA<'a>),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
19 Error(&'a ErrorMsg<'a>),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
20 Info(&'a InfoMsg<'a>),
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
21 RadioPrompt(&'a RadioQAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
22 BinaryPrompt(&'a BinaryQAndA<'a>),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
23 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
24
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
25 impl Exchange<'_> {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
26 /// Sets an error answer on this question, without having to inspect it.
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
27 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
28 /// Use this as a default match case:
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
29 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
30 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
31 /// use nonstick::conv::{Exchange, QAndA};
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
32 /// use nonstick::ErrorCode;
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
33 ///
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
34 /// fn cant_respond(message: Exchange) {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
35 /// // "question" is kind of a bad name in the context of
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
36 /// // a one-way message, but it's for consistency.
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
37 /// match message {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
38 /// Exchange::Info(i) => {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
39 /// eprintln!("fyi, {:?}", i.question());
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
40 /// i.set_answer(Ok(()))
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
41 /// }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
42 /// Exchange::Error(e) => {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
43 /// eprintln!("ERROR: {:?}", e.question());
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
44 /// e.set_answer(Ok(()))
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
45 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
46 /// // We can't answer any questions.
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
47 /// other => other.set_error(ErrorCode::ConversationError),
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
48 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
49 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
50 pub fn set_error(&self, err: ErrorCode) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
51 match *self {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
52 Exchange::Prompt(m) => m.set_answer(Err(err)),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
53 Exchange::MaskedPrompt(m) => m.set_answer(Err(err)),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
54 Exchange::Error(m) => m.set_answer(Err(err)),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
55 Exchange::Info(m) => m.set_answer(Err(err)),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
56 Exchange::RadioPrompt(m) => m.set_answer(Err(err)),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
57 Exchange::BinaryPrompt(m) => m.set_answer(Err(err)),
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
58 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
59 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
60 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
61
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
62 macro_rules! q_and_a {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
63 ($(#[$m:meta])* $name:ident<'a, Q=$qt:ty, A=$at:ty>, $val:path) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
64 $(#[$m])*
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
65 pub struct $name<'a> {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
66 q: $qt,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
67 a: Cell<Result<$at>>,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
68 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
69
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
70 $(#[$m])*
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
71 impl<'a> $name<'a> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
72 #[doc = concat!("Creates a `", stringify!($t), "` to be sent to the user.")]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
73 pub fn new(question: $qt) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
74 Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
75 q: question,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76 a: Cell::new(Err(ErrorCode::ConversationError)),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
77 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
78 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
79
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
80 /// Converts this Q&A into a [`Exchange`] for the [`Conversation`].
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
81 pub fn exchange(&self) -> Exchange<'_> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
82 $val(self)
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
83 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
84
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
85 /// The contents of the question being asked.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
86 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
87 /// For instance, this might say `"Username:"` to prompt the user
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
88 /// for their name, or the text of an error message.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
89 pub fn question(&self) -> $qt {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
90 self.q
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
91 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
92
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
93 /// Sets the answer to the question.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
94 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
95 /// The [`Conversation`] implementation calls this to set the answer.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
96 /// The conversation should *always call this function*,
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
97 /// even for Q&A messages that don't have "an answer"
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
98 /// (like error or info messages).
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
99 pub fn set_answer(&self, answer: Result<$at>) {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
100 self.a.set(answer)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
101 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
102
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
103 /// Gets the answer to the question.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
104 pub fn answer(self) -> Result<$at> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
105 self.a.into_inner()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
106 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
107 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
108
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
109 // shout out to stackoverflow user ballpointben for this lazy impl:
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
110 // https://stackoverflow.com/a/78871280/39808
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
111 $(#[$m])*
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
112 impl fmt::Debug for $name<'_> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> StdResult<(), fmt::Error> {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
114 f.debug_struct(stringify!($name)).field("q", &self.q).finish_non_exhaustive()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
115 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
116 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
117 };
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
118 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
119
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
120 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
121 /// A Q&A that asks the user for text and does not show it while typing.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
122 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
123 /// In other words, a password entry prompt.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
124 MaskedQAndA<'a, Q=&'a OsStr, A=OsString>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
125 Exchange::MaskedPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
126 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
127
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
128 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
129 /// A standard Q&A prompt that asks the user for text.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
130 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
131 /// This is the normal "ask a person a question" prompt.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
132 /// When the user types, their input will be shown to them.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
133 /// It can be used for things like usernames.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
134 QAndA<'a, Q=&'a OsStr, A=OsString>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
135 Exchange::Prompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
136 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
137
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
138 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
139 /// A Q&A for "radio button"–style data. (Linux-PAM extension)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
140 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
141 /// This message type is theoretically useful for "yes/no/maybe"
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
142 /// questions, but nowhere in the documentation is it specified
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
143 /// what the format of the answer will be, or how this should be shown.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
144 RadioQAndA<'a, Q=&'a OsStr, A=OsString>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
145 Exchange::RadioPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
146 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
147
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
148 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
149 /// Asks for binary data. (Linux-PAM extension)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
150 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
151 /// This sends a binary message to the client application.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
152 /// It can be used to communicate with non-human logins,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
153 /// or to enable things like security keys.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
154 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
155 /// The `data_type` tag is a value that is simply passed through
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
156 /// to the application. PAM does not define any meaning for it.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
157 BinaryQAndA<'a, Q=(&'a [u8], u8), A=BinaryData>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
158 Exchange::BinaryPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
159 );
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
160
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
161 /// Owned binary data.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
162 #[derive(Debug, Default, PartialEq)]
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
163 pub struct BinaryData {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
164 /// The data.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
165 pub data: Vec<u8>,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
166 /// A tag describing the type of the data, to use how you please.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
167 pub data_type: u8,
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
168 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
169
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
170 impl BinaryData {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
171 /// Creates a `BinaryData` with the given contents and type.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
172 pub fn new(data: impl Into<Vec<u8>>, data_type: u8) -> Self {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
173 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
174 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
175 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
176 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
177 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
178 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
179
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
180 impl<IV: Into<Vec<u8>>> From<(IV, u8)> for BinaryData {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
181 /// Makes a new BinaryData from borrowed data.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
182 fn from((data, data_type): (IV, u8)) -> Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
183 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
184 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
185 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
186 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
187 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
188 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
189
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
190 impl From<BinaryData> for (Vec<u8>, u8) {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
191 /// Easy destructuring.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
192 fn from(value: BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
193 (value.data, value.data_type)
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
194 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
195 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
196
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
197 impl<'a> From<&'a BinaryData> for (&'a [u8], u8) {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
198 fn from(value: &'a BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
199 (&value.data, value.data_type)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
200 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
201 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
202
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
203 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
204 /// A message containing information to be passed to the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
205 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
206 /// While this does not have an answer, [`Conversation`] implementations
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
207 /// should still call [`set_answer`][`QAndA::set_answer`] to verify that
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
208 /// the message has been displayed (or actively discarded).
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
209 InfoMsg<'a, Q = &'a OsStr, A = ()>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
210 Exchange::Info
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
211 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
212
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
213 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
214 /// An error message to be passed to the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
215 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
216 /// While this does not have an answer, [`Conversation`] implementations
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
217 /// should still call [`set_answer`][`QAndA::set_answer`] to verify that
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
218 /// the message has been displayed (or actively discarded).
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
219 ErrorMsg<'a, Q = &'a OsStr, A = ()>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
220 Exchange::Error
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
221 );
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
222
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
223 /// A channel for PAM modules to request information from the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
224 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
225 /// This trait is used by both applications and PAM modules:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
226 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
227 /// - Applications implement Conversation and provide a user interface
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
228 /// to allow the user to respond to PAM questions.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
229 /// - Modules call a Conversation implementation to request information
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
230 /// or send information to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
231 pub trait Conversation {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
232 /// Sends messages to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
233 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
234 /// The returned Vec of messages always contains exactly as many entries
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
235 /// as there were messages in the request; one corresponding to each.
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
236 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
237 /// TODO: write detailed documentation about how to use this.
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
238 fn communicate(&self, messages: &[Exchange]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
239 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
240
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
241 /// Turns a simple function into a [`Conversation`].
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
242 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
243 /// This can be used to wrap a free-floating function for use as a
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
244 /// Conversation:
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
245 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
246 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
247 /// use nonstick::conv::{conversation_func, Conversation, Exchange};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
248 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
249 /// # use nonstick::Conversation;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
250 /// pub fn get_auth_data(conv: &mut impl Conversation) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
251 /// /* ... */
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
252 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
253 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
254 ///
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
255 /// fn my_terminal_prompt(messages: &[Exchange]) {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
256 /// // ...
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
257 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
258 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
259 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
260 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
261 /// some_library::get_auth_data(&mut conversation_func(my_terminal_prompt));
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
262 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
263 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
264 pub fn conversation_func(func: impl Fn(&[Exchange])) -> impl Conversation {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
265 FunctionConvo(func)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
266 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
267
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
268 struct FunctionConvo<C: Fn(&[Exchange])>(C);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
269
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
270 impl<C: Fn(&[Exchange])> Conversation for FunctionConvo<C> {
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
271 fn communicate(&self, messages: &[Exchange]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
272 self.0(messages)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
273 }
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
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
276 /// A Conversation
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
277 struct UsernamePasswordConvo {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
278 username: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
279 password: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
280 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
281
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
282 /// A conversation trait for asking or answering one question at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
283 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
284 /// An implementation of this is provided for any [`Conversation`],
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
285 /// or a PAM application can implement this trait and handle messages
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
286 /// one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
287 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
288 /// For example, to use a `Conversation` as a `ConversationAdapter`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
289 ///
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
290 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
291 /// # use nonstick::{Conversation, Result};
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
292 /// # use std::ffi::OsString;
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
293 /// // Bring this trait into scope to get `masked_prompt`, among others.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
294 /// use nonstick::ConversationAdapter;
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
295 ///
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
296 /// fn ask_for_token(convo: &impl Conversation) -> Result<OsString> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
297 /// convo.masked_prompt("enter your one-time token")
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
298 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
299 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
300 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
301 /// or to use a `ConversationAdapter` as a `Conversation`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
302 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
303 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
304 /// use nonstick::{Conversation, ConversationAdapter};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
305 /// # use nonstick::{BinaryData, Result};
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
306 /// # use std::ffi::{OsStr, OsString};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
307 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
308 /// # use nonstick::Conversation;
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
309 /// pub fn get_auth_data(conv: &impl Conversation) { /* ... */
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
310 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
311 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
312 ///
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
313 /// struct MySimpleConvo {/* ... */}
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
314 /// # impl MySimpleConvo { fn new() -> Self { Self{} } }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
315 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
316 /// impl ConversationAdapter for MySimpleConvo {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
317 /// // ...
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
318 /// # fn prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
319 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
320 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
321 /// #
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
322 /// # fn masked_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
323 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
324 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
325 /// #
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
326 /// # fn error_msg(&self, message: impl AsRef<OsStr>) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
327 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
328 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
329 /// #
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
330 /// # fn info_msg(&self, message: impl AsRef<OsStr>) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
331 /// # unimplemented!()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
332 /// # }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
333 /// #
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
334 /// # fn radio_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
335 /// # unimplemented!()
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
336 /// # }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
337 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
338 /// # fn binary_prompt(&self, (data, data_type): (&[u8], u8)) -> Result<BinaryData> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
339 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
340 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
341 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
342 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
343 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
344 /// let mut simple = MySimpleConvo::new();
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
345 /// some_library::get_auth_data(&mut simple.into_conversation())
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
346 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
347 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
348 pub trait ConversationAdapter {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
349 /// Lets you use this simple conversation as a full [Conversation].
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
350 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
351 /// The wrapper takes each message received in [`Conversation::communicate`]
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
352 /// and passes them one-by-one to the appropriate method,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
353 /// then collects responses to return.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
354 fn into_conversation(self) -> Demux<Self>
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
355 where
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
356 Self: Sized,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
357 {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
358 Demux(self)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
359 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
360 /// Prompts the user for something.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
361 fn prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
362 /// Prompts the user for something, but hides what the user types.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
363 fn masked_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
364 /// Alerts the user to an error.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
365 fn error_msg(&self, message: impl AsRef<OsStr>);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
366 /// Sends an informational message to the user.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
367 fn info_msg(&self, message: impl AsRef<OsStr>);
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
368 /// \[Linux extension] Prompts the user for a yes/no/maybe conditional.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
369 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
370 /// PAM documentation doesn't define the format of the response.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
371 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
372 /// When called on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
373 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
374 /// If implemented on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
375 /// this will never be called.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
376 fn radio_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
377 let _ = request;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
378 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
379 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
380 /// \[Linux extension] Requests binary data from the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
381 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
382 /// When called on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
383 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
384 /// If implemented on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
385 /// this will never be called.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
386 fn binary_prompt(&self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
387 let _ = data_and_type;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
388 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
389 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
390 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
391
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
392 impl<CA: ConversationAdapter> From<CA> for Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
393 fn from(value: CA) -> Self {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
394 Demux(value)
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
395 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
396 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
397
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
398 macro_rules! conv_fn {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
399 ($(#[$m:meta])* $fn_name:ident($param:tt: $pt:ty) -> $resp_type:ty { $msg:ty }) => {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
400 $(#[$m])*
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
401 fn $fn_name(&self, $param: impl AsRef<$pt>) -> Result<$resp_type> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
402 let prompt = <$msg>::new($param.as_ref());
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
403 self.communicate(&[prompt.exchange()]);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
404 prompt.answer()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
405 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
406 };
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
407 ($(#[$m:meta])*$fn_name:ident($param:tt: $pt:ty) { $msg:ty }) => {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
408 $(#[$m])*
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
409 fn $fn_name(&self, $param: impl AsRef<$pt>) {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
410 self.communicate(&[<$msg>::new($param.as_ref()).exchange()]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
411 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
412 };
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
413 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
414
146
1bc52025156b Split PAM items into their own separate struct.
Paul Fisher <paul@pfish.zone>
parents: 143
diff changeset
415 impl<C: Conversation + ?Sized> ConversationAdapter for C {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
416 conv_fn!(prompt(message: OsStr) -> OsString { QAndA });
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
417 conv_fn!(masked_prompt(message: OsStr) -> OsString { MaskedQAndA } );
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
418 conv_fn!(error_msg(message: OsStr) { ErrorMsg });
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
419 conv_fn!(info_msg(message: OsStr) { InfoMsg });
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
420 conv_fn!(radio_prompt(message: OsStr) -> OsString { RadioQAndA });
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
421 fn binary_prompt(&self, (data, typ): (&[u8], u8)) -> Result<BinaryData> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
422 let prompt = BinaryQAndA::new((data, typ));
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
423 self.communicate(&[prompt.exchange()]);
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
424 prompt.answer()
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
425 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
426 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
427
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
428 /// A [`Conversation`] which asks the questions one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
429 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
430 /// This is automatically created by [`ConversationAdapter::into_conversation`].
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
431 pub struct Demux<CA: ConversationAdapter>(CA);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
432
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
433 impl<CA: ConversationAdapter> Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
434 /// Gets the original Conversation out of this wrapper.
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
435 fn into_inner(self) -> CA {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
436 self.0
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
437 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
438 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
439
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
440 impl<CA: ConversationAdapter> Conversation for Demux<CA> {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
441 fn communicate(&self, messages: &[Exchange]) {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
442 for msg in messages {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
443 match msg {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
444 Exchange::Prompt(prompt) => prompt.set_answer(self.0.prompt(prompt.question())),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
445 Exchange::MaskedPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
446 prompt.set_answer(self.0.masked_prompt(prompt.question()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
447 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
448 Exchange::RadioPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
449 prompt.set_answer(self.0.radio_prompt(prompt.question()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
450 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
451 Exchange::Info(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
452 self.0.info_msg(prompt.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
453 prompt.set_answer(Ok(()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
454 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
455 Exchange::Error(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
456 self.0.error_msg(prompt.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
457 prompt.set_answer(Ok(()))
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
458 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
459 Exchange::BinaryPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
460 let q = prompt.question();
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
461 prompt.set_answer(self.0.binary_prompt(q))
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
462 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
463 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
464 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
465 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
466 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
467
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
468 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
469 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
470 use super::*;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
471
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
472 #[test]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
473 fn test_demux() {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
474 #[derive(Default)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
475 struct DemuxTester {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
476 error_ran: Cell<bool>,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
477 info_ran: Cell<bool>,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
478 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
479
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
480 impl ConversationAdapter for DemuxTester {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
481 fn prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
482 match request.as_ref().to_str().unwrap() {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
483 "what" => Ok("whatwhat".into()),
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
484 "give_err" => Err(ErrorCode::PermissionDenied),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
485 _ => panic!("unexpected prompt!"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
486 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
487 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
488 fn masked_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
489 assert_eq!("reveal", request.as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
490 Ok("my secrets".into())
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
491 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
492 fn error_msg(&self, message: impl AsRef<OsStr>) {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
493 self.error_ran.set(true);
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
494 assert_eq!("whoopsie", message.as_ref());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
495 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
496 fn info_msg(&self, message: impl AsRef<OsStr>) {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
497 self.info_ran.set(true);
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
498 assert_eq!("did you know", message.as_ref());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
499 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
500 fn radio_prompt(&self, request: impl AsRef<OsStr>) -> Result<OsString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
501 assert_eq!("channel?", request.as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
502 Ok("zero".into())
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
503 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
504 fn binary_prompt(&self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
505 assert_eq!((&[10, 9, 8][..], 66), data_and_type);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
506 Ok(BinaryData::new(vec![5, 5, 5], 5))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
507 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
508 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
509
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
510 let tester = DemuxTester::default();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
511
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
512 let what = QAndA::new("what".as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
513 let pass = MaskedQAndA::new("reveal".as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
514 let err = ErrorMsg::new("whoopsie".as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
515 let info = InfoMsg::new("did you know".as_ref());
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
516 let has_err = QAndA::new("give_err".as_ref());
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
517
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
518 let conv = tester.into_conversation();
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
519
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
520 // Basic tests.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
521
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
522 conv.communicate(&[
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
523 what.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
524 pass.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
525 err.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
526 info.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
527 has_err.exchange(),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
528 ]);
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
529
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
530 assert_eq!("whatwhat", what.answer().unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
531 assert_eq!("my secrets", pass.answer().unwrap());
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
532 assert_eq!(Ok(()), err.answer());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
533 assert_eq!(Ok(()), info.answer());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
534 assert_eq!(ErrorCode::PermissionDenied, has_err.answer().unwrap_err());
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
535 let tester = conv.into_inner();
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
536 assert!(tester.error_ran.get());
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
537 assert!(tester.info_ran.get());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
538
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
539 // Test the Linux extensions separately.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
540 {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
541 let conv = tester.into_conversation();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
542
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
543 let radio = RadioQAndA::new("channel?".as_ref());
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
544 let bin = BinaryQAndA::new((&[10, 9, 8], 66));
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
545 conv.communicate(&[radio.exchange(), bin.exchange()]);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
546
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
547 assert_eq!("zero", radio.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
548 assert_eq!(BinaryData::from(([5, 5, 5], 5)), bin.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
549 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
550 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
551
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
552 fn test_mux() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
553 struct MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
554
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
555 impl Conversation for MuxTester {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
556 fn communicate(&self, messages: &[Exchange]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
557 if let [msg] = messages {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
558 match *msg {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
559 Exchange::Info(info) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
560 assert_eq!("let me tell you", info.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
561 info.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
562 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
563 Exchange::Error(error) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
564 assert_eq!("oh no", error.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
565 error.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
566 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
567 Exchange::Prompt(prompt) => {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
568 prompt.set_answer(match prompt.question().to_str().unwrap() {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
569 "should_err" => Err(ErrorCode::PermissionDenied),
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
570 "question" => Ok("answer".into()),
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
571 other => panic!("unexpected question {other:?}"),
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
572 })
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
573 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
574 Exchange::MaskedPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
575 assert_eq!("password!", ask.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
576 ask.set_answer(Ok("open sesame".into()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
577 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
578 Exchange::BinaryPrompt(prompt) => {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
579 assert_eq!((&[1, 2, 3][..], 69), prompt.question());
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
580 prompt.set_answer(Ok(BinaryData::from((&[3, 2, 1], 42))))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
581 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
582 Exchange::RadioPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
583 assert_eq!("radio?", ask.question());
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 130
diff changeset
584 ask.set_answer(Ok("yes".into()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
585 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
586 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
587 } else {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
588 panic!(
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
589 "there should only be one message, not {len}",
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
590 len = messages.len()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
591 )
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
592 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
593 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
594 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
595
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
596 let tester = MuxTester;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
597
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
598 assert_eq!("answer", tester.prompt("question").unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
599 assert_eq!("open sesame", tester.masked_prompt("password!").unwrap());
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
600 tester.error_msg("oh no");
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
601 tester.info_msg("let me tell you");
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
602 // Linux-PAM extensions. Always implemented, but separate for clarity.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
603 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
604 assert_eq!("yes", tester.radio_prompt("radio?").unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
605 assert_eq!(
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
606 BinaryData::new(vec![3, 2, 1], 42),
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
607 tester.binary_prompt((&[1, 2, 3], 69)).unwrap(),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
608 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
609 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
610 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
611 ErrorCode::BufferError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
612 tester.prompt("should_error").unwrap_err(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
613 );
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
614 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
615 ErrorCode::ConversationError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
616 tester.masked_prompt("return_wrong_type").unwrap_err()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
617 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
618 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
619 }