use std::ffi::{CStr, CString}; use std::sync::{Arc, Mutex}; use std::thread; use crate::pam_client::Conversation; use crate::raw_conv::RawConv; pub struct PamAnyConversation { pub service_display_name: String, pub user: String, pub conv: Arc>, } impl Conversation for PamAnyConversation { fn prompt_echo(&mut self, _msg: &CStr) -> Result { CString::new(self.user.as_str()).map_err(|_| ()) } fn prompt_blind(&mut self, msg: &CStr) -> Result { let msg = msg.to_str().map_err(|_| ())?; let conv = self.conv.lock().map_err(|_| ())?; let response = conv.send_prompt(&format!("[{}] {}", self.service_display_name, msg))?; response.ok_or(()) } fn info(&mut self, msg: &CStr) { let msg = msg.to_str().unwrap_or(""); let msg = format!("[{}] {}", self.service_display_name, msg); let conv = self.conv.clone(); thread::spawn(move || { if let Ok(conv) = conv.lock() { let _ = conv.send_info(&msg); } }); } fn error(&mut self, msg: &CStr) { let msg = msg.to_str().unwrap_or(""); let msg = format!("[{}] {}", self.service_display_name, msg); let conv = self.conv.clone(); thread::spawn(move || { if let Ok(conv) = conv.lock() { let _ = conv.send_error(&msg); } }); } }