Mercurial > crates > nonstick
annotate src/pam_ffi/handle.rs @ 73:ac6881304c78
Do conversations, along with way too much stuff.
This implements conversations, along with all the memory management
brouhaha that goes along with it. The conversation now lives directly
on the handle rather than being a thing you have to get from it
and then call manually. It Turns Out this makes things a lot easier!
I guess we reorganized things again. For the last time. For real.
I promise.
This all passes ASAN, so it seems Pretty Good!
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 05 Jun 2025 03:41:38 -0400 |
parents | |
children | c7c596e6388f |
rev | line source |
---|---|
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
1 use super::conversation::LibPamConversation; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
2 use crate::constants::{ErrorCode, InvalidEnum, Result}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
3 use crate::conv::Message; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
4 use crate::handle::{PamApplicationOnly, PamModuleOnly, PamShared}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
5 use crate::pam_ffi::memory; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
6 use crate::pam_ffi::memory::Immovable; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
7 use crate::{Conversation, Response}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
8 use num_derive::FromPrimitive; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
9 use num_traits::FromPrimitive; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
10 use std::ffi::{c_char, c_int}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
11 use std::ops::{Deref, DerefMut}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
12 use std::result::Result as StdResult; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
13 use std::{mem, ptr}; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
14 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
15 /// An owned PAM handle. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
16 #[repr(transparent)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
17 pub struct OwnedLibPamHandle(*mut LibPamHandle); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
18 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
19 /// An opaque structure that a PAM handle points to. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
20 #[repr(C)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
21 pub struct LibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
22 _data: (), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
23 _marker: Immovable, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
24 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
25 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
26 impl LibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
27 /// Gets a C string item. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
28 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
29 /// # Safety |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
30 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
31 /// You better be requesting an item which is a C string. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
32 unsafe fn get_cstr_item(&mut self, item_type: ItemType) -> Result<Option<&str>> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
33 let mut output = ptr::null(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
34 let ret = unsafe { super::pam_get_item(self, item_type as c_int, &mut output) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
35 ErrorCode::result_from(ret)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
36 memory::wrap_string(output.cast()) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
37 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 /// Sets a C string item. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
41 /// # Safety |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
42 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
43 /// You better be setting an item which is a C string. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
44 unsafe fn set_cstr_item(&mut self, item_type: ItemType, data: Option<&str>) -> Result<()> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
45 let data_str = memory::option_cstr(data)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
46 let ret = unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
47 super::pam_set_item( |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
48 self, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 item_type as c_int, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
50 memory::prompt_ptr(data_str.as_ref()).cast(), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
51 ) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
52 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
53 ErrorCode::result_from(ret) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
54 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
55 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
56 /// Gets the `PAM_CONV` item from the handle. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
57 fn conversation_item(&mut self) -> Result<&mut LibPamConversation> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
58 let output: *mut LibPamConversation = ptr::null_mut(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
59 let result = unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
60 super::pam_get_item( |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
61 self, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
62 ItemType::Conversation.into(), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
63 &mut output.cast_const().cast(), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
64 ) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
65 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
66 ErrorCode::result_from(result)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
67 // SAFETY: We got this result from PAM, and we're checking if it's null. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
68 unsafe { output.as_mut() }.ok_or(ErrorCode::ConversationError) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
69 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
70 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
71 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
72 impl PamApplicationOnly for OwnedLibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
73 fn close(self, status: Result<()>) -> Result<()> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
74 let ret = unsafe { super::pam_end(self.0, ErrorCode::result_to_c(status)) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
75 // Forget rather than dropping, since dropping also calls pam_end. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
76 mem::forget(self); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
77 ErrorCode::result_from(ret) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
78 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
79 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
80 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
81 impl Deref for OwnedLibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
82 type Target = LibPamHandle; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
83 fn deref(&self) -> &Self::Target { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
84 unsafe { &*self.0 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
85 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
86 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
87 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
88 impl DerefMut for OwnedLibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
89 fn deref_mut(&mut self) -> &mut Self::Target { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
90 unsafe { &mut *self.0 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
91 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
92 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
93 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
94 impl Drop for OwnedLibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
95 /// Ends the PAM session with a zero error code. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
96 /// You probably want to call [`close`](Self::close) instead of |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
97 /// letting this drop by itself. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
98 fn drop(&mut self) { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
99 unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
100 super::pam_end(self.0, 0); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
101 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
102 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
103 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
104 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
105 macro_rules! cstr_item { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
106 (get = $getter:ident, item = $item_type:path) => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
107 fn $getter(&mut self) -> Result<Option<&str>> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
108 unsafe { self.get_cstr_item($item_type) } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
109 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
110 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
111 (set = $setter:ident, item = $item_type:path) => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
112 fn $setter(&mut self, value: Option<&str>) -> Result<()> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
113 unsafe { self.set_cstr_item($item_type, value) } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
114 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
115 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
116 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
117 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
118 impl PamShared for LibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
119 fn get_user(&mut self, prompt: Option<&str>) -> Result<&str> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
120 let prompt = memory::option_cstr(prompt)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
121 let mut output: *const c_char = ptr::null(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
122 let ret = |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
123 unsafe { super::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref())) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
124 ErrorCode::result_from(ret)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
125 unsafe { memory::wrap_string(output) } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
126 .transpose() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
127 .unwrap_or(Err(ErrorCode::ConversationError)) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
128 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
129 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
130 cstr_item!(get = user_item, item = ItemType::User); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
131 cstr_item!(set = set_user_item, item = ItemType::User); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
132 cstr_item!(get = service, item = ItemType::Service); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
133 cstr_item!(set = set_service, item = ItemType::Service); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
134 cstr_item!(get = user_prompt, item = ItemType::UserPrompt); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
135 cstr_item!(set = set_user_prompt, item = ItemType::UserPrompt); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
136 cstr_item!(get = tty_name, item = ItemType::Tty); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
137 cstr_item!(set = set_tty_name, item = ItemType::Tty); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
138 cstr_item!(get = remote_user, item = ItemType::RemoteUser); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
139 cstr_item!(set = set_remote_user, item = ItemType::RemoteUser); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
140 cstr_item!(get = remote_host, item = ItemType::RemoteHost); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
141 cstr_item!(set = set_remote_host, item = ItemType::RemoteHost); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
142 cstr_item!(set = set_authtok_item, item = ItemType::AuthTok); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
143 cstr_item!(set = set_old_authtok_item, item = ItemType::OldAuthTok); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
144 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
145 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
146 impl Conversation for LibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
147 fn converse(&mut self, messages: &[Message]) -> Result<Vec<Response>> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
148 self.conversation_item()?.converse(messages) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
149 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
150 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
151 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
152 impl PamModuleOnly for LibPamHandle { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
153 fn get_authtok(&mut self, prompt: Option<&str>) -> Result<&str> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
154 let prompt = memory::option_cstr(prompt)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
155 let mut output: *const c_char = ptr::null_mut(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
156 // SAFETY: We're calling this with known-good values. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
157 let res = unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
158 super::pam_get_authtok( |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
159 self, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
160 ItemType::AuthTok.into(), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
161 &mut output, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
162 memory::prompt_ptr(prompt.as_ref()), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
163 ) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
164 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
165 ErrorCode::result_from(res)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
166 // SAFETY: We got this string from PAM. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
167 unsafe { memory::wrap_string(output) } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
168 .transpose() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
169 .unwrap_or(Err(ErrorCode::ConversationError)) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
170 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
171 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
172 cstr_item!(get = authtok_item, item = ItemType::AuthTok); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
173 cstr_item!(get = old_authtok_item, item = ItemType::OldAuthTok); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
174 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
175 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
176 /// Function called at the end of a PAM session that is called to clean up |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
177 /// a value previously provided to PAM in a `pam_set_data` call. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
178 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
179 /// You should never call this yourself. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
180 extern "C" fn set_data_cleanup<T>(_: *const libc::c_void, c_data: *mut libc::c_void, _: c_int) { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
181 unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
182 let _data: Box<T> = Box::from_raw(c_data.cast()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
183 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
184 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
185 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
186 /// Identifies what is being gotten or set with `pam_get_item` |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
187 /// or `pam_set_item`. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
188 #[derive(FromPrimitive)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
189 #[repr(i32)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
190 #[non_exhaustive] // because C could give us anything! |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
191 pub enum ItemType { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
192 /// The PAM service name. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
193 Service = 1, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
194 /// The user's login name. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
195 User = 2, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
196 /// The TTY name. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
197 Tty = 3, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
198 /// The remote host (if applicable). |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
199 RemoteHost = 4, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
200 /// The conversation struct (not a CStr-based item). |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
201 Conversation = 5, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
202 /// The authentication token (password). |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
203 AuthTok = 6, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
204 /// The old authentication token (when changing passwords). |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
205 OldAuthTok = 7, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
206 /// The remote user's name. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
207 RemoteUser = 8, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
208 /// The prompt shown when requesting a username. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
209 UserPrompt = 9, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
210 /// App-supplied function to override failure delays. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
211 FailDelay = 10, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
212 /// X display name. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
213 XDisplay = 11, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
214 /// X server authentication data. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
215 XAuthData = 12, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
216 /// The type of `pam_get_authtok`. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
217 AuthTokType = 13, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
218 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
219 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
220 impl TryFrom<c_int> for ItemType { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
221 type Error = InvalidEnum<Self>; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
222 fn try_from(value: c_int) -> StdResult<Self, Self::Error> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
223 Self::from_i32(value).ok_or(value.into()) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
224 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
225 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
226 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
227 impl From<ItemType> for c_int { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
228 fn from(val: ItemType) -> Self { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
229 val as Self |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
230 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
231 } |