pam: Take dyn Converse instead of PasswordConv
This commit is contained in:
@@ -6,14 +6,18 @@ use pam_sys::{PamConversation, PamMessage, PamMessageStyle, PamResponse, PamRetu
|
||||
|
||||
use super::converse::Converse;
|
||||
|
||||
pub fn make_conversation<C: Converse>(user_converse: &mut C) -> PamConversation {
|
||||
pub struct PamConvHandlerWrapper {
|
||||
pub handler: Box<dyn Converse>,
|
||||
}
|
||||
|
||||
pub fn make_conversation(conv: &mut PamConvHandlerWrapper) -> PamConversation {
|
||||
PamConversation {
|
||||
conv: Some(converse::<C>),
|
||||
data_ptr: user_converse as *mut C as *mut c_void,
|
||||
conv: Some(converse),
|
||||
data_ptr: conv as *mut PamConvHandlerWrapper as *mut c_void,
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn converse<C: Converse>(
|
||||
pub extern "C" fn converse(
|
||||
num_msg: c_int,
|
||||
msg: *mut *mut PamMessage,
|
||||
out_resp: *mut *mut PamResponse,
|
||||
@@ -27,7 +31,7 @@ pub extern "C" fn converse<C: Converse>(
|
||||
return PamReturnCode::BUF_ERR as c_int;
|
||||
}
|
||||
|
||||
let handler = unsafe { &mut *(appdata_ptr as *mut C) };
|
||||
let wrapper = unsafe { &mut *(appdata_ptr as *mut PamConvHandlerWrapper) };
|
||||
|
||||
let mut result: PamReturnCode = PamReturnCode::SUCCESS;
|
||||
for i in 0..num_msg as isize {
|
||||
@@ -38,21 +42,21 @@ pub extern "C" fn converse<C: Converse>(
|
||||
// match on msg_style
|
||||
match PamMessageStyle::from(m.msg_style) {
|
||||
PamMessageStyle::PROMPT_ECHO_ON => {
|
||||
if let Ok(handler_response) = handler.prompt_echo(msg) {
|
||||
if let Ok(handler_response) = wrapper.handler.prompt_echo(msg) {
|
||||
r.resp = unsafe { strdup(handler_response.as_ptr()) };
|
||||
} else {
|
||||
result = PamReturnCode::CONV_ERR;
|
||||
}
|
||||
}
|
||||
PamMessageStyle::PROMPT_ECHO_OFF => {
|
||||
if let Ok(handler_response) = handler.prompt_blind(msg) {
|
||||
if let Ok(handler_response) = wrapper.handler.prompt_blind(msg) {
|
||||
r.resp = unsafe { strdup(handler_response.as_ptr()) };
|
||||
} else {
|
||||
result = PamReturnCode::CONV_ERR;
|
||||
}
|
||||
}
|
||||
PamMessageStyle::ERROR_MSG => handler.error(msg),
|
||||
PamMessageStyle::TEXT_INFO => handler.info(msg),
|
||||
PamMessageStyle::ERROR_MSG => wrapper.handler.error(msg),
|
||||
PamMessageStyle::TEXT_INFO => wrapper.handler.info(msg),
|
||||
}
|
||||
if result != PamReturnCode::SUCCESS {
|
||||
break;
|
||||
@@ -61,7 +65,6 @@ pub extern "C" fn converse<C: Converse>(
|
||||
|
||||
// free allocated memory if an error occured
|
||||
if result != PamReturnCode::SUCCESS {
|
||||
|
||||
// Free any strdup'd response strings
|
||||
for i in 0..num_msg as isize {
|
||||
let r: &mut PamResponse = unsafe { &mut *(resp.offset(i)) };
|
||||
|
@@ -6,25 +6,26 @@ use std::ptr;
|
||||
use libc::c_void;
|
||||
use pam_sys::{PamFlag, PamHandle, PamItemType, PamReturnCode};
|
||||
|
||||
use super::converse::PasswordConv;
|
||||
use super::converse::Converse;
|
||||
use super::env::{get_pam_env, PamEnvList};
|
||||
use super::ffi::make_conversation;
|
||||
use super::ffi::{make_conversation, PamConvHandlerWrapper};
|
||||
|
||||
pub struct PamSession<'a> {
|
||||
handle: &'a mut PamHandle,
|
||||
pub converse: Box<PasswordConv>,
|
||||
pub converse: Box<PamConvHandlerWrapper>,
|
||||
last_code: PamReturnCode,
|
||||
}
|
||||
|
||||
impl<'a> PamSession<'a> {
|
||||
pub fn start(service: &str, mut pam_conv: Box<PasswordConv>) -> Result<PamSession, Box<dyn Error>> {
|
||||
let conv = make_conversation(&mut *pam_conv);
|
||||
pub fn start(service: &str, pam_conv: Box<dyn Converse>) -> Result<PamSession, Box<dyn Error>> {
|
||||
let mut pch = Box::new(PamConvHandlerWrapper { handler: pam_conv });
|
||||
let conv = make_conversation(&mut *pch);
|
||||
let mut pam_handle: *mut PamHandle = ptr::null_mut();
|
||||
|
||||
match pam_sys::start(service, None, &conv, &mut pam_handle) {
|
||||
PamReturnCode::SUCCESS => Ok(PamSession {
|
||||
handle: unsafe { &mut *pam_handle },
|
||||
converse: pam_conv,
|
||||
converse: pch,
|
||||
last_code: PamReturnCode::SUCCESS,
|
||||
}),
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, "unable to start pam session").into()),
|
||||
|
@@ -20,8 +20,8 @@ use pam_sys::{PamFlag, PamItemType};
|
||||
use users::os::unix::UserExt;
|
||||
use users::User;
|
||||
|
||||
use crate::pam::session::PamSession;
|
||||
use crate::pam::converse::PasswordConv;
|
||||
use crate::pam::session::PamSession;
|
||||
use crate::pollable::signals::blocked_sigset;
|
||||
use crate::terminal;
|
||||
|
||||
|
Reference in New Issue
Block a user