@@ -29,7 +29,7 @@ use warpgate_core::Services;
29
29
use self :: handler:: ClientHandlerEvent ;
30
30
use super :: { ChannelOperation , DirectTCPIPParams } ;
31
31
use crate :: client:: handler:: ClientHandlerError ;
32
- use crate :: { load_all_usable_private_keys, ForwardedTcpIpParams } ;
32
+ use crate :: { load_all_usable_private_keys, ForwardedStreamlocalParams , ForwardedTcpIpParams } ;
33
33
34
34
#[ derive( Debug , thiserror:: Error ) ]
35
35
pub enum ConnectionError {
@@ -91,6 +91,7 @@ pub enum RCEvent {
91
91
HostKeyReceived ( PublicKey ) ,
92
92
HostKeyUnknown ( PublicKey , oneshot:: Sender < bool > ) ,
93
93
ForwardedTcpIp ( Uuid , ForwardedTcpIpParams ) ,
94
+ ForwardedStreamlocal ( Uuid , ForwardedStreamlocalParams ) ,
94
95
X11 ( Uuid , String , u32 ) ,
95
96
}
96
97
@@ -102,6 +103,8 @@ pub enum RCCommand {
102
103
Channel ( Uuid , ChannelOperation ) ,
103
104
ForwardTCPIP ( String , u32 ) ,
104
105
CancelTCPIPForward ( String , u32 ) ,
106
+ StreamlocalForward ( String ) ,
107
+ CancelStreamlocalForward ( String ) ,
105
108
Disconnect ,
106
109
}
107
110
@@ -126,6 +129,7 @@ pub struct RemoteClient {
126
129
channel_pipes : Arc < Mutex < HashMap < Uuid , UnboundedSender < ChannelOperation > > > > ,
127
130
pending_ops : Vec < ( Uuid , ChannelOperation ) > ,
128
131
pending_forwards : Vec < ( String , u32 ) > ,
132
+ pending_streamlocal_forwards : Vec < String > ,
129
133
state : RCState ,
130
134
abort_rx : UnboundedReceiver < ( ) > ,
131
135
inner_event_rx : UnboundedReceiver < InnerEvent > ,
@@ -155,6 +159,7 @@ impl RemoteClient {
155
159
channel_pipes : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
156
160
pending_ops : vec ! [ ] ,
157
161
pending_forwards : vec ! [ ] ,
162
+ pending_streamlocal_forwards : vec ! [ ] ,
158
163
state : RCState :: NotInitialized ,
159
164
inner_event_rx,
160
165
inner_event_tx : inner_event_tx. clone ( ) ,
@@ -309,6 +314,11 @@ impl RemoteClient {
309
314
let id = self . setup_server_initiated_channel ( channel) . await ?;
310
315
let _ = self . tx . send ( RCEvent :: ForwardedTcpIp ( id, params) ) ;
311
316
}
317
+ ClientHandlerEvent :: ForwardedStreamlocal ( channel, params) => {
318
+ info ! ( "New forwarded socket connection: {params:?}" ) ;
319
+ let id = self . setup_server_initiated_channel ( channel) . await ?;
320
+ let _ = self . tx . send ( RCEvent :: ForwardedStreamlocal ( id, params) ) ;
321
+ }
312
322
ClientHandlerEvent :: X11 ( channel, originator_address, originator_port) => {
313
323
info ! ( "New X11 connection from {originator_address}:{originator_port:?}" ) ;
314
324
let id = self . setup_server_initiated_channel ( channel) . await ?;
@@ -355,10 +365,19 @@ impl RemoteClient {
355
365
for ( id, op) in ops {
356
366
self . apply_channel_op ( id, op) . await ?;
357
367
}
368
+
358
369
let forwards = self . pending_forwards . drain ( ..) . collect :: < Vec < _ > > ( ) ;
359
370
for ( address, port) in forwards {
360
371
self . tcpip_forward ( address, port) . await ?;
361
372
}
373
+
374
+ let forwards = self
375
+ . pending_streamlocal_forwards
376
+ . drain ( ..)
377
+ . collect :: < Vec < _ > > ( ) ;
378
+ for socket_path in forwards {
379
+ self . streamlocal_forward ( socket_path) . await ?;
380
+ }
362
381
}
363
382
Err ( e) => {
364
383
debug ! ( "Connect error: {}" , e) ;
@@ -376,6 +395,12 @@ impl RemoteClient {
376
395
RCCommand :: CancelTCPIPForward ( address, port) => {
377
396
self . cancel_tcpip_forward ( address, port) . await ?;
378
397
}
398
+ RCCommand :: StreamlocalForward ( socket_path) => {
399
+ self . streamlocal_forward ( socket_path) . await ?;
400
+ }
401
+ RCCommand :: CancelStreamlocalForward ( socket_path) => {
402
+ self . cancel_streamlocal_forward ( socket_path) . await ?;
403
+ }
379
404
RCCommand :: Disconnect => {
380
405
self . disconnect ( ) . await ;
381
406
return Ok ( true ) ;
@@ -635,6 +660,30 @@ impl RemoteClient {
635
660
Ok ( ( ) )
636
661
}
637
662
663
+ async fn streamlocal_forward ( & mut self , socket_path : String ) -> Result < ( ) , SshClientError > {
664
+ if let Some ( session) = & self . session {
665
+ let mut session = session. lock ( ) . await ;
666
+ session. streamlocal_forward ( socket_path) . await ?;
667
+ } else {
668
+ self . pending_streamlocal_forwards . push ( socket_path) ;
669
+ }
670
+ Ok ( ( ) )
671
+ }
672
+
673
+ async fn cancel_streamlocal_forward (
674
+ & mut self ,
675
+ socket_path : String ,
676
+ ) -> Result < ( ) , SshClientError > {
677
+ if let Some ( session) = & self . session {
678
+ let session = session. lock ( ) . await ;
679
+ session. cancel_streamlocal_forward ( socket_path) . await ?;
680
+ } else {
681
+ self . pending_streamlocal_forwards
682
+ . retain ( |x| x != & socket_path) ;
683
+ }
684
+ Ok ( ( ) )
685
+ }
686
+
638
687
async fn disconnect ( & mut self ) {
639
688
if let Some ( session) = & mut self . session {
640
689
let _ = session
0 commit comments