comparison src/conv.rs @ 60:05cc2c27334f

The Big Refactor: clean up docs and exports. - Brings the most important symbols in the library to the root with `pub use` statements. - Expands and updates documentation. - Rearranges things extensively to make the external interface nicer and make the structure easier to understand. - Renames a few things (e.g. `Result`).
author Paul Fisher <paul@pfish.zone>
date Wed, 21 May 2025 19:00:51 -0400
parents 3f4a77aa88be
children d83623951070
comparison
equal deleted inserted replaced
59:3f4a77aa88be 60:05cc2c27334f
1 //! The [Conversation] struct, for interacting with the user.
2
1 use libc::{c_char, c_int}; 3 use libc::{c_char, c_int};
2 use std::ffi::{CStr, CString}; 4 use std::ffi::{CStr, CString};
3 use std::ptr; 5 use std::ptr;
4 6
5 use crate::constants::ErrorCode; 7 use crate::constants::ErrorCode;
6 use crate::constants::MessageStyle; 8 use crate::constants::MessageStyle;
7 use crate::constants::PamResult; 9 use crate::constants::Result;
8 use crate::items::Item; 10 use crate::items::Item;
9 11
10 #[repr(C)] 12 #[repr(C)]
11 struct Message { 13 struct Message {
12 msg_style: MessageStyle, 14 msg_style: MessageStyle,
17 struct Response { 19 struct Response {
18 resp: *const c_char, 20 resp: *const c_char,
19 resp_retcode: libc::c_int, // Unused - always zero 21 resp_retcode: libc::c_int, // Unused - always zero
20 } 22 }
21 23
24 #[doc(hidden)]
22 #[repr(C)] 25 #[repr(C)]
23 pub struct Inner { 26 pub struct Inner {
24 conv: extern "C" fn( 27 conv: extern "C" fn(
25 num_msg: c_int, 28 num_msg: c_int,
26 pam_message: &&Message, 29 pam_message: &&Message,
28 appdata_ptr: *const libc::c_void, 31 appdata_ptr: *const libc::c_void,
29 ) -> c_int, 32 ) -> c_int,
30 appdata_ptr: *const libc::c_void, 33 appdata_ptr: *const libc::c_void,
31 } 34 }
32 35
33 /// A `Conv`ersation channel with the user. 36 /// A communication channel with the user.
34 /// 37 ///
35 /// Communication is mediated by the PAM client (the application that invoked 38 /// Use this to communicate with the user, if needed, beyond the standard
36 /// pam). Messages sent will be relayed to the user by the client, and response 39 /// things you can get/set with `get_user`/`get_authtok` and friends.
37 /// will be relayed back. 40 /// The PAM client (i.e., the application that is logging in) will present
38 pub struct Conv<'a>(&'a Inner); 41 /// the messages you send to the user and ask for responses.
42 pub struct Conversation<'a>(&'a Inner);
39 43
40 impl Conv<'_> { 44 impl Conversation<'_> {
41 /// Sends a message to the pam client. 45 /// Sends a message to the PAM client.
42 /// 46 ///
43 /// This will typically result in the user seeing a message or a prompt. 47 /// This will typically result in the user seeing a message or a prompt.
44 /// There are several message styles available: 48 /// For details, see what [MessageStyle]s are available.
45 /// 49 ///
46 /// - PAM_PROMPT_ECHO_OFF 50 /// Note that the user experience will depend on how each style
47 /// - PAM_PROMPT_ECHO_ON 51 /// is implemented by the client, and that not all clients
48 /// - PAM_ERROR_MSG 52 /// will implement all message styles.
49 /// - PAM_TEXT_INFO 53 pub fn send(&self, style: MessageStyle, msg: &str) -> Result<Option<&CStr>> {
50 /// - PAM_RADIO_TYPE
51 /// - PAM_BINARY_PROMPT
52 ///
53 /// Note that the user experience will depend on how the client implements
54 /// these message styles - and not all applications implement all message
55 /// styles.
56 pub fn send(&self, style: MessageStyle, msg: &str) -> PamResult<Option<&CStr>> {
57 let mut resp_ptr: *const Response = ptr::null(); 54 let mut resp_ptr: *const Response = ptr::null();
58 let msg_cstr = CString::new(msg).unwrap(); 55 let msg_cstr = CString::new(msg).unwrap();
59 let msg = Message { 56 let msg = Message {
60 msg_style: style, 57 msg_style: style,
61 msg: msg_cstr.as_ptr(), 58 msg: msg_cstr.as_ptr(),
72 }; 69 };
73 Ok(result) 70 Ok(result)
74 } 71 }
75 } 72 }
76 73
77 impl Item for Conv<'_> { 74 impl Item for Conversation<'_> {
78 type Raw = Inner; 75 type Raw = Inner;
79 76
80 fn type_id() -> crate::items::ItemType { 77 fn type_id() -> crate::items::ItemType {
81 crate::items::ItemType::Conversation 78 crate::items::ItemType::Conversation
82 } 79 }