@@ -11,8 +11,9 @@ use mullvad_types::relay_constraints::{
11
11
Udp2TcpObfuscationSettings , WireguardConstraints ,
12
12
} ;
13
13
use mullvad_types:: wireguard;
14
+ use std:: net:: SocketAddr ;
14
15
use talpid_types:: net:: {
15
- proxy:: { CustomProxy , Socks5Remote } ,
16
+ proxy:: { CustomProxy , Socks5Local , Socks5Remote } ,
16
17
TransportProtocol , TunnelType ,
17
18
} ;
18
19
use test_macro:: test_function;
@@ -666,3 +667,105 @@ pub async fn test_remote_socks_bridge(
666
667
667
668
Ok ( ( ) )
668
669
}
670
+
671
+ /// Try to connect to an OpenVPN relay via a local, passwordless SOCKS5 server.
672
+ /// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
673
+ /// * The conncheck reports an unexpected exit relay.
674
+ #[ test_function]
675
+ pub async fn test_local_socks_bridge (
676
+ _: TestContext ,
677
+ rpc : ServiceClient ,
678
+ mut mullvad_client : MullvadProxyClient ,
679
+ ) -> Result < ( ) , Error > {
680
+ let remote_addr = SocketAddr :: from ( (
681
+ crate :: vm:: network:: NON_TUN_GATEWAY ,
682
+ crate :: vm:: network:: SOCKS5_PORT ,
683
+ ) ) ;
684
+ let socks_server = rpc
685
+ . start_tcp_forward ( "127.0.0.1:0" . parse ( ) . unwrap ( ) , remote_addr)
686
+ . await
687
+ . expect ( "failed to start TCP forward" ) ;
688
+
689
+ // FIXME: needs to connect before?
690
+
691
+ mullvad_client
692
+ . set_bridge_state ( relay_constraints:: BridgeState :: On )
693
+ . await
694
+ . expect ( "failed to enable bridge mode" ) ;
695
+
696
+ mullvad_client
697
+ . set_bridge_settings ( BridgeSettings {
698
+ bridge_type : BridgeType :: Custom ,
699
+ normal : BridgeConstraints :: default ( ) ,
700
+ custom : Some ( CustomProxy :: Socks5Local ( Socks5Local :: new (
701
+ remote_addr,
702
+ socks_server. bind_addr ( ) . port ( ) ,
703
+ ) ) ) ,
704
+ } )
705
+ . await
706
+ . expect ( "failed to update bridge settings" ) ;
707
+
708
+ set_relay_settings (
709
+ & mut mullvad_client,
710
+ RelaySettings :: Normal ( RelayConstraints {
711
+ tunnel_protocol : Constraint :: Only ( TunnelType :: OpenVpn ) ,
712
+ ..Default :: default ( )
713
+ } ) ,
714
+ )
715
+ . await
716
+ . expect ( "failed to update relay settings" ) ;
717
+
718
+ //
719
+ // Connect to VPN
720
+ //
721
+
722
+ connect_and_wait ( & mut mullvad_client) . await ?;
723
+
724
+ let ( entry, exit) = match mullvad_client. get_tunnel_state ( ) . await ? {
725
+ mullvad_types:: states:: TunnelState :: Connected { endpoint, .. } => {
726
+ ( endpoint. proxy . unwrap ( ) . endpoint , endpoint. endpoint )
727
+ }
728
+ actual => {
729
+ panic ! ( "unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}" )
730
+ }
731
+ } ;
732
+
733
+ log:: info!(
734
+ "Selected entry bridge {entry_addr} & exit relay {exit_addr}" ,
735
+ entry_addr = entry. address,
736
+ exit_addr = exit. address
737
+ ) ;
738
+
739
+ // Start recording outgoing packets. Their destination will be verified
740
+ // against the bridge's IP address later.
741
+ let monitor = start_packet_monitor (
742
+ move |packet| packet. destination . ip ( ) == entry. address . ip ( ) ,
743
+ MonitorOptions :: default ( ) ,
744
+ )
745
+ . await ;
746
+
747
+ //
748
+ // Verify exit IP
749
+ //
750
+
751
+ log:: info!( "Verifying exit server" ) ;
752
+
753
+ assert ! (
754
+ helpers:: using_mullvad_exit( & rpc) . await ,
755
+ "expected Mullvad exit IP"
756
+ ) ;
757
+
758
+ //
759
+ // Verify entry IP
760
+ //
761
+
762
+ log:: info!( "Verifying entry server" ) ;
763
+
764
+ let monitor_result = monitor. into_result ( ) . await . unwrap ( ) ;
765
+ assert ! (
766
+ !monitor_result. packets. is_empty( ) ,
767
+ "detected no traffic to entry server" ,
768
+ ) ;
769
+
770
+ Ok ( ( ) )
771
+ }
0 commit comments