diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2018-11-13 06:16:48 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2018-11-13 13:34:09 +0100 |
| commit | f048c66ab3672b32098158f97a56ac6a0717c976 (patch) | |
| tree | a6aee9db2e37a9a723ca1f2140e8bedf96ba0c16 /talpid-core/src | |
| parent | e59ac7a68a5cdda11d82b4a69ad33fddd3b3d294 (diff) | |
| download | mullvadvpn-f048c66ab3672b32098158f97a56ac6a0717c976.tar.xz mullvadvpn-f048c66ab3672b32098158f97a56ac6a0717c976.zip | |
Add block_on_disconnected setting, for never unblocking the firewall
Diffstat (limited to 'talpid-core/src')
6 files changed, 67 insertions, 8 deletions
diff --git a/talpid-core/src/tunnel_state_machine/blocked_state.rs b/talpid-core/src/tunnel_state_machine/blocked_state.rs index 3e63551110..14b72a20f8 100644 --- a/talpid-core/src/tunnel_state_machine/blocked_state.rs +++ b/talpid-core/src/tunnel_state_machine/blocked_state.rs @@ -58,6 +58,10 @@ impl TunnelState for BlockedState { Self::set_security_policy(shared_values); SameState(self) } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + SameState(self) + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; if !is_offline && self.block_reason == BlockReason::IsOffline { diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 577f435260..fa6735f145 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -94,6 +94,10 @@ impl ConnectedState { } } } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + SameState(self) + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; if is_offline { diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index df0a00744e..e4d81dd51e 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -211,6 +211,10 @@ impl ConnectingState { } } } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + SameState(self) + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; if is_offline { diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs index 60444e9cc7..643395931f 100644 --- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs @@ -1,7 +1,8 @@ use super::{ - BlockedState, ConnectingState, Error, EventConsequence, SharedTunnelStateValues, TunnelCommand, - TunnelState, TunnelStateTransition, TunnelStateWrapper, + BlockedState, ConnectingState, EventConsequence, ResultExt, SharedTunnelStateValues, + TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper, }; +use crate::security::SecurityPolicy; use error_chain::ChainedError; use futures::sync::mpsc; use futures::Stream; @@ -10,10 +11,23 @@ use futures::Stream; pub struct DisconnectedState; impl DisconnectedState { - fn reset_security_policy(shared_values: &mut SharedTunnelStateValues) { - if let Err(error) = shared_values.security.reset_policy() { - let chained_error = Error::with_chain(error, "Failed to reset security policy"); - log::error!("{}", chained_error.display_chain()); + fn set_security_policy(shared_values: &mut SharedTunnelStateValues) { + let result = if shared_values.block_when_disconnected { + let policy = SecurityPolicy::Blocked { + allow_lan: shared_values.allow_lan, + }; + shared_values + .security + .apply_policy(policy) + .chain_err(|| "Failed to apply blocking security policy for disconnected state") + } else { + shared_values + .security + .reset_policy() + .chain_err(|| "Failed to reset security policy") + }; + if let Err(error) = result { + log::error!("{}", error.display_chain()); } } } @@ -25,8 +39,7 @@ impl TunnelState for DisconnectedState { shared_values: &mut SharedTunnelStateValues, _: Self::Bootstrap, ) -> (TunnelStateWrapper, TunnelStateTransition) { - Self::reset_security_policy(shared_values); - + Self::set_security_policy(shared_values); ( TunnelStateWrapper::from(DisconnectedState), TunnelStateTransition::Disconnected, @@ -42,7 +55,19 @@ impl TunnelState for DisconnectedState { match try_handle_event!(self, commands.poll()) { Ok(TunnelCommand::AllowLan(allow_lan)) => { + let changed = shared_values.allow_lan != allow_lan; shared_values.allow_lan = allow_lan; + if changed { + Self::set_security_policy(shared_values); + } + SameState(self) + } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + let changed = shared_values.block_when_disconnected != block_when_disconnected; + shared_values.block_when_disconnected = block_when_disconnected; + if changed { + Self::set_security_policy(shared_values); + } SameState(self) } Ok(TunnelCommand::IsOffline(is_offline)) => { diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs index 7ebb637d2d..928880f274 100644 --- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs @@ -33,6 +33,10 @@ impl DisconnectingState { shared_values.allow_lan = allow_lan; AfterDisconnect::Nothing } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + AfterDisconnect::Nothing + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; AfterDisconnect::Nothing @@ -46,6 +50,10 @@ impl DisconnectingState { shared_values.allow_lan = allow_lan; AfterDisconnect::Block(reason) } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + AfterDisconnect::Block(reason) + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; if !is_offline && reason == BlockReason::IsOffline { @@ -64,6 +72,10 @@ impl DisconnectingState { shared_values.allow_lan = allow_lan; AfterDisconnect::Reconnect(retry_attempt) } + Ok(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => { + shared_values.block_when_disconnected = block_when_disconnected; + AfterDisconnect::Reconnect(retry_attempt) + } Ok(TunnelCommand::IsOffline(is_offline)) => { shared_values.is_offline = is_offline; if is_offline { diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index e44ec91234..d952e458f2 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -43,6 +43,7 @@ error_chain! { /// Spawn the tunnel state machine thread, returning a channel for sending tunnel commands. pub fn spawn<P, T>( allow_lan: bool, + block_when_disconnected: bool, tunnel_parameters_generator: impl TunnelParametersGenerator, log_dir: Option<PathBuf>, resource_dir: PathBuf, @@ -62,6 +63,7 @@ where thread::spawn(move || { match create_event_loop( allow_lan, + block_when_disconnected, is_offline, tunnel_parameters_generator, log_dir, @@ -97,6 +99,7 @@ where fn create_event_loop<T>( allow_lan: bool, + block_when_disconnected: bool, is_offline: bool, tunnel_parameters_generator: impl TunnelParametersGenerator, log_dir: Option<PathBuf>, @@ -111,6 +114,7 @@ where let reactor = Core::new().chain_err(|| ErrorKind::ReactorError)?; let state_machine = TunnelStateMachine::new( allow_lan, + block_when_disconnected, is_offline, tunnel_parameters_generator, log_dir, @@ -132,6 +136,8 @@ where pub enum TunnelCommand { /// Enable or disable LAN access in the firewall. AllowLan(bool), + /// Enable or disable the block_when_disconnected feature. + BlockWhenDisconnected(bool), /// Notify the state machine of the connectivity of the device. IsOffline(bool), /// Open tunnel connection. @@ -168,6 +174,7 @@ struct TunnelStateMachine { impl TunnelStateMachine { fn new( allow_lan: bool, + block_when_disconnected: bool, is_offline: bool, tunnel_parameters_generator: impl TunnelParametersGenerator, log_dir: Option<PathBuf>, @@ -180,6 +187,7 @@ impl TunnelStateMachine { let mut shared_values = SharedTunnelStateValues { security, allow_lan, + block_when_disconnected, is_offline, tunnel_parameters_generator: Box::new(tunnel_parameters_generator), log_dir, @@ -258,6 +266,8 @@ struct SharedTunnelStateValues { security: NetworkSecurity, /// Should LAN access be allowed outside the tunnel. allow_lan: bool, + /// Should network access be allowed when in the disconnected state. + block_when_disconnected: bool, /// True when the computer is known to be offline. is_offline: bool, /// The generator of new `TunnelParameter`s |
