1
+ use std:: io;
2
+
1
3
use crate :: cutils:: string_from_ptr;
2
4
3
5
use super :: sys:: * ;
@@ -126,10 +128,17 @@ impl Converser for CLIConverser {
126
128
}
127
129
tty. prompt ( msg) ?;
128
130
if self . password_feedback {
129
- Ok ( tty. read_password_with_feedback ( ) ? )
131
+ tty. read_password_with_feedback ( )
130
132
} else {
131
- Ok ( tty. read_password ( ) ? )
133
+ tty. read_password ( )
132
134
}
135
+ . map_err ( |err| {
136
+ if let io:: ErrorKind :: TimedOut = err. kind ( ) {
137
+ PamError :: TimedOut
138
+ } else {
139
+ PamError :: IoError ( err)
140
+ }
141
+ } )
133
142
}
134
143
135
144
fn handle_error ( & self , msg : & str ) -> PamResult < ( ) > {
@@ -149,6 +158,10 @@ pub(super) struct ConverserData<C> {
149
158
pub ( super ) converser_name : String ,
150
159
pub ( super ) no_interact : bool ,
151
160
pub ( super ) auth_prompt : Option < String > ,
161
+ // pam_authenticate does not return error codes returned by the conversation
162
+ // function; these are set by the conversation function instead of returning
163
+ // multiple error codes.
164
+ pub ( super ) timed_out : bool ,
152
165
pub ( super ) panicked : bool ,
153
166
}
154
167
@@ -194,11 +207,16 @@ pub(super) unsafe extern "C" fn converse<C: Converser>(
194
207
// send the conversation off to the Rust part
195
208
// SAFETY: appdata_ptr contains the `*mut ConverserData` that is untouched by PAM
196
209
let app_data = unsafe { & mut * ( appdata_ptr as * mut ConverserData < C > ) } ;
197
- let Ok ( resp_buf) = handle_message ( app_data, style, & msg) else {
198
- return PamErrorType :: ConversationError ;
199
- } ;
200
-
201
- resp_bufs. push ( resp_buf) ;
210
+ match handle_message ( app_data, style, & msg) {
211
+ Ok ( resp_buf) => {
212
+ resp_bufs. push ( resp_buf) ;
213
+ }
214
+ Err ( PamError :: TimedOut ) => {
215
+ app_data. timed_out = true ;
216
+ return PamErrorType :: ConversationError ;
217
+ }
218
+ Err ( _) => return PamErrorType :: ConversationError ,
219
+ }
202
220
}
203
221
204
222
// Allocate enough memory for the responses, which are initialized with zero.
@@ -374,6 +392,7 @@ mod test {
374
392
converser_name : "tux" . to_string ( ) ,
375
393
no_interact : false ,
376
394
auth_prompt : Some ( "authenticate" . to_owned ( ) ) ,
395
+ timed_out : false ,
377
396
panicked : false ,
378
397
} ) ;
379
398
let cookie = PamConvBorrow :: new ( hello. as_mut ( ) ) ;
0 commit comments