@@ -3,6 +3,7 @@ use super::{Error, Session};
3
3
use std:: borrow:: Cow ;
4
4
use std:: ffi:: OsString ;
5
5
use std:: fs;
6
+ use std:: iter:: IntoIterator ;
6
7
use std:: path:: { Path , PathBuf } ;
7
8
use std:: process:: Stdio ;
8
9
use std:: str;
@@ -45,6 +46,7 @@ pub struct SessionBuilder {
45
46
control_dir : Option < PathBuf > ,
46
47
config_file : Option < PathBuf > ,
47
48
compression : Option < bool > ,
49
+ jump_hosts : Vec < Box < str > > ,
48
50
user_known_hosts_file : Option < Box < Path > > ,
49
51
}
50
52
@@ -60,6 +62,7 @@ impl Default for SessionBuilder {
60
62
control_dir : None ,
61
63
config_file : None ,
62
64
compression : None ,
65
+ jump_hosts : Vec :: new ( ) ,
63
66
user_known_hosts_file : None ,
64
67
}
65
68
}
@@ -153,6 +156,27 @@ impl SessionBuilder {
153
156
self
154
157
}
155
158
159
+ /// Specify one or multiple jump hosts.
160
+ ///
161
+ /// Connect to the target host by first making a ssh connection to the
162
+ /// jump host described by destination and then establishing a TCP
163
+ /// forwarding to the ultimate destination from there.
164
+ ///
165
+ /// Multiple jump hops may be specified.
166
+ /// This is a shortcut to specify a ProxyJump configuration directive.
167
+ ///
168
+ /// Note that configuration directives specified by [`SessionBuilder`]
169
+ /// do not apply to the jump hosts.
170
+ ///
171
+ /// Use ~/.ssh/config to specify configuration for jump hosts.
172
+ pub fn jump_hosts < T : AsRef < str > > ( & mut self , hosts : impl IntoIterator < Item = T > ) -> & mut Self {
173
+ self . jump_hosts = hosts
174
+ . into_iter ( )
175
+ . map ( |s| s. as_ref ( ) . to_string ( ) . into_boxed_str ( ) )
176
+ . collect ( ) ;
177
+ self
178
+ }
179
+
156
180
/// Specify the path to the `known_hosts` file.
157
181
///
158
182
/// The path provided may use tilde notation (`~`) to refer to the user's
@@ -317,6 +341,20 @@ impl SessionBuilder {
317
341
init. arg ( "-o" ) . arg ( format ! ( "Compression={}" , arg) ) ;
318
342
}
319
343
344
+ let mut it = self . jump_hosts . iter ( ) ;
345
+
346
+ if let Some ( jump_host) = it. next ( ) {
347
+ let s = jump_host. to_string ( ) ;
348
+
349
+ let dest = it. fold ( s, |mut s, jump_host| {
350
+ s. push ( ',' ) ;
351
+ s. push_str ( jump_host) ;
352
+ s
353
+ } ) ;
354
+
355
+ init. arg ( "-J" ) . arg ( & dest) ;
356
+ }
357
+
320
358
if let Some ( user_known_hosts_file) = & self . user_known_hosts_file {
321
359
let mut option: OsString = "UserKnownHostsFile=" . into ( ) ;
322
360
option. push ( & * * user_known_hosts_file) ;
0 commit comments