Skip to content

Commit 766ec5d

Browse files
committed
Add test for remote custom SOCKS5 bridge
1 parent d6f28b6 commit 766ec5d

File tree

1 file changed

+189
-3
lines changed

1 file changed

+189
-3
lines changed

test/test-manager/src/tests/tunnel.rs

+189-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ use crate::network_monitor::{start_packet_monitor, MonitorOptions};
66

77
use mullvad_management_interface::MullvadProxyClient;
88
use mullvad_types::relay_constraints::{
9-
self, BridgeSettings, Constraint, OpenVpnConstraints, RelayConstraints, RelaySettings,
10-
SelectedObfuscation, TransportPort, Udp2TcpObfuscationSettings, WireguardConstraints,
9+
self, BridgeConstraints, BridgeSettings, BridgeType, Constraint, OpenVpnConstraints,
10+
RelayConstraints, RelaySettings, SelectedObfuscation, TransportPort,
11+
Udp2TcpObfuscationSettings, WireguardConstraints,
1112
};
1213
use mullvad_types::wireguard;
13-
use talpid_types::net::{TransportProtocol, TunnelType};
14+
use talpid_types::net::{
15+
proxy::{CustomProxy, Socks5Remote},
16+
TransportProtocol, TunnelType,
17+
};
1418
use test_macro::test_function;
1519
use test_rpc::meta::Os;
1620
use test_rpc::mullvad_daemon::ServiceStatus;
@@ -571,3 +575,185 @@ pub async fn test_quantum_resistant_multihop_udp2tcp_tunnel(
571575

572576
Ok(())
573577
}
578+
579+
/// Try to connect to an OpenVPN relay via a remote, passwordless SOCKS5 server.
580+
/// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
581+
/// * The conncheck reports an unexpected exit relay.
582+
#[test_function]
583+
pub async fn test_remote_socks_bridge(
584+
_: TestContext,
585+
rpc: ServiceClient,
586+
mut mullvad_client: MullvadProxyClient,
587+
) -> Result<(), Error> {
588+
mullvad_client
589+
.set_bridge_state(relay_constraints::BridgeState::On)
590+
.await
591+
.expect("failed to enable bridge mode");
592+
593+
mullvad_client
594+
.set_bridge_settings(BridgeSettings {
595+
bridge_type: BridgeType::Custom,
596+
normal: BridgeConstraints::default(),
597+
custom: Some(CustomProxy::Socks5Remote(Socks5Remote::new((
598+
crate::vm::network::NON_TUN_GATEWAY,
599+
crate::vm::network::SOCKS5_PORT,
600+
)))),
601+
})
602+
.await
603+
.expect("failed to update bridge settings");
604+
605+
set_relay_settings(
606+
&mut mullvad_client,
607+
RelaySettings::Normal(RelayConstraints {
608+
tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
609+
..Default::default()
610+
}),
611+
)
612+
.await
613+
.expect("failed to update relay settings");
614+
615+
//
616+
// Connect to VPN
617+
//
618+
619+
connect_and_wait(&mut mullvad_client).await?;
620+
621+
let (entry, exit) = match mullvad_client.get_tunnel_state().await? {
622+
mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
623+
(endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
624+
}
625+
actual => {
626+
panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}")
627+
}
628+
};
629+
630+
log::info!(
631+
"Selected entry bridge {entry_addr} & exit relay {exit_addr}",
632+
entry_addr = entry.address,
633+
exit_addr = exit.address
634+
);
635+
636+
// Start recording outgoing packets. Their destination will be verified
637+
// against the bridge's IP address later.
638+
let monitor = start_packet_monitor(
639+
move |packet| packet.destination.ip() == entry.address.ip(),
640+
MonitorOptions::default(),
641+
)
642+
.await;
643+
644+
//
645+
// Verify exit IP
646+
//
647+
648+
log::info!("Verifying exit server");
649+
650+
assert!(
651+
helpers::using_mullvad_exit(&rpc).await,
652+
"expected Mullvad exit IP"
653+
);
654+
655+
//
656+
// Verify entry IP
657+
//
658+
659+
log::info!("Verifying entry server");
660+
661+
let monitor_result = monitor.into_result().await.unwrap();
662+
assert!(
663+
!monitor_result.packets.is_empty(),
664+
"detected no traffic to entry server",
665+
);
666+
667+
Ok(())
668+
}
669+
670+
/// Try to connect to an OpenVPN relay via a local, passwordless SOCKS5 server.
671+
/// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
672+
/// * The conncheck reports an unexpected exit relay.
673+
#[test_function]
674+
pub async fn test_local_socks_bridge(
675+
_: TestContext,
676+
rpc: ServiceClient,
677+
mut mullvad_client: MullvadProxyClient,
678+
) -> Result<(), Error> {
679+
mullvad_client
680+
.set_bridge_state(relay_constraints::BridgeState::On)
681+
.await
682+
.expect("failed to enable bridge mode");
683+
684+
mullvad_client
685+
.set_bridge_settings(BridgeSettings {
686+
bridge_type: BridgeType::Custom,
687+
normal: BridgeConstraints::default(),
688+
custom: Some(CustomProxy::Socks5Remote(Socks5Remote::new((
689+
crate::vm::network::NON_TUN_GATEWAY,
690+
crate::vm::network::SOCKS5_PORT,
691+
)))),
692+
})
693+
.await
694+
.expect("failed to update bridge settings");
695+
696+
set_relay_settings(
697+
&mut mullvad_client,
698+
RelaySettings::Normal(RelayConstraints {
699+
tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
700+
..Default::default()
701+
}),
702+
)
703+
.await
704+
.expect("failed to update relay settings");
705+
706+
//
707+
// Connect to VPN
708+
//
709+
710+
connect_and_wait(&mut mullvad_client).await?;
711+
712+
let (entry, exit) = match mullvad_client.get_tunnel_state().await? {
713+
mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
714+
(endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
715+
}
716+
actual => {
717+
panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}")
718+
}
719+
};
720+
721+
log::info!(
722+
"Selected entry bridge {entry_addr} & exit relay {exit_addr}",
723+
entry_addr = entry.address,
724+
exit_addr = exit.address
725+
);
726+
727+
// Start recording outgoing packets. Their destination will be verified
728+
// against the bridge's IP address later.
729+
let monitor = start_packet_monitor(
730+
move |packet| packet.destination.ip() == entry.address.ip(),
731+
MonitorOptions::default(),
732+
)
733+
.await;
734+
735+
//
736+
// Verify exit IP
737+
//
738+
739+
log::info!("Verifying exit server");
740+
741+
assert!(
742+
helpers::using_mullvad_exit(&rpc).await,
743+
"expected Mullvad exit IP"
744+
);
745+
746+
//
747+
// Verify entry IP
748+
//
749+
750+
log::info!("Verifying entry server");
751+
752+
let monitor_result = monitor.into_result().await.unwrap();
753+
assert!(
754+
!monitor_result.packets.is_empty(),
755+
"detected no traffic to entry server",
756+
);
757+
758+
Ok(())
759+
}

0 commit comments

Comments
 (0)