11use std:: io;
22
33use crate :: cutils:: string_from_ptr;
4- use crate :: system:: time:: Duration ;
4+ use crate :: system:: {
5+ signal:: { self , SignalSet } ,
6+ time:: Duration ,
7+ } ;
58
69use super :: sys:: * ;
710
@@ -65,16 +68,10 @@ fn handle_message<C: Converser>(
6568 use PamMessageStyle :: * ;
6669
6770 match style {
68- PromptEchoOn => {
69- if app_data. no_interact {
70- return Err ( PamError :: InteractionRequired ) ;
71- }
72- app_data. converser . handle_normal_prompt ( msg) . map ( Some )
73- }
71+ PromptEchoOn | PromptEchoOff if app_data. no_interact => Err ( PamError :: InteractionRequired ) ,
72+
73+ PromptEchoOn => app_data. converser . handle_normal_prompt ( msg) . map ( Some ) ,
7474 PromptEchoOff => {
75- if app_data. no_interact {
76- return Err ( PamError :: InteractionRequired ) ;
77- }
7875 let final_prompt = match app_data. auth_prompt . as_deref ( ) {
7976 None => {
8077 // Suppress password prompt entirely when -p '' is passed.
@@ -89,6 +86,7 @@ fn handle_message<C: Converser>(
8986 . handle_hidden_prompt ( & final_prompt)
9087 . map ( Some )
9188 }
89+
9290 ErrorMessage => app_data. converser . handle_error ( msg) . map ( |( ) | None ) ,
9391 TextInfo => app_data. converser . handle_info ( msg) . map ( |( ) | None ) ,
9492 }
@@ -106,25 +104,50 @@ pub struct CLIConverser {
106104
107105use rpassword:: Terminal ;
108106
107+ struct SignalGuard ( Option < SignalSet > ) ;
108+
109+ impl SignalGuard {
110+ fn unblock_interrupts ( ) -> Self {
111+ let cur_signals = SignalSet :: empty ( ) . and_then ( |mut set| {
112+ set. add ( signal:: consts:: SIGINT ) ?;
113+ set. add ( signal:: consts:: SIGQUIT ) ?;
114+ set. unblock ( )
115+ } ) ;
116+
117+ Self ( cur_signals. ok ( ) )
118+ }
119+ }
120+
121+ impl Drop for SignalGuard {
122+ fn drop ( & mut self ) {
123+ if let Some ( signal) = & self . 0 {
124+ // Ignore any errors at this point
125+ let _ = signal. set_mask ( ) ;
126+ }
127+ }
128+ }
129+
109130impl CLIConverser {
110- fn open ( & self ) -> std:: io:: Result < Terminal < ' _ > > {
111- if self . use_stdin {
112- Terminal :: open_stdie ( )
131+ fn open ( & self ) -> std:: io:: Result < ( Terminal < ' _ > , SignalGuard ) > {
132+ let term = if self . use_stdin {
133+ Terminal :: open_stdie ( ) ?
113134 } else {
114- Terminal :: open_tty ( )
115- }
135+ Terminal :: open_tty ( ) ?
136+ } ;
137+
138+ Ok ( ( term, SignalGuard :: unblock_interrupts ( ) ) )
116139 }
117140}
118141
119142impl Converser for CLIConverser {
120143 fn handle_normal_prompt ( & self , msg : & str ) -> PamResult < PamBuffer > {
121- let mut tty = self . open ( ) ?;
144+ let ( mut tty, _guard ) = self . open ( ) ?;
122145 tty. prompt ( & format ! ( "[{}: input needed] {msg} " , self . name) ) ?;
123146 Ok ( tty. read_cleartext ( ) ?)
124147 }
125148
126149 fn handle_hidden_prompt ( & self , msg : & str ) -> PamResult < PamBuffer > {
127- let mut tty = self . open ( ) ?;
150+ let ( mut tty, _guard ) = self . open ( ) ?;
128151 if self . bell && !self . use_stdin {
129152 tty. bell ( ) ?;
130153 }
@@ -144,12 +167,12 @@ impl Converser for CLIConverser {
144167 }
145168
146169 fn handle_error ( & self , msg : & str ) -> PamResult < ( ) > {
147- let mut tty = self . open ( ) ?;
170+ let ( mut tty, _ ) = self . open ( ) ?;
148171 Ok ( tty. prompt ( & format ! ( "[{} error] {msg}\n " , self . name) ) ?)
149172 }
150173
151174 fn handle_info ( & self , msg : & str ) -> PamResult < ( ) > {
152- let mut tty = self . open ( ) ?;
175+ let ( mut tty, _ ) = self . open ( ) ?;
153176 Ok ( tty. prompt ( & format ! ( "[{}] {msg}\n " , self . name) ) ?)
154177 }
155178}
0 commit comments