@@ -25,13 +25,13 @@ use super::IncomingSshPacket;
2525use crate :: auth:: AuthRequest ;
2626use crate :: cert:: PublicKeyOrCertificate ;
2727use crate :: client:: { Handler , Msg , Prompt , Reply , Session } ;
28- use crate :: helpers:: { sign_with_hash_alg , AlgorithmExt , EncodedExt , NameList } ;
28+ use crate :: helpers:: { AlgorithmExt , EncodedExt , NameList , sign_with_hash_alg } ;
2929use crate :: keys:: key:: parse_public_key;
3030use crate :: parsing:: { ChannelOpenConfirmation , ChannelType , OpenChannelMessage } ;
3131use crate :: session:: { Encrypted , EncryptedState , GlobalRequestResponse } ;
3232use crate :: {
33- auth , map_err , msg , Channel , ChannelId , ChannelMsg , ChannelOpenFailure , ChannelParams , CryptoVec , Error ,
34- MethodSet , Sig ,
33+ Channel , ChannelId , ChannelMsg , ChannelOpenFailure , ChannelParams , Error , MethodSet , Sig , auth ,
34+ map_err , msg ,
3535} ;
3636
3737impl Session {
@@ -120,7 +120,9 @@ impl Session {
120120 let remaining_methods: MethodSet =
121121 ( & map_err ! ( NameList :: decode( & mut r) ) ?) . into ( ) ;
122122 let partial_success = map_err ! ( u8 :: decode( & mut r) ) ? != 0 ;
123- debug ! ( "remaining methods {remaining_methods:?}, partial success {partial_success:?}" ) ;
123+ debug ! (
124+ "remaining methods {remaining_methods:?}, partial success {partial_success:?}"
125+ ) ;
124126 auth_request. methods = remaining_methods. clone ( ) ;
125127
126128 let no_more_methods = auth_request. methods . is_empty ( ) ;
@@ -185,7 +187,7 @@ impl Session {
185187 let responses = loop {
186188 match self . receiver . recv ( ) . await {
187189 Some ( Msg :: AuthInfoResponse { responses } ) => {
188- break responses
190+ break responses;
189191 }
190192 None => return Err ( crate :: Error :: RecvError . into ( ) ) ,
191193 _ => { }
@@ -227,19 +229,13 @@ impl Session {
227229 ) ?;
228230 let len = self . common . buffer . len ( ) ;
229231 let buf = std:: mem:: take ( & mut self . common . buffer ) ;
230- // Convert Vec<u8>→CryptoVec at the Signer
231- // trait boundary (public API uses CryptoVec).
232- let mut cv = CryptoVec :: new ( ) ;
233- cv. extend ( & buf) ;
234232
235233 self . sender
236- . send ( Reply :: SignRequest { key, data : cv } )
234+ . send ( Reply :: SignRequest { key, data : buf } )
237235 . map_err ( |_| crate :: Error :: SendError ) ?;
238236 self . common . buffer = loop {
239237 match self . receiver . recv ( ) . await {
240- Some ( Msg :: Signed { data } ) => {
241- break data[ ..] . to_vec ( )
242- }
238+ Some ( Msg :: Signed { data } ) => break data[ ..] . to_vec ( ) ,
243239 None => return Err ( crate :: Error :: RecvError . into ( ) ) ,
244240 _ => { }
245241 }
@@ -252,6 +248,39 @@ impl Session {
252248 } )
253249 }
254250 }
251+ Some ( auth:: Method :: FutureCertificate { cert, hash_alg } ) => {
252+ debug ! ( "certificate" ) ;
253+ self . common . buffer . clear ( ) ;
254+ let i = enc. client_make_to_sign (
255+ & self . common . auth_user ,
256+ & PublicKeyOrCertificate :: Certificate ( cert. clone ( ) ) ,
257+ & mut self . common . buffer ,
258+ ) ?;
259+ let len = self . common . buffer . len ( ) ;
260+ let buf = std:: mem:: take ( & mut self . common . buffer ) ;
261+
262+ self . sender
263+ . send ( Reply :: SignRequestCert {
264+ cert,
265+ hash_alg,
266+ data : buf,
267+ } )
268+ . map_err ( |_| crate :: Error :: SendError ) ?;
269+ self . common . buffer = loop {
270+ match self . receiver . recv ( ) . await {
271+ Some ( Msg :: Signed { data } ) => break data,
272+ None => return Err ( crate :: Error :: RecvError . into ( ) ) ,
273+ _ => { }
274+ }
275+ } ;
276+ if self . common . buffer . len ( ) != len {
277+ // The buffer was modified.
278+ push_packet ! ( enc. write, {
279+ #[ allow( clippy:: indexing_slicing) ] // length checked
280+ enc. write. extend( & self . common. buffer[ i..] ) ;
281+ } )
282+ }
283+ }
255284 _ => { }
256285 }
257286 }
@@ -413,11 +442,7 @@ impl Session {
413442 }
414443
415444 if let Some ( chan) = self . channels . get ( & channel_num) {
416- let _ = chan
417- . send ( ChannelMsg :: Data {
418- data : data. clone ( ) ,
419- } )
420- . await ;
445+ let _ = chan. send ( ChannelMsg :: Data { data : data. clone ( ) } ) . await ;
421446 }
422447
423448 client. data ( channel_num, & data, self ) . await
@@ -867,9 +892,7 @@ impl Session {
867892 }
868893 EncryptedState :: InitCompression | EncryptedState :: Authenticated => false ,
869894 } ;
870- debug ! (
871- "write_auth_request_if_needed: is_waiting = {is_waiting:?}"
872- ) ;
895+ debug ! ( "write_auth_request_if_needed: is_waiting = {is_waiting:?}" ) ;
873896 if is_waiting {
874897 enc. write_auth_request ( user, & meth) ?;
875898 let auth_request = AuthRequest :: new ( & meth) ;
@@ -946,6 +969,18 @@ impl Encrypted {
946969 key. to_bytes( ) ?. as_slice( ) . encode( & mut self . write) ?;
947970 true
948971 }
972+ auth:: Method :: FutureCertificate { ref cert, .. } => {
973+ user. as_bytes( ) . encode( & mut self . write) ?;
974+ "ssh-connection" . encode( & mut self . write) ?;
975+ "publickey" . encode( & mut self . write) ?;
976+ self . write. push( 0 ) ; // This is a probe
977+
978+ cert. algorithm( )
979+ . to_certificate_type( )
980+ . encode( & mut self . write) ?;
981+ cert. to_bytes( ) ?. as_slice( ) . encode( & mut self . write) ?;
982+ true
983+ }
949984 auth:: Method :: KeyboardInteractive { ref submethods } => {
950985 debug!( "Keyboard interactive" ) ;
951986 user. as_bytes( ) . encode( & mut self . write) ?;
0 commit comments