diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-05-11 11:52:28 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-05-11 16:12:44 +0200 |
| commit | 2eb6eb02ea3a00b4b23d4ecacd37bafee9bb6060 (patch) | |
| tree | b81d70494751100cd0dd3b1988a2fb95e0d6976a | |
| parent | 7c66dc69f3d5ca8246d00555a45e8132f0a8a202 (diff) | |
| download | mullvadvpn-2eb6eb02ea3a00b4b23d4ecacd37bafee9bb6060.tar.xz mullvadvpn-2eb6eb02ea3a00b4b23d4ecacd37bafee9bb6060.zip | |
Reapply connecting firewall policy when the tunnel interface has been
created
| -rw-r--r-- | talpid-core/src/firewall/linux.rs | 1 | ||||
| -rw-r--r-- | talpid-core/src/firewall/macos.rs | 1 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 12 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows.rs | 6 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 38 |
7 files changed, 51 insertions, 11 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs index 64ab195afe..a0c767d926 100644 --- a/talpid-core/src/firewall/linux.rs +++ b/talpid-core/src/firewall/linux.rs @@ -577,6 +577,7 @@ impl<'a> PolicyBatch<'a> { let allow_lan = match policy { FirewallPolicy::Connecting { peer_endpoint, + tunnel_interface: _, pingable_hosts, allow_lan, allowed_endpoint, diff --git a/talpid-core/src/firewall/macos.rs b/talpid-core/src/firewall/macos.rs index 2e23c99dd2..ddc6815990 100644 --- a/talpid-core/src/firewall/macos.rs +++ b/talpid-core/src/firewall/macos.rs @@ -97,6 +97,7 @@ impl Firewall { match policy { FirewallPolicy::Connecting { peer_endpoint, + tunnel_interface: _, allow_lan, allowed_endpoint, pingable_hosts, diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 1e782e2e6a..558b2b6040 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -103,6 +103,8 @@ pub enum FirewallPolicy { Connecting { /// The peer endpoint that should be allowed. peer_endpoint: Endpoint, + /// Tunnel interface alias. + tunnel_interface: Option<String>, /// Hosts that should be pingable whilst connecting. pingable_hosts: Vec<IpAddr>, /// Flag setting if communication with LAN networks should be possible. @@ -144,19 +146,25 @@ impl fmt::Display for FirewallPolicy { match self { FirewallPolicy::Connecting { peer_endpoint, + tunnel_interface, pingable_hosts, allow_lan, .. } => write!( f, - "Connecting to {} with gateways {}, {} LAN", + "Connecting to {} with gateways {}, {} LAN, interface: {}", peer_endpoint, pingable_hosts .iter() .map(ToString::to_string) .collect::<Vec<String>>() .join(","), - if *allow_lan { "Allowing" } else { "Blocking" } + if *allow_lan { "Allowing" } else { "Blocking" }, + if let Some(alias) = tunnel_interface { + alias + } else { + "none" + } ), FirewallPolicy::Connected { peer_endpoint, diff --git a/talpid-core/src/firewall/windows.rs b/talpid-core/src/firewall/windows.rs index a7e7f3d918..34e0481610 100644 --- a/talpid-core/src/firewall/windows.rs +++ b/talpid-core/src/firewall/windows.rs @@ -93,17 +93,17 @@ impl FirewallT for Firewall { match policy { FirewallPolicy::Connecting { peer_endpoint, + tunnel_interface, pingable_hosts, allow_lan, allowed_endpoint, relay_client, } => { let cfg = &WinFwSettings::new(allow_lan); - // TODO: Determine interface alias at runtime self.set_connecting_state( &peer_endpoint, &cfg, - "Mullvad".to_string(), + &tunnel_interface, &allowed_endpoint, &pingable_hosts, &relay_client, @@ -154,7 +154,7 @@ impl Firewall { &mut self, endpoint: &Endpoint, winfw_settings: &WinFwSettings, - _tunnel_iface_alias: String, + _tunnel_iface_alias: &Option<String>, allowed_endpoint: &Endpoint, pingable_hosts: &Vec<IpAddr>, relay_client: &Path, diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index 87fc3d4306..063feacc3d 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -70,6 +70,8 @@ pub enum Error { pub enum TunnelEvent { /// Sent when the tunnel fails to connect due to an authentication error. AuthFailed(Option<String>), + /// Sent when the tunnel interface has been created. + InterfaceUp(String), /// Sent when the tunnel comes up and is ready for traffic. Up(TunnelMetadata), /// Sent when the tunnel goes down. diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs index 81089e59e6..c51fdf57f5 100644 --- a/talpid-core/src/tunnel/wireguard/mod.rs +++ b/talpid-core/src/tunnel/wireguard/mod.rs @@ -159,6 +159,8 @@ impl WireguardMonitor { let tunnel = Self::open_tunnel(&config, log_path, tun_provider, route_manager)?; let iface_name = tunnel.get_interface_name().to_string(); + (on_event)(TunnelEvent::InterfaceUp(iface_name.clone())); + #[cfg(target_os = "linux")] route_manager .create_routing_rules(config.enable_ipv6) diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 5257475d63..29c3bb0a90 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -47,6 +47,7 @@ const MIN_TUNNEL_ALIVE_TIME: Duration = Duration::from_millis(1000); pub struct ConnectingState { tunnel_events: TunnelEventsReceiver, tunnel_parameters: TunnelParameters, + tunnel_interface: Option<String>, tunnel_close_event: TunnelCloseEvent, close_handle: Option<CloseHandle>, retry_attempt: u32, @@ -56,6 +57,7 @@ impl ConnectingState { fn set_firewall_policy( shared_values: &mut SharedTunnelStateValues, params: &TunnelParameters, + tunnel_interface: &Option<String>, ) -> Result<(), FirewallPolicyError> { #[cfg(target_os = "linux")] shared_values.disable_connectivity_check(); @@ -64,6 +66,7 @@ impl ConnectingState { let policy = FirewallPolicy::Connecting { peer_endpoint, + tunnel_interface: tunnel_interface.clone(), pingable_hosts: gateway_list_from_params(params), allow_lan: shared_values.allow_lan, allowed_endpoint: shared_values.allowed_endpoint.clone(), @@ -117,6 +120,7 @@ impl ConnectingState { Ok(ConnectingState { tunnel_events: event_rx.fuse(), tunnel_parameters: parameters, + tunnel_interface: None, tunnel_close_event, close_handle, retry_attempt, @@ -224,7 +228,11 @@ impl ConnectingState { if let Err(error_cause) = shared_values.set_allow_lan(allow_lan) { self.disconnect(shared_values, AfterDisconnect::Block(error_cause)) } else { - match Self::set_firewall_policy(shared_values, &self.tunnel_parameters) { + match Self::set_firewall_policy( + shared_values, + &self.tunnel_parameters, + &self.tunnel_interface, + ) { Ok(()) => { cfg_if! { if #[cfg(target_os = "android")] { @@ -243,9 +251,11 @@ impl ConnectingState { } Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { if shared_values.set_allowed_endpoint(endpoint) { - if let Err(error) = - Self::set_firewall_policy(shared_values, &self.tunnel_parameters) - { + if let Err(error) = Self::set_firewall_policy( + shared_values, + &self.tunnel_parameters, + &self.tunnel_interface, + ) { return self.disconnect( shared_values, AfterDisconnect::Block(ErrorStateCause::SetFirewallPolicyError(error)), @@ -298,7 +308,7 @@ impl ConnectingState { } fn handle_tunnel_events( - self, + mut self, event: Option<tunnel::TunnelEvent>, shared_values: &mut SharedTunnelStateValues, ) -> EventConsequence { @@ -309,6 +319,20 @@ impl ConnectingState { shared_values, AfterDisconnect::Block(ErrorStateCause::AuthFailed(reason)), ), + Some(TunnelEvent::InterfaceUp(interface)) => { + self.tunnel_interface = Some(interface); + match Self::set_firewall_policy( + shared_values, + &self.tunnel_parameters, + &self.tunnel_interface, + ) { + Ok(()) => SameState(self.into()), + Err(error) => self.disconnect( + shared_values, + AfterDisconnect::Block(ErrorStateCause::SetFirewallPolicyError(error)), + ), + } + } Some(TunnelEvent::Up(metadata)) => NewState(ConnectedState::enter( shared_values, self.into_connected_state_bootstrap(metadata), @@ -403,7 +427,9 @@ impl TunnelState for ConnectingState { ErrorState::enter(shared_values, ErrorStateCause::TunnelParameterError(err)) } Ok(tunnel_parameters) => { - if let Err(error) = Self::set_firewall_policy(shared_values, &tunnel_parameters) { + if let Err(error) = + Self::set_firewall_policy(shared_values, &tunnel_parameters, &None) + { ErrorState::enter( shared_values, ErrorStateCause::SetFirewallPolicyError(error), |
