Mercurial > crates > nonstick
annotate src/conv.rs @ 71:58f9d2a4df38
Reorganize everything again???
- Splits ffi/memory stuff into a bunch of stuff in the pam_ffi module.
- Builds infrastructure for passing Messages and Responses.
- Adds tests for some things at least.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 03 Jun 2025 21:54:58 -0400 |
parents | 9f8381a1c09c |
children | 47eb242a4f88 |
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 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
6 use crate::constants::Result; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
7 use crate::pam_ffi::Message; |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
8 use secure_string::SecureString; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
9 // TODO: In most cases, we should be passing around references to strings |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
10 // or binary data. Right now we don't because that turns type inference and |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
11 // trait definitions/implementations into a HUGE MESS. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
12 // |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
13 // Ideally, we would be using some kind of `TD: TextData` and `BD: BinaryData` |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
14 // associated types in the various Conversation traits to avoid copying |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
15 // when unnecessary. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
16 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
17 /// The responses that PAM will return from a request. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
18 #[derive(Debug, PartialEq, derive_more::From)] |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
19 pub enum Response { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
20 /// Used to fill in list entries where there is no response expected. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
21 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
22 /// Used in response to: |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
23 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
24 /// - [`Error`](Message::Error) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
25 /// - [`Info`](Message::Info) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
26 NoResponse, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
27 /// A response with text data from the user. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
28 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
29 /// Used in response to: |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
30 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
31 /// - [`Prompt`](Message::Prompt) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
32 /// - [`RadioPrompt`](Message::RadioPrompt) (a Linux-PAM extension) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
33 Text(String), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
34 /// A response to a masked request with text data from the user. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
35 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
36 /// Used in response to: |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
37 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
38 /// - [`MaskedPrompt`](Message::MaskedPrompt) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
39 MaskedText(SecureString), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
40 /// A response to a binary request (a Linux-PAM extension). |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
41 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
42 /// Used in response to: |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
43 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
44 /// - [`BinaryPrompt`](Message::BinaryPrompt) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
45 Binary(BinaryData), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
46 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
47 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
48 /// 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
|
49 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
50 /// 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
|
51 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
52 /// - Applications implement Conversation and provide a user interface |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
53 /// to allow the user to respond to PAM questions. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
54 /// - Modules call a Conversation implementation to request information |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
55 /// or send information to the user. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
56 pub trait Conversation { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
57 /// Sends messages to the user. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
58 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
59 /// 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
|
60 /// as there were messages in the request; one corresponding to each. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
61 fn send(&mut self, messages: &[Message]) -> Result<Vec<Response>>; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
62 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
63 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
64 /// Trait that an application can implement if they want to handle messages |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
65 /// one at a time. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
66 pub trait DemuxedConversation { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
67 /// Prompts the user for some text. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
68 fn prompt(&mut self, request: &str) -> Result<String>; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
69 /// Prompts the user for some text, but hides their typing. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
70 fn masked_prompt(&mut self, request: &str) -> Result<SecureString>; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
71 /// Prompts the user for a radio option (a Linux-PAM extension). |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
72 /// |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
73 /// The Linux-PAM documentation doesn't give the format of the response. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
74 fn radio_prompt(&mut self, request: &str) -> Result<String>; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
75 /// Alerts the user to an error. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
76 fn error(&mut self, message: &str); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
77 /// Sends an informational message to the user. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
78 fn info(&mut self, message: &str); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
79 /// Requests binary data from the user (a Linux-PAM extension). |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
80 fn binary_prompt(&mut self, data: &[u8], data_type: u8) -> Result<BinaryData>; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
81 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
82 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
83 impl<D: DemuxedConversation> Conversation for D { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
84 fn send(&mut self, messages: &[Message]) -> Result<Vec<Response>> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
85 messages |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
86 .iter() |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
87 .map(|msg| match *msg { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
88 Message::Prompt(prompt) => self.prompt(prompt).map(Response::from), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
89 Message::MaskedPrompt(prompt) => self.masked_prompt(prompt).map(Response::from), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
90 Message::RadioPrompt(prompt) => self.radio_prompt(prompt).map(Response::from), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
91 Message::Info(message) => { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
92 self.info(message); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
93 Ok(Response::NoResponse) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
94 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
95 Message::Error(message) => { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
96 self.error(message); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
97 Ok(Response::NoResponse) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
98 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
99 Message::BinaryPrompt { data_type, data } => { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
100 self.binary_prompt(data, data_type).map(Response::from) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
101 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
102 }) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
103 .collect() |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
104 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
105 } |
15
27730595f1ea
Adding pam-http module
Anthony Nowell <anthony@algorithmia.com>
parents:
diff
changeset
|
106 |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
107 /// Owned binary data. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
108 #[derive(Debug, PartialEq)] |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
109 pub struct BinaryData { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
110 data: Vec<u8>, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
111 data_type: u8, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
112 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
113 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
114 impl BinaryData { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
115 pub fn new(data: Vec<u8>, data_type: u8) -> Self { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
116 Self { data, data_type } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
117 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
118 pub fn data(&self) -> &[u8] { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
119 &self.data |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
120 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
121 pub fn data_type(&self) -> u8 { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
122 self.data_type |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
123 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
124 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
125 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
126 impl From<BinaryData> for Vec<u8> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
127 /// Extracts the inner vector from the BinaryData. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
128 fn from(value: BinaryData) -> Self { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
129 value.data |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
130 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
131 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
132 |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
133 #[cfg(test)] |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
134 mod tests { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
135 use super::{Conversation, DemuxedConversation, Message, Response, SecureString}; |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
136 use crate::constants::ErrorCode; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
137 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
138 #[test] |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
139 fn test_demux() { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
140 #[derive(Default)] |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
141 struct DemuxTester { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
142 error_ran: bool, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
143 info_ran: bool, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
144 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
145 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
146 impl DemuxedConversation for DemuxTester { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
147 fn prompt(&mut self, request: &str) -> crate::Result<String> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
148 match request { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
149 "what" => Ok("whatwhat".to_owned()), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
150 "give_err" => Err(ErrorCode::PermissionDenied), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
151 _ => panic!("unexpected prompt!"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
152 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
153 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
154 fn masked_prompt(&mut self, request: &str) -> crate::Result<SecureString> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
155 assert_eq!("reveal", request); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
156 Ok(SecureString::from("my secrets")) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
157 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
158 fn radio_prompt(&mut self, request: &str) -> crate::Result<String> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
159 assert_eq!("channel?", request); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
160 Ok("zero".to_owned()) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
161 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
162 fn error(&mut self, message: &str) { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
163 self.error_ran = true; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
164 assert_eq!("whoopsie", message); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
165 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
166 fn info(&mut self, message: &str) { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
167 self.info_ran = true; |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
168 assert_eq!("did you know", message); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
169 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
170 fn binary_prompt( |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
171 &mut self, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
172 data: &[u8], |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
173 data_type: u8, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
174 ) -> crate::Result<super::BinaryData> { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
175 assert_eq!(&[10, 9, 8], data); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
176 assert_eq!(66, data_type); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
177 Ok(super::BinaryData::new(vec![5, 5, 5], 5)) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
178 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
179 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
180 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
181 let mut tester = DemuxTester::default(); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
182 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
183 assert_eq!( |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
184 vec![ |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
185 Response::Text("whatwhat".to_owned()), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
186 Response::MaskedText("my secrets".into()), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
187 Response::NoResponse, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
188 Response::NoResponse, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
189 ], |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
190 tester |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
191 .send(&[ |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
192 Message::Prompt("what"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
193 Message::MaskedPrompt("reveal"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
194 Message::Error("whoopsie"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
195 Message::Info("did you know"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
196 ]) |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
197 .unwrap() |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
198 ); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
199 assert!(tester.error_ran); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
200 assert!(tester.info_ran); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
201 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
202 assert_eq!( |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
203 ErrorCode::PermissionDenied, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
204 tester.send(&[Message::Prompt("give_err")]).unwrap_err(), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
205 ); |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
206 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
207 // Test the Linux-PAM extensions separately. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
208 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
209 assert_eq!( |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
210 vec![ |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
211 Response::Text("zero".to_owned()), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
212 Response::Binary(super::BinaryData::new(vec![5, 5, 5], 5)), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
213 ], |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
214 tester |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
215 .send(&[ |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
216 Message::RadioPrompt("channel?"), |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
217 Message::BinaryPrompt { |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
218 data: &[10, 9, 8], |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
219 data_type: 66 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
220 }, |
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 .unwrap() |
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 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
225 } |