@@ -165,6 +165,7 @@ pub(crate) struct ConnectHandler<'a> {
165165 shared_args : & ' a SharedArgs < ' a > ,
166166 latest_key_password : RefCell < Option < String > > ,
167167 password_from_stdin : RefCell < Option < String > > ,
168+ cookie_from_stdin : RefCell < Option < String > > ,
168169}
169170
170171impl < ' a > ConnectHandler < ' a > {
@@ -174,6 +175,7 @@ impl<'a> ConnectHandler<'a> {
174175 shared_args,
175176 latest_key_password : Default :: default ( ) ,
176177 password_from_stdin : Default :: default ( ) ,
178+ cookie_from_stdin : Default :: default ( ) ,
177179 }
178180 }
179181
@@ -413,7 +415,7 @@ impl<'a> ConnectHandler<'a> {
413415
414416 async fn obtain_credential ( & self , prelogin : & Prelogin , server : & str ) -> anyhow:: Result < Credential > {
415417 if self . args . cookie_on_stdin {
416- return read_cookie_from_stdin ( ) ;
418+ return self . read_cookie_from_stdin ( ) ;
417419 }
418420
419421 let is_gateway = prelogin. is_gateway ( ) ;
@@ -473,6 +475,27 @@ impl<'a> ConnectHandler<'a> {
473475 }
474476 }
475477
478+ fn read_cookie_from_stdin ( & self ) -> anyhow:: Result < Credential > {
479+ // If the cookie has been read from stdin, use it directly
480+ if let Some ( cookie) = self . cookie_from_stdin . borrow ( ) . as_ref ( ) {
481+ info ! ( "Reusing the cookie read from standard input" ) ;
482+ return Credential :: try_from ( serde_json:: from_str :: < SamlAuthResult > ( cookie) ?) ;
483+ }
484+
485+ info ! ( "Reading cookie from standard input" ) ;
486+
487+ let mut cookie = String :: new ( ) ;
488+ std:: io:: stdin ( ) . read_line ( & mut cookie) ?;
489+
490+ // Considering that the gateway connection may fail even though the cookie read
491+ // from stdin is correct. It may retry the gateway connection, so we need to
492+ // save the cookie read from stdin to avoid reading stdin again.
493+ self . cookie_from_stdin . replace ( Some ( cookie. trim_end ( ) . to_owned ( ) ) ) ;
494+
495+ let auth_result = serde_json:: from_str :: < SamlAuthResult > ( cookie. trim_end ( ) ) . context ( "Failed to parse auth data" ) ?;
496+ Credential :: try_from ( auth_result)
497+ }
498+
476499 fn obtain_password ( & self , prelogin : & StandardPrelogin ) -> anyhow:: Result < String > {
477500 let password = if self . args . passwd_on_stdin {
478501 // If the password has been read from stdin, use it directly
@@ -522,16 +545,6 @@ impl<'a> ConnectHandler<'a> {
522545 }
523546}
524547
525- fn read_cookie_from_stdin ( ) -> anyhow:: Result < Credential > {
526- info ! ( "Reading cookie from standard input" ) ;
527-
528- let mut cookie = String :: new ( ) ;
529- std:: io:: stdin ( ) . read_line ( & mut cookie) ?;
530-
531- let auth_result = serde_json:: from_str :: < SamlAuthResult > ( cookie. trim_end ( ) ) . context ( "Failed to parse auth data" ) ?;
532- Credential :: try_from ( auth_result)
533- }
534-
535548fn write_pid_file ( ) {
536549 let pid = std:: process:: id ( ) ;
537550
0 commit comments