11use std:: ffi:: { c_int, c_void} ;
2- use std:: io;
32use std:: time:: Duration ;
43
54use crate :: cutils:: string_from_ptr;
@@ -12,7 +11,7 @@ use super::{error::PamResult, rpassword, securemem::PamBuffer, PamError, PamErro
1211
1312/// Each message in a PAM conversation will have a message style. Each of these
1413/// styles must be handled separately.
15- #[ derive( Clone , Copy ) ]
14+ #[ derive( Clone , Copy , Eq , PartialEq ) ]
1615pub enum PamMessageStyle {
1716 /// Prompt for input using a message. The input should considered secret
1817 /// and should be hidden from view.
@@ -128,7 +127,7 @@ impl Drop for SignalGuard {
128127}
129128
130129impl CLIConverser {
131- fn open ( & self ) -> std :: io :: Result < ( Terminal < ' _ > , SignalGuard ) > {
130+ fn open ( & self ) -> PamResult < ( Terminal < ' _ > , SignalGuard ) > {
132131 let term = if self . use_stdin {
133132 Terminal :: open_stdie ( ) ?
134133 } else {
@@ -142,11 +141,11 @@ impl CLIConverser {
142141impl Converser for CLIConverser {
143142 fn handle_normal_prompt ( & self , msg : & str ) -> PamResult < PamBuffer > {
144143 let ( mut tty, _guard) = self . open ( ) ?;
145- Ok ( tty. read_input (
144+ tty. read_input (
146145 & format ! ( "[{}: input needed] {msg} " , self . name) ,
147146 None ,
148147 Hidden :: No ,
149- ) ? )
148+ )
150149 }
151150
152151 fn handle_hidden_prompt ( & self , msg : & str ) -> PamResult < PamBuffer > {
@@ -163,13 +162,6 @@ impl Converser for CLIConverser {
163162 Hidden :: Yes ( ( ) )
164163 } ,
165164 )
166- . map_err ( |err| {
167- if let io:: ErrorKind :: TimedOut = err. kind ( ) {
168- PamError :: TimedOut
169- } else {
170- PamError :: IoError ( err)
171- }
172- } )
173165 }
174166
175167 fn handle_error ( & self , msg : & str ) -> PamResult < ( ) > {
@@ -192,7 +184,7 @@ pub(super) struct ConverserData<C> {
192184 // pam_authenticate does not return error codes returned by the conversation
193185 // function; these are set by the conversation function instead of returning
194186 // multiple error codes.
195- pub ( super ) timed_out : bool ,
187+ pub ( super ) error : Option < PamError > ,
196188 pub ( super ) panicked : bool ,
197189}
198190
@@ -238,15 +230,22 @@ pub(super) unsafe extern "C" fn converse<C: Converser>(
238230 // send the conversation off to the Rust part
239231 // SAFETY: appdata_ptr contains the `*mut ConverserData` that is untouched by PAM
240232 let app_data = unsafe { & mut * ( appdata_ptr as * mut ConverserData < C > ) } ;
233+
234+ if app_data. error . is_some ( )
235+ && ( style == PamMessageStyle :: PromptEchoOff
236+ || style == PamMessageStyle :: PromptEchoOn )
237+ {
238+ return PamErrorType :: ConversationError ;
239+ }
240+
241241 match handle_message ( app_data, style, & msg) {
242242 Ok ( resp_buf) => {
243243 resp_bufs. push ( resp_buf) ;
244244 }
245- Err ( PamError :: TimedOut ) => {
246- app_data. timed_out = true ;
245+ Err ( err ) => {
246+ app_data. error = Some ( err ) ;
247247 return PamErrorType :: ConversationError ;
248248 }
249- Err ( _) => return PamErrorType :: ConversationError ,
250249 }
251250 }
252251
@@ -423,7 +422,7 @@ mod test {
423422 converser_name : "tux" . to_string ( ) ,
424423 no_interact : false ,
425424 auth_prompt : Some ( "authenticate" . to_owned ( ) ) ,
426- timed_out : false ,
425+ error : None ,
427426 panicked : false ,
428427 } ) ;
429428 let cookie = PamConvBorrow :: new ( hello. as_mut ( ) ) ;
0 commit comments