diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-06-11 13:53:25 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-06-11 15:31:57 +0200 |
| commit | 9742344ce30a135d2475d8231fe72bb45f06d155 (patch) | |
| tree | a059b114fffa7cace10c050f6e944a21ce0f6cc0 | |
| parent | 4e9cace12939e6a906a238554a5779604d10e3e7 (diff) | |
| download | mullvadvpn-9742344ce30a135d2475d8231fe72bb45f06d155.tar.xz mullvadvpn-9742344ce30a135d2475d8231fe72bb45f06d155.zip | |
Pass a single relay client path to WinFw
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 12 | ||||
| -rw-r--r-- | mullvad-setup/src/main.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 11 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows.rs | 74 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 20 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 9 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 11 |
8 files changed, 72 insertions, 69 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 9b1854d4a3..e8edcbcafa 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -564,8 +564,6 @@ where tunnel_state_machine_shutdown_tx, #[cfg(target_os = "android")] android_context, - #[cfg(windows)] - Self::get_approved_applications(), ) .map_err(Error::TunnelError)?; @@ -636,16 +634,6 @@ where Ok(daemon) } - #[cfg(windows)] - fn get_approved_applications() -> Vec<PathBuf> { - let resource_dir = mullvad_paths::get_resource_dir(); - vec![ - resource_dir.join("mullvad-daemon.exe"), - resource_dir.join("openvpn.exe"), - resource_dir.join("sslocal.exe"), - ] - } - /// Consume the `Daemon` and run the main event loop. Blocks until an error happens or a /// shutdown event is received. pub fn run(mut self) -> Result<(), Error> { diff --git a/mullvad-setup/src/main.rs b/mullvad-setup/src/main.rs index a01f832c3e..f8fda169b5 100644 --- a/mullvad-setup/src/main.rs +++ b/mullvad-setup/src/main.rs @@ -69,8 +69,6 @@ fn reset_firewall() -> Result<(), Error> { let mut firewall = Firewall::new(FirewallArguments { initialize_blocked: false, allow_lan: None, - #[cfg(windows)] - approved_applications: vec!["foobar".into()], }) .map_err(Error::FirewallError)?; diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 80c9b65713..6b65dd5b70 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -94,6 +94,9 @@ pub enum FirewallPolicy { pingable_hosts: Vec<IpAddr>, /// Flag setting if communication with LAN networks should be possible. allow_lan: bool, + /// A process that is allowed to send packets to the relay. + #[cfg(windows)] + relay_client: PathBuf, }, /// Allow traffic only to server and over tunnel interface @@ -104,6 +107,9 @@ pub enum FirewallPolicy { tunnel: crate::tunnel::TunnelMetadata, /// Flag setting if communication with LAN networks should be possible. allow_lan: bool, + /// A process that is allowed to send packets to the relay. + #[cfg(windows)] + relay_client: PathBuf, }, /// Block all network traffic in and out from the computer. @@ -120,6 +126,7 @@ impl fmt::Display for FirewallPolicy { peer_endpoint, pingable_hosts, allow_lan, + .. } => write!( f, "Connecting to {} with gateways {}, {} LAN", @@ -135,6 +142,7 @@ impl fmt::Display for FirewallPolicy { peer_endpoint, tunnel, allow_lan, + .. } => write!( f, "Connected to {} over \"{}\" (ip: {}, v4 gw: {}, v6 gw: {:?}), {} LAN", @@ -171,9 +179,6 @@ pub struct FirewallArguments { pub initialize_blocked: bool, /// This argument is required for the blocked state to configure the firewall correctly. pub allow_lan: Option<bool>, - /// List of applications that are approved for communicating with the relay. - #[cfg(windows)] - pub approved_applications: Vec<PathBuf>, } impl Firewall { diff --git a/talpid-core/src/firewall/windows.rs b/talpid-core/src/firewall/windows.rs index d3b18c2c3a..4cd689cd44 100644 --- a/talpid-core/src/firewall/windows.rs +++ b/talpid-core/src/firewall/windows.rs @@ -1,11 +1,12 @@ use crate::logging::windows::log_sink; -use std::{net::IpAddr, ptr}; +use std::{net::IpAddr, path::Path, ptr}; use self::winfw::*; use super::{FirewallArguments, FirewallPolicy, FirewallT}; use crate::winnet; use log::{debug, error, trace}; +use std::os::windows::ffi::OsStrExt; use talpid_types::net::Endpoint; use widestring::WideCString; @@ -53,28 +54,12 @@ impl FirewallT for Firewall { fn new(args: FirewallArguments) -> Result<Self, Self::Error> { let logging_context = b"WinFw\0".as_ptr(); - let app_strings = args - .approved_applications - .iter() - .map(|app| Self::to_widestring(app.to_string_lossy())) - .collect::<Vec<_>>(); - let app_ptrs = app_strings - .iter() - .map(|app| app.as_ptr()) - .collect::<Vec<_>>(); - - let approved_applications = WinFwApprovedApplications { - apps: app_ptrs.as_ptr(), - num_apps: app_ptrs.len(), - }; - if args.initialize_blocked { let cfg = &WinFwSettings::new(args.allow_lan.unwrap()); unsafe { WinFw_InitializeBlocked( WINFW_TIMEOUT_SECONDS, &cfg, - &approved_applications, Some(log_sink), logging_context, ) @@ -82,13 +67,8 @@ impl FirewallT for Firewall { }; } else { unsafe { - WinFw_Initialize( - WINFW_TIMEOUT_SECONDS, - &approved_applications, - Some(log_sink), - logging_context, - ) - .into_result()? + WinFw_Initialize(WINFW_TIMEOUT_SECONDS, Some(log_sink), logging_context) + .into_result()? }; } @@ -102,6 +82,7 @@ impl FirewallT for Firewall { peer_endpoint, pingable_hosts, allow_lan, + relay_client, } => { let cfg = &WinFwSettings::new(allow_lan); // TODO: Determine interface alias at runtime @@ -110,15 +91,17 @@ impl FirewallT for Firewall { &cfg, "wg-mullvad".to_string(), &pingable_hosts, + &relay_client, ) } FirewallPolicy::Connected { peer_endpoint, tunnel, allow_lan, + relay_client, } => { let cfg = &WinFwSettings::new(allow_lan); - self.set_connected_state(&peer_endpoint, &cfg, &tunnel) + self.set_connected_state(&peer_endpoint, &cfg, &tunnel, &relay_client) } FirewallPolicy::Blocked { allow_lan } => { let cfg = &WinFwSettings::new(allow_lan); @@ -154,6 +137,7 @@ impl Firewall { winfw_settings: &WinFwSettings, _tunnel_iface_alias: String, pingable_hosts: &Vec<IpAddr>, + relay_client: &Path, ) -> Result<(), Error> { trace!("Applying 'connecting' firewall policy"); let ip_str = Self::widestring_ip(endpoint.address.ip()); @@ -165,10 +149,18 @@ impl Firewall { protocol: WinFwProt::from(endpoint.protocol), }; + let mut relay_client: Vec<u16> = relay_client.as_os_str().encode_wide().collect(); + relay_client.push(0u16); + if pingable_hosts.is_empty() { unsafe { - return WinFw_ApplyPolicyConnecting(winfw_settings, &winfw_relay, ptr::null()) - .into_result(); + return WinFw_ApplyPolicyConnecting( + winfw_settings, + &winfw_relay, + relay_client.as_ptr(), + ptr::null(), + ) + .into_result(); } } @@ -188,7 +180,13 @@ impl Firewall { }; unsafe { - WinFw_ApplyPolicyConnecting(winfw_settings, &winfw_relay, &pingable_hosts).into_result() + WinFw_ApplyPolicyConnecting( + winfw_settings, + &winfw_relay, + relay_client.as_ptr(), + &pingable_hosts, + ) + .into_result() } } @@ -197,16 +195,12 @@ impl Firewall { WideCString::new(buf).unwrap() } - fn to_widestring<T: AsRef<str>>(string: T) -> WideCString { - let buf = string.as_ref().encode_utf16().collect::<Vec<_>>(); - WideCString::new(buf).unwrap() - } - fn set_connected_state( &mut self, endpoint: &Endpoint, winfw_settings: &WinFwSettings, tunnel_metadata: &crate::tunnel::TunnelMetadata, + relay_client: &Path, ) -> Result<(), Error> { trace!("Applying 'connected' firewall policy"); let ip_str = Self::widestring_ip(endpoint.address.ip()); @@ -239,10 +233,14 @@ impl Firewall { None => ptr::null(), }; + let mut relay_client: Vec<u16> = relay_client.as_os_str().encode_wide().collect(); + relay_client.push(0u16); + unsafe { WinFw_ApplyPolicyConnected( winfw_settings, &winfw_relay, + relay_client.as_ptr(), tunnel_alias.as_ptr(), v4_gateway.as_ptr(), v6_gateway_ptr, @@ -311,12 +309,6 @@ mod winfw { pub num_addresses: usize, } - #[repr(C)] - pub struct WinFwApprovedApplications { - pub apps: *const *const libc::wchar_t, - pub num_apps: usize, - } - #[allow(dead_code)] #[repr(u8)] #[derive(Clone, Copy)] @@ -336,7 +328,6 @@ mod winfw { #[link_name = "WinFw_Initialize"] pub fn WinFw_Initialize( timeout: libc::c_uint, - approved_applications: *const WinFwApprovedApplications, sink: Option<LogSink>, sink_context: *const u8, ) -> InitializationResult; @@ -345,7 +336,6 @@ mod winfw { pub fn WinFw_InitializeBlocked( timeout: libc::c_uint, settings: &WinFwSettings, - approved_applications: *const WinFwApprovedApplications, sink: Option<LogSink>, sink_context: *const u8, ) -> InitializationResult; @@ -357,6 +347,7 @@ mod winfw { pub fn WinFw_ApplyPolicyConnecting( settings: &WinFwSettings, relay: &WinFwRelay, + relayClient: *const libc::wchar_t, pingable_hosts: *const WinFwPingableHosts, ) -> ApplyConnectingResult; @@ -364,6 +355,7 @@ mod winfw { pub fn WinFw_ApplyPolicyConnected( settings: &WinFwSettings, relay: &WinFwRelay, + relayClient: *const libc::wchar_t, tunnelIfaceAlias: *const libc::wchar_t, v4Gateway: *const libc::wchar_t, v6Gateway: *const libc::wchar_t, diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index 8e19fe3813..3ad5469ac5 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -175,6 +175,26 @@ impl TunnelMonitor { } } + /// Returns a path to an executable that communicates with relay servers. + #[cfg(windows)] + pub fn get_relay_client(resource_dir: &Path, params: &TunnelParameters) -> PathBuf { + let resource_dir = resource_dir.to_path_buf(); + let process_string = match params { + TunnelParameters::OpenVpn(params) => { + if let Some(proxy) = ¶ms.proxy { + match proxy { + openvpn_types::ProxySettings::Shadowsocks(..) => "sslocal.exe", + _ => "openvpn.exe", + } + } else { + "openvpn.exe" + } + } + _ => "mullvad-daemon.exe", + }; + resource_dir.join(process_string) + } + fn start_wireguard_tunnel<L>( params: &wireguard_types::TunnelParameters, log: Option<PathBuf>, diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 6ba26007b7..7ddc9bedeb 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -16,6 +16,10 @@ use talpid_types::{ BoxedError, ErrorExt, }; +#[cfg(windows)] +use crate::tunnel::TunnelMonitor; + + pub struct ConnectedStateBootstrap { pub metadata: TunnelMetadata, pub tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>, @@ -55,6 +59,11 @@ impl ConnectedState { peer_endpoint, tunnel: self.metadata.clone(), allow_lan: shared_values.allow_lan, + #[cfg(windows)] + relay_client: TunnelMonitor::get_relay_client( + &shared_values.resource_dir, + &self.tunnel_parameters, + ), }; shared_values.firewall.apply_policy(policy) } diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 13a7104aa1..6b762110ae 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -60,6 +60,8 @@ impl ConnectingState { peer_endpoint, pingable_hosts: gateway_list_from_params(params), allow_lan: shared_values.allow_lan, + #[cfg(windows)] + relay_client: TunnelMonitor::get_relay_client(&shared_values.resource_dir, ¶ms), }; shared_values.firewall.apply_policy(policy) } diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 7f867fdcd0..b0222ade67 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -87,7 +87,6 @@ pub fn spawn( state_change_listener: impl Sender<TunnelStateTransition> + Send + 'static, shutdown_tx: oneshot::Sender<()>, #[cfg(target_os = "android")] android_context: AndroidContext, - #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<Arc<mpsc::UnboundedSender<TunnelCommand>>, Error> { let (command_tx, command_rx) = mpsc::unbounded(); let command_tx = Arc::new(command_tx); @@ -120,8 +119,6 @@ pub fn spawn( command_rx, state_change_listener, shutdown_tx, - #[cfg(target_os = "windows")] - approved_applications, ) { Ok((mut reactor, event_loop)) => { startup_result_tx.send(Ok(())).expect( @@ -162,7 +159,6 @@ fn create_event_loop( commands: mpsc::UnboundedReceiver<TunnelCommand>, state_change_listener: impl Sender<TunnelStateTransition>, shutdown_tx: oneshot::Sender<()>, - #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<(Core, impl Future<Item = (), Error = Error>), Error> { let reactor = Core::new().map_err(Error::ReactorError)?; let state_machine = TunnelStateMachine::new( @@ -175,8 +171,6 @@ fn create_event_loop( resource_dir, cache_dir, commands, - #[cfg(windows)] - approved_applications, )?; let future = state_machine @@ -234,21 +228,16 @@ impl TunnelStateMachine { resource_dir: PathBuf, cache_dir: impl AsRef<Path>, commands: mpsc::UnboundedReceiver<TunnelCommand>, - #[cfg(windows)] approved_applications: Vec<PathBuf>, ) -> Result<Self, Error> { let args = if block_when_disconnected { FirewallArguments { initialize_blocked: true, allow_lan: Some(allow_lan), - #[cfg(windows)] - approved_applications, } } else { FirewallArguments { initialize_blocked: false, allow_lan: None, - #[cfg(windows)] - approved_applications, } }; |
