comparison pam/src/conv.rs @ 30:539d81e3bdc2

Merge pull request #4 from holycleugh/conv-fixes Conv fixes
author Anthony Nowell <anowell@gmail.com>
date Tue, 01 Jan 2019 13:08:13 -0700
parents c16564971c05
children 1f4ef4c7e555
comparison
equal deleted inserted replaced
26:31618a75f251 30:539d81e3bdc2
1 use libc::{c_char, c_int}; 1 use libc::{c_char, c_int};
2 use std::ffi::{CStr, CString};
2 use std::ptr; 3 use std::ptr;
3 use std::ffi::{CStr, CString};
4 4
5 use constants::PamResultCode; 5 use constants::PamResultCode;
6 use constants::*; 6 use constants::*;
7 use module::{PamItem, PamResult}; 7 use module::{PamItem, PamResult};
8 8
26 /// Communication is mediated by the pam client (the application that invoked 26 /// Communication is mediated by the pam client (the application that invoked
27 /// pam). Messages sent will be relayed to the user by the client, and response 27 /// pam). Messages sent will be relayed to the user by the client, and response
28 /// will be relayed back. 28 /// will be relayed back.
29 #[repr(C)] 29 #[repr(C)]
30 pub struct PamConv { 30 pub struct PamConv {
31 conv: extern "C" fn(num_msg: c_int, 31 conv: extern "C" fn(
32 pam_message: &&PamMessage, 32 num_msg: c_int,
33 pam_response: &mut *const PamResponse, 33 pam_message: &&PamMessage,
34 appdata_ptr: *const AppDataPtr) 34 pam_response: &mut *const PamResponse,
35 -> PamResultCode, 35 appdata_ptr: *const AppDataPtr,
36 appdata_ptr: *const AppDataPtr, 36 ) -> PamResultCode,
37 ppdata_ptr: *const AppDataPtr,
37 } 38 }
38 39
39 impl PamConv { 40 impl PamConv {
40 /// Sends a message to the pam client. 41 /// Sends a message to the pam client.
41 /// 42 ///
52 /// Note that the user experience will depend on how the client implements 53 /// Note that the user experience will depend on how the client implements
53 /// these message styles - and not all applications implement all message 54 /// these message styles - and not all applications implement all message
54 /// styles. 55 /// styles.
55 pub fn send(&self, style: PamMessageStyle, msg: &str) -> PamResult<Option<String>> { 56 pub fn send(&self, style: PamMessageStyle, msg: &str) -> PamResult<Option<String>> {
56 let mut resp_ptr: *const PamResponse = ptr::null(); 57 let mut resp_ptr: *const PamResponse = ptr::null();
58 let msg_cstr = CString::new(msg).unwrap();
57 let msg = PamMessage { 59 let msg = PamMessage {
58 msg_style: style, 60 msg_style: style,
59 msg: CString::new(msg).unwrap().as_ptr(), 61 msg: msg_cstr.as_ptr(),
60 }; 62 };
61 63
62 let ret = (self.conv)(1, &&msg, &mut resp_ptr, self.appdata_ptr); 64 let ret = (self.conv)(1, &&msg, &mut resp_ptr, self.appdata_ptr);
63 65
64 if PamResultCode::PAM_SUCCESS == ret { 66 if PamResultCode::PAM_SUCCESS == ret {
65 if resp_ptr.is_null() { 67 // PamResponse.resp is null for styles that don't return user input like PAM_TEXT_INFO
68 let response = unsafe { (*resp_ptr).resp };
69 if response.is_null() {
66 Ok(None) 70 Ok(None)
67 } else { 71 } else {
68 let bytes = unsafe { CStr::from_ptr((*resp_ptr).resp).to_bytes() }; 72 let bytes = unsafe { CStr::from_ptr(response).to_bytes() };
69 Ok(String::from_utf8(bytes.to_vec()).ok()) 73 Ok(String::from_utf8(bytes.to_vec()).ok())
70 } 74 }
71 } else { 75 } else {
72 Err(ret) 76 Err(ret)
73 } 77 }