summaryrefslogtreecommitdiff
path: root/src-repo/src/pam_any_conversation.rs
blob: 825cb6a68ed130e3486f3ec14fea86bde228d07e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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<Mutex<RawConv>>,
}

impl Conversation for PamAnyConversation {
    fn prompt_echo(&mut self, _msg: &CStr) -> Result<CString, ()> {
        CString::new(self.user.as_str()).map_err(|_| ())
    }

    fn prompt_blind(&mut self, msg: &CStr) -> Result<CString, ()> {
        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);
            }
        });
    }
}