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