annotate src/conv.rs @ 141:a508a69c068a

Remove a lot of Results from functions. Many functions are documented to only return failing Results when given improper inputs or when there is a memory allocation failure (which can be verified by looking at the source). In cases where we know our input is correct, we don't need to check for memory allocation errors for the same reason that Rust doesn't do so when you, e.g., create a new Vec.
author Paul Fisher <paul@pfish.zone>
date Sat, 05 Jul 2025 17:16:56 -0400
parents 80c07e5ab22f
children ebb71a412b58
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;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
8 use std::fmt;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
9 use std::fmt::Debug;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
10 use std::result::Result as StdResult;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
11
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
12 /// 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
13 #[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
14 #[non_exhaustive]
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
15 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
16 Prompt(&'a QAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
17 MaskedPrompt(&'a MaskedQAndA<'a>),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
18 Error(&'a ErrorMsg<'a>),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
19 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
20 RadioPrompt(&'a RadioQAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
21 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
22 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
23
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
24 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
25 /// 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
26 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
27 /// 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
28 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
29 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
30 /// 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
31 /// 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
32 ///
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
33 /// fn cant_respond(message: Exchange) {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
34 /// match message {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
35 /// Exchange::Info(i) => {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
36 /// eprintln!("fyi, {}", i.question());
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
37 /// 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
38 /// }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
39 /// Exchange::Error(e) => {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
40 /// eprintln!("ERROR: {}", e.question());
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
41 /// 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
42 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
43 /// // 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
44 /// 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
45 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
46 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
47 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
48 match *self {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
49 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
50 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
51 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
52 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
53 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
54 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
55 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
56 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
57 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
58
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
59 macro_rules! q_and_a {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
60 ($(#[$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
61 $(#[$m])*
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
62 pub struct $name<'a> {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
63 q: $qt,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
64 a: Cell<Result<$at>>,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
65 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
66
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
67 $(#[$m])*
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
68 impl<'a> $name<'a> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
69 #[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
70 pub fn new(question: $qt) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
71 Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
72 q: question,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
73 a: Cell::new(Err(ErrorCode::ConversationError)),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
74 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
75 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
77 /// 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
78 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
79 $val(self)
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
80 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
81
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
82 /// 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
83 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
84 /// 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
85 /// 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
86 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
87 self.q
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
88 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
89
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
90 /// 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
91 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
92 /// 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
93 /// 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
94 /// 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
95 /// (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
96 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
97 self.a.set(answer)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
98 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
99
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
100 /// 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
101 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
102 self.a.into_inner()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
103 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
104 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
105
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
106 // 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
107 // https://stackoverflow.com/a/78871280/39808
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
108 $(#[$m])*
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
109 impl fmt::Debug for $name<'_> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
110 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
111 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
112 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
113 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
114 };
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
115 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
116
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
117 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
118 /// 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
119 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
120 /// In other words, a password entry prompt.
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
121 MaskedQAndA<'a, Q=&'a str, A=String>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
122 Exchange::MaskedPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
123 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
124
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
125 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
126 /// 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
127 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
128 /// 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
129 /// 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
130 /// It can be used for things like usernames.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
131 QAndA<'a, Q=&'a str, A=String>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
132 Exchange::Prompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
133 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
134
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
135 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
136 /// 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
137 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
138 /// 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
139 /// 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
140 /// what the format of the answer will be, or how this should be shown.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
141 RadioQAndA<'a, Q=&'a str, A=String>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
142 Exchange::RadioPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
143 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
144
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
145 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
146 /// Asks for binary data. (Linux-PAM extension)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
147 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
148 /// 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
149 /// 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
150 /// or to enable things like security keys.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
151 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
152 /// 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
153 /// 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
154 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
155 Exchange::BinaryPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
156 );
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
157
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
158 /// Owned binary data.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
159 #[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
160 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
161 /// The data.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
162 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
163 /// 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
164 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
165 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
166
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
167 impl BinaryData {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
168 /// 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
169 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
170 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
171 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
172 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
173 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
174 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
175 }
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 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
178 /// 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
179 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
180 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
181 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
182 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
183 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
184 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
185 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
186
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
187 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
188 /// Easy destructuring.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
189 fn from(value: BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
190 (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
191 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
192 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
193
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
194 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
195 fn from(value: &'a BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
196 (&value.data, value.data_type)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
197 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
198 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
199
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
200 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
201 /// 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
202 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
203 /// 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
204 /// 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
205 /// the message has been displayed (or actively discarded).
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
206 InfoMsg<'a, Q = &'a str, A = ()>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
207 Exchange::Info
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
208 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
209
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
210 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
211 /// 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
212 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
213 /// 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
214 /// 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
215 /// the message has been displayed (or actively discarded).
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
216 ErrorMsg<'a, Q = &'a str, A = ()>,
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
217 Exchange::Error
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
218 );
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
219
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
220 /// 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
221 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
222 /// 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
223 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
224 /// - Applications implement Conversation and provide a user interface
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
225 /// to allow the user to respond to PAM questions.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
226 /// - Modules call a Conversation implementation to request information
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
227 /// or send information to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
228 pub trait Conversation {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
229 /// Sends messages to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
230 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
231 /// 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
232 /// 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
233 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
234 /// 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
235 fn communicate(&self, messages: &[Exchange]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
236 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
237
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
238 /// 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
239 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
240 /// 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
241 /// 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 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
244 /// 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
245 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
246 /// # use nonstick::Conversation;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
247 /// 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
248 /// /* ... */
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
249 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
250 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
251 ///
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
252 /// 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
253 /// // ...
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
254 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
255 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
256 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
257 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
258 /// 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
259 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
260 /// ```
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
261 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
262 FunctionConvo(func)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
263 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
264
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
265 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
266
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
267 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
268 fn communicate(&self, messages: &[Exchange]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
269 self.0(messages)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
270 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
271 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
272
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
273 /// A Conversation
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
274 struct UsernamePasswordConvo {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
275 username: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
276 password: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
277 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
278
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
279 /// 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
280 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
281 /// 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
282 /// 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
283 /// one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
284 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
285 /// 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
286 ///
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
287 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
288 /// # use nonstick::{Conversation, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
289 /// // 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
290 /// use nonstick::ConversationAdapter;
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
291 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
292 /// fn ask_for_token(convo: &impl Conversation) -> Result<String> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
293 /// 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
294 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
295 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
296 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
297 /// 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
298 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
299 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
300 /// 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
301 /// # use nonstick::{BinaryData, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
302 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
303 /// # use nonstick::Conversation;
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
304 /// 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
305 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
306 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
307 ///
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
308 /// struct MySimpleConvo {/* ... */}
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
309 /// # 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
310 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
311 /// 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
312 /// // ...
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
313 /// # fn prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
314 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
315 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
316 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
317 /// # fn masked_prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
318 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
319 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
320 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
321 /// # fn error_msg(&self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
322 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
323 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
324 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
325 /// # fn info_msg(&self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
326 /// # unimplemented!()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
327 /// # }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
328 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
329 /// # fn radio_prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
330 /// # unimplemented!()
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
331 /// # }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
332 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
333 /// # 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
334 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
335 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
336 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
337 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
338 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
339 /// let mut simple = MySimpleConvo::new();
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
340 /// 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
341 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
342 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
343 pub trait ConversationAdapter {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
344 /// 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
345 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
346 /// 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
347 /// 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
348 /// then collects responses to return.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
349 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
350 where
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
351 Self: Sized,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
352 {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
353 Demux(self)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
354 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
355 /// Prompts the user for something.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
356 fn prompt(&self, request: &str) -> Result<String>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
357 /// Prompts the user for something, but hides what the user types.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
358 fn masked_prompt(&self, request: &str) -> Result<String>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
359 /// Alerts the user to an error.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
360 fn error_msg(&self, message: &str);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
361 /// Sends an informational message to the user.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
362 fn info_msg(&self, message: &str);
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
363 /// \[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
364 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
365 /// 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
366 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
367 /// 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
368 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
369 /// 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
370 /// this will never be called.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
371 fn radio_prompt(&self, request: &str) -> Result<String> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
372 let _ = request;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
373 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
374 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
375 /// \[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
376 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
377 /// 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
378 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
379 /// 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
380 /// this will never be called.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
381 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
382 let _ = data_and_type;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
383 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
384 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
385 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
386
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
387 impl<CA: ConversationAdapter> From<CA> for Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
388 fn from(value: CA) -> Self {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
389 Demux(value)
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
390 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
391 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
392
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
393 macro_rules! conv_fn {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
394 ($(#[$m:meta])* $fn_name:ident($($param:tt: $pt:ty),+) -> $resp_type:ty { $msg:ty }) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
395 $(#[$m])*
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
396 fn $fn_name(&self, $($param: $pt),*) -> Result<$resp_type> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
397 let prompt = <$msg>::new($($param),*);
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
398 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
399 prompt.answer()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
400 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
401 };
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
402 ($(#[$m:meta])*$fn_name:ident($($param:tt: $pt:ty),+) { $msg:ty }) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
403 $(#[$m])*
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
404 fn $fn_name(&self, $($param: $pt),*) {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
405 self.communicate(&[<$msg>::new($($param),*).exchange()]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
406 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
407 };
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
408 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
409
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
410 impl<C: Conversation> ConversationAdapter for C {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
411 conv_fn!(prompt(message: &str) -> String { QAndA });
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
412 conv_fn!(masked_prompt(message: &str) -> String { MaskedQAndA } );
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
413 conv_fn!(error_msg(message: &str) { ErrorMsg });
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
414 conv_fn!(info_msg(message: &str) { InfoMsg });
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
415 conv_fn!(radio_prompt(message: &str) -> String { RadioQAndA });
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
416 conv_fn!(binary_prompt((data, data_type): (&[u8], u8)) -> BinaryData { BinaryQAndA });
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
417 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
418
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
419 /// 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
420 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
421 /// This is automatically created by [`ConversationAdapter::into_conversation`].
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
422 pub struct Demux<CA: ConversationAdapter>(CA);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
423
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
424 impl<CA: ConversationAdapter> Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
425 /// Gets the original Conversation out of this wrapper.
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
426 fn into_inner(self) -> CA {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
427 self.0
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
428 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
429 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
430
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
431 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
432 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
433 for msg in messages {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
434 match msg {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
435 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
436 Exchange::MaskedPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
437 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
438 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
439 Exchange::RadioPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
440 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
441 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
442 Exchange::Info(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
443 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
444 prompt.set_answer(Ok(()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
445 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
446 Exchange::Error(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
447 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
448 prompt.set_answer(Ok(()))
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
449 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
450 Exchange::BinaryPrompt(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
451 let q = prompt.question();
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
452 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
453 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
454 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
455 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
456 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
457 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
458
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
459 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
460 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
461 use super::*;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
462 use crate::constants::ErrorCode;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
463
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
464 #[test]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
465 fn test_demux() {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
466 #[derive(Default)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
467 struct DemuxTester {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
468 error_ran: Cell<bool>,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
469 info_ran: Cell<bool>,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
470 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
471
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
472 impl ConversationAdapter for DemuxTester {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
473 fn prompt(&self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
474 match request {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
475 "what" => Ok("whatwhat".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
476 "give_err" => Err(ErrorCode::PermissionDenied),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
477 _ => panic!("unexpected prompt!"),
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 fn masked_prompt(&self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
481 assert_eq!("reveal", request);
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
482 Ok("my secrets".to_owned())
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
483 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
484 fn error_msg(&self, message: &str) {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
485 self.error_ran.set(true);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
486 assert_eq!("whoopsie", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
487 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
488 fn info_msg(&self, message: &str) {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
489 self.info_ran.set(true);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
490 assert_eq!("did you know", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
491 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
492 fn radio_prompt(&self, request: &str) -> Result<String> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
493 assert_eq!("channel?", request);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
494 Ok("zero".to_owned())
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
495 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
496 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
497 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
498 Ok(BinaryData::new(vec![5, 5, 5], 5))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
499 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
500 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
501
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
502 let tester = DemuxTester::default();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
503
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
504 let what = QAndA::new("what");
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
505 let pass = MaskedQAndA::new("reveal");
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
506 let err = ErrorMsg::new("whoopsie");
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
507 let info = InfoMsg::new("did you know");
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
508 let has_err = QAndA::new("give_err");
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
509
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
510 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
511
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
512 // Basic tests.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
513
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
514 conv.communicate(&[
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
515 what.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
516 pass.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
517 err.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
518 info.exchange(),
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
519 has_err.exchange(),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
520 ]);
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 assert_eq!("whatwhat", what.answer().unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
523 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
524 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
525 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
526 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
527 let tester = conv.into_inner();
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
528 assert!(tester.error_ran.get());
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
529 assert!(tester.info_ran.get());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
530
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
531 // Test the Linux extensions separately.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
532 {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
533 let conv = tester.into_conversation();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
534
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
535 let radio = RadioQAndA::new("channel?");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
536 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
537 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
538
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
539 assert_eq!("zero", radio.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
540 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
541 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
542 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
543
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
544 fn test_mux() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
545 struct MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
546
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
547 impl Conversation for MuxTester {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
548 fn communicate(&self, messages: &[Exchange]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
549 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
550 match *msg {
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
551 Exchange::Info(info) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
552 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
553 info.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
554 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
555 Exchange::Error(error) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
556 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
557 error.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
558 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
559 Exchange::Prompt(prompt) => prompt.set_answer(match prompt.question() {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
560 "should_err" => Err(ErrorCode::PermissionDenied),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
561 "question" => Ok("answer".to_owned()),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
562 other => panic!("unexpected question {other:?}"),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
563 }),
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
564 Exchange::MaskedPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
565 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
566 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
567 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
568 Exchange::BinaryPrompt(prompt) => {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
569 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
570 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
571 }
130
80c07e5ab22f Transfer over (almost) completely to using libpam-sys.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
572 Exchange::RadioPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
573 assert_eq!("radio?", ask.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
574 ask.set_answer(Ok("yes".to_owned()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
575 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
576 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
577 } else {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
578 panic!(
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
579 "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
580 len = messages.len()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
581 )
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
582 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
583 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
584 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
585
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
586 let tester = MuxTester;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
587
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
588 assert_eq!("answer", tester.prompt("question").unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
589 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
590 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
591 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
592 // 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
593 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
594 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
595 assert_eq!(
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
596 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
597 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
598 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
599 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
600 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
601 ErrorCode::BufferError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
602 tester.prompt("should_error").unwrap_err(),
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!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
605 ErrorCode::ConversationError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
606 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
607 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
608 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
609 }