@@ -4,7 +4,7 @@ use anyhow::{Error, Result};
44use futures:: stream:: StreamExt ;
55use log:: * ;
66use std:: time:: Duration ;
7- use tokio:: time;
7+ use tokio:: { io :: AsyncWriteExt , time} ;
88use tokio_util:: compat:: * ;
99
1010mod fallback;
@@ -23,11 +23,17 @@ use pty::*;
2323
2424type ShellStream = ShellServerStream < Compat < Box < dyn TunnelStream > > > ;
2525
26- pub ( crate ) struct ShellServer { }
26+ pub ( crate ) struct ShellServer {
27+ conf : ShellServerConfig ,
28+ }
29+
30+ pub ( crate ) struct ShellServerConfig {
31+ pub ( crate ) echo_stdout : bool ,
32+ }
2733
2834impl ShellServer {
29- pub ( crate ) fn new ( ) -> Result < ShellServer > {
30- Ok ( ShellServer { } )
35+ pub ( crate ) fn new ( conf : ShellServerConfig ) -> Result < ShellServer > {
36+ Ok ( ShellServer { conf } )
3137 }
3238
3339 pub ( crate ) async fn run ( self , stream : Box < dyn TunnelStream > , key : ShellKey ) -> Result < ( ) > {
@@ -108,6 +114,11 @@ impl ShellServer {
108114 mut shell : Box < dyn Shell + Send + ' a > ,
109115 ) -> Result < ( ) > {
110116 let mut buff = [ 0u8 ; 1024 ] ;
117+ let mut host_stdout = if self . conf . echo_stdout {
118+ Some ( tokio:: io:: stdout ( ) )
119+ } else {
120+ None
121+ } ;
111122
112123 loop {
113124 info ! ( "waiting for shell message" ) ;
@@ -122,6 +133,12 @@ impl ShellServer {
122133 } ,
123134 Ok ( read) => {
124135 info!( "read {} bytes from stdout" , read) ;
136+
137+ if let Some ( host_stdout) = host_stdout. as_mut( ) {
138+ host_stdout. write_all( & buff[ ..read] ) . await ?;
139+ host_stdout. flush( ) . await ?;
140+ }
141+
125142 stream. write( & ShellServerMessage :: Stdout ( buff[ ..read] . to_vec( ) ) ) . await ?;
126143 info!( "sent {} bytes to client shell" , read) ;
127144 } ,
@@ -167,9 +184,13 @@ mod tests {
167184 use tokio:: time:: timeout;
168185 use tunshell_shared:: Message ;
169186
187+ fn new_shell_server ( ) -> ShellServer {
188+ ShellServer :: new ( ShellServerConfig { echo_stdout : true } ) . unwrap ( )
189+ }
190+
170191 #[ test]
171192 fn test_new_shell_server ( ) {
172- ShellServer :: new ( ) . unwrap ( ) ;
193+ new_shell_server ( ) ;
173194 }
174195
175196 #[ test]
@@ -186,8 +207,7 @@ mod tests {
186207 ) ;
187208
188209 let mock_stream = Cursor :: new ( mock_data) . compat ( ) ;
189- ShellServer :: new ( )
190- . unwrap ( )
210+ new_shell_server ( )
191211 . run ( Box :: new ( mock_stream) , ShellKey :: new ( "MyKey" ) )
192212 . await
193213 . expect_err ( "client key should be rejected" ) ;
@@ -203,9 +223,7 @@ mod tests {
203223
204224 timeout (
205225 Duration :: from_millis ( 5000 ) ,
206- ShellServer :: new ( )
207- . unwrap ( )
208- . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) ) ,
226+ new_shell_server ( ) . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) ) ,
209227 )
210228 . await
211229 . unwrap ( )
@@ -230,9 +248,7 @@ mod tests {
230248
231249 timeout (
232250 Duration :: from_millis ( 5000 ) ,
233- ShellServer :: new ( )
234- . unwrap ( )
235- . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) ) ,
251+ new_shell_server ( ) . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) ) ,
236252 )
237253 . await
238254 . unwrap ( )
@@ -289,7 +305,7 @@ mod tests {
289305 ) ;
290306
291307 let mock_stream = Cursor :: new ( mock_data) . compat ( ) ;
292- let server = ShellServer :: new ( ) . unwrap ( ) ;
308+ let server = new_shell_server ( ) ;
293309
294310 server
295311 . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) )
@@ -331,7 +347,7 @@ mod tests {
331347 ) ;
332348
333349 let mock_stream = Cursor :: new ( mock_data) . compat ( ) ;
334- let server = ShellServer :: new ( ) . unwrap ( ) ;
350+ let server = new_shell_server ( ) ;
335351
336352 server
337353 . run ( Box :: new ( mock_stream) , ShellKey :: new ( "CorrectKey" ) )
0 commit comments