summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-09-05 15:50:53 +0200
committerLinus Färnstrand <linus@mullvad.net>2018-09-05 15:50:53 +0200
commitfb40dedf46348e8764aed95610b135e40c3b1ba1 (patch)
tree9efdcfe4e6d1c0d01417f5b9f8fdeb0f10637312
parente1e8b371ab146916ee5074102800c197f2232302 (diff)
parent1b44398fb05dc69e24f3a389e43f926f7512e6c8 (diff)
downloadmullvadvpn-fb40dedf46348e8764aed95610b135e40c3b1ba1.tar.xz
mullvadvpn-fb40dedf46348e8764aed95610b135e40c3b1ba1.zip
Merge branch 'blocked-state-block-network'
-rw-r--r--mullvad-daemon/src/main.rs5
-rw-r--r--talpid-core/src/security/linux/mod.rs22
-rw-r--r--talpid-core/src/security/macos/mod.rs7
-rw-r--r--talpid-core/src/security/mod.rs6
-rw-r--r--talpid-core/src/security/windows/mod.rs44
-rw-r--r--talpid-core/src/tunnel_state_machine/blocked_state.rs36
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs14
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs16
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs4
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs18
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs2
11 files changed, 121 insertions, 53 deletions
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index 2fb27c3048..b67658c2ab 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -604,8 +604,9 @@ impl Daemon {
}
fn connect_tunnel(&mut self) {
+ let allow_lan = self.settings.get_allow_lan();
let command = match self.settings.get_account_token() {
- None => TunnelCommand::Block(BlockReason::NoAccountToken),
+ None => TunnelCommand::Block(BlockReason::NoAccountToken, allow_lan),
Some(account_token) => match self.settings.get_relay_settings() {
RelaySettings::CustomTunnelEndpoint(custom_relay) => custom_relay
.to_tunnel_endpoint()
@@ -622,7 +623,7 @@ impl Daemon {
.map(|parameters| TunnelCommand::Connect(parameters))
.unwrap_or_else(|error| {
error!("{}", error.display_chain());
- TunnelCommand::Block(BlockReason::NoMatchingRelay)
+ TunnelCommand::Block(BlockReason::NoMatchingRelay, allow_lan)
}),
};
self.send_tunnel_command(command);
diff --git a/talpid-core/src/security/linux/mod.rs b/talpid-core/src/security/linux/mod.rs
index e904f03966..de29219298 100644
--- a/talpid-core/src/security/linux/mod.rs
+++ b/talpid-core/src/security/linux/mod.rs
@@ -220,24 +220,28 @@ impl<'a> PolicyBatch<'a> {
}
fn add_policy_specific_rules(&mut self, policy: &SecurityPolicy) -> Result<()> {
- let (relay_endpoint, allow_lan, tunnel) = match policy {
+ let allow_lan = match policy {
SecurityPolicy::Connecting {
relay_endpoint,
allow_lan,
- } => (relay_endpoint, *allow_lan, None),
+ } => {
+ self.add_allow_endpoint_rules(relay_endpoint)?;
+ *allow_lan
+ }
SecurityPolicy::Connected {
relay_endpoint,
tunnel,
allow_lan,
- } => (relay_endpoint, *allow_lan, Some(tunnel)),
+ } => {
+ self.add_allow_endpoint_rules(relay_endpoint)?;
+ self.add_dns_rule(tunnel, TransportProtocol::Udp)?;
+ self.add_dns_rule(tunnel, TransportProtocol::Tcp)?;
+ self.add_allow_tunnel_rules(tunnel)?;
+ *allow_lan
+ }
+ SecurityPolicy::Blocked { allow_lan } => *allow_lan,
};
- self.add_allow_endpoint_rules(relay_endpoint)?;
- if let Some(tunnel) = tunnel {
- self.add_dns_rule(tunnel, TransportProtocol::Udp)?;
- self.add_dns_rule(tunnel, TransportProtocol::Tcp)?;
- self.add_allow_tunnel_rules(tunnel)?;
- }
if allow_lan {
self.add_allow_lan_rules()?;
}
diff --git a/talpid-core/src/security/macos/mod.rs b/talpid-core/src/security/macos/mod.rs
index b7477f81e8..331f2f29ec 100644
--- a/talpid-core/src/security/macos/mod.rs
+++ b/talpid-core/src/security/macos/mod.rs
@@ -147,6 +147,13 @@ impl MacosNetworkSecurity {
}
Ok(rules)
}
+ SecurityPolicy::Blocked { allow_lan } => {
+ let mut rules = Vec::new();
+ if allow_lan {
+ rules.append(&mut Self::get_allow_lan_rules()?);
+ }
+ Ok(rules)
+ }
}
}
diff --git a/talpid-core/src/security/mod.rs b/talpid-core/src/security/mod.rs
index a37bb23253..5dcbc87dd3 100644
--- a/talpid-core/src/security/mod.rs
+++ b/talpid-core/src/security/mod.rs
@@ -36,6 +36,12 @@ pub enum SecurityPolicy {
/// Flag setting if communication with LAN networks should be possible.
allow_lan: bool,
},
+
+ /// Block all network traffic in and out from the computer.
+ Blocked {
+ /// Flag setting if communication with LAN networks should be possible.
+ allow_lan: bool,
+ },
}
/// Abstract firewall interaction trait
diff --git a/talpid-core/src/security/windows/mod.rs b/talpid-core/src/security/windows/mod.rs
index 6789674971..16fd707030 100644
--- a/talpid-core/src/security/windows/mod.rs
+++ b/talpid-core/src/security/windows/mod.rs
@@ -19,30 +19,35 @@ mod system_state;
use self::dns::WinDns;
-error_chain!{
- errors{
+error_chain! {
+ errors {
/// Failure to initialize windows firewall module
- Initialization{
+ Initialization {
description("Failed to initialise windows firewall module")
}
/// Failure to deinitialize windows firewall module
- Deinitialization{
+ Deinitialization {
description("Failed to deinitialize windows firewall module")
}
- /// Failure to apply a firewall _connected_ policy
- ApplyingConnectedPolicy{
+ /// Failure to apply a firewall _connecting_ policy
+ ApplyingConnectingPolicy {
description("Failed to apply firewall policy for when the daemon is connecting to a tunnel")
}
- /// Failure to apply a firewall _connecting_ policy
- ApplyingConnectingPolicy{
+ /// Failure to apply a firewall _connected_ policy
+ ApplyingConnectedPolicy {
description("Failed to apply firewall policy for when the daemon is connected to a tunnel")
}
+ /// Failure to apply firewall _blocked_ policy
+ ApplyingBlockedPolicy {
+ description("Failed to apply blocked security policy")
+ }
+
/// Failure to reset firewall policies
- ResettingPolicy{
+ ResettingPolicy {
description("Failed to reset firewall policies")
}
}
@@ -93,6 +98,10 @@ impl NetworkSecurity for WindowsNetworkSecurity {
let cfg = &WinFwSettings::new(allow_lan);
self.set_connected_state(&relay_endpoint, &cfg, &tunnel)
}
+ SecurityPolicy::Blocked { allow_lan } => {
+ let cfg = &WinFwSettings::new(allow_lan);
+ self.set_blocked_state(&cfg)
+ }
}
}
@@ -177,6 +186,11 @@ impl WindowsNetworkSecurity {
).into_result()
}
}
+
+ fn set_blocked_state(&mut self, winfw_settings: &WinFwSettings) -> Result<()> {
+ trace!("Applying 'blocked' firewall policy");
+ unsafe { WinFw_ApplyPolicyBlocked(winfw_settings).into_result() }
+ }
}
@@ -227,13 +241,14 @@ mod winfw {
ffi_error!(InitializationResult, ErrorKind::Initialization.into());
ffi_error!(DeinitializationResult, ErrorKind::Deinitialization.into());
ffi_error!(
- ApplyConnectedResult,
- ErrorKind::ApplyingConnectedPolicy.into()
- );
- ffi_error!(
ApplyConnectingResult,
ErrorKind::ApplyingConnectingPolicy.into()
);
+ ffi_error!(
+ ApplyConnectedResult,
+ ErrorKind::ApplyingConnectedPolicy.into()
+ );
+ ffi_error!(ApplyBlockedResult, ErrorKind::ApplyingBlockedPolicy.into());
ffi_error!(ResettingPolicyResult, ErrorKind::ResettingPolicy.into());
extern "system" {
@@ -261,6 +276,9 @@ mod winfw {
primaryDns: *const libc::wchar_t,
) -> ApplyConnectedResult;
+ #[link_name(WinFw_ApplyPolicyBlocked)]
+ pub fn WinFw_ApplyPolicyBlocked(settings: &WinFwSettings) -> ApplyBlockedResult;
+
#[link_name(WinFw_Reset)]
pub fn WinFw_Reset() -> ResettingPolicyResult;
}
diff --git a/talpid-core/src/tunnel_state_machine/blocked_state.rs b/talpid-core/src/tunnel_state_machine/blocked_state.rs
index 50efb9e371..57203db275 100644
--- a/talpid-core/src/tunnel_state_machine/blocked_state.rs
+++ b/talpid-core/src/tunnel_state_machine/blocked_state.rs
@@ -1,23 +1,40 @@
+use error_chain::ChainedError;
use futures::sync::mpsc;
use futures::Stream;
use talpid_types::tunnel::BlockReason;
use super::{
- ConnectingState, DisconnectedState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
- TunnelState, TunnelStateTransition, TunnelStateWrapper,
+ ConnectingState, DisconnectedState, EventConsequence, ResultExt, SharedTunnelStateValues,
+ TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
+use security::{NetworkSecurity, SecurityPolicy};
/// No tunnel is running and all network connections are blocked.
pub struct BlockedState;
+impl BlockedState {
+ fn set_security_policy(shared_values: &mut SharedTunnelStateValues, allow_lan: bool) {
+ let policy = SecurityPolicy::Blocked { allow_lan };
+ debug!("Setting security policy: {:?}", policy);
+ if let Err(error) = shared_values
+ .security
+ .apply_policy(policy)
+ .chain_err(|| "Failed to apply security policy for blocked state")
+ {
+ error!("{}", error.display_chain());
+ }
+ }
+}
+
impl TunnelState for BlockedState {
- type Bootstrap = BlockReason;
+ type Bootstrap = (BlockReason, bool);
fn enter(
- _: &mut SharedTunnelStateValues,
- block_reason: Self::Bootstrap,
+ shared_values: &mut SharedTunnelStateValues,
+ (block_reason, allow_lan): Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ Self::set_security_policy(shared_values, allow_lan);
(
TunnelStateWrapper::from(BlockedState),
TunnelStateTransition::Blocked(block_reason),
@@ -32,16 +49,19 @@ impl TunnelState for BlockedState {
use self::EventConsequence::*;
match try_handle_event!(self, commands.poll()) {
+ Ok(TunnelCommand::AllowLan(allow_lan)) => {
+ Self::set_security_policy(shared_values, allow_lan);
+ SameState(self)
+ }
Ok(TunnelCommand::Connect(parameters)) => {
NewState(ConnectingState::enter(shared_values, parameters))
}
Ok(TunnelCommand::Disconnect) | Err(_) => {
NewState(DisconnectedState::enter(shared_values, ()))
}
- Ok(TunnelCommand::Block(reason)) => {
- NewState(BlockedState::enter(shared_values, reason))
+ Ok(TunnelCommand::Block(reason, allow_lan)) => {
+ NewState(BlockedState::enter(shared_values, (reason, allow_lan)))
}
- _ => SameState(self),
}
}
}
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index 0117958503..b9856dbedc 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -79,7 +79,10 @@ impl ConnectedState {
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetSecurityPolicyError),
+ AfterDisconnect::Block(
+ BlockReason::SetSecurityPolicyError,
+ allow_lan,
+ ),
),
))
}
@@ -107,12 +110,12 @@ impl ConnectedState {
AfterDisconnect::Nothing,
),
)),
- Ok(TunnelCommand::Block(reason)) => NewState(DisconnectingState::enter(
+ Ok(TunnelCommand::Block(reason, allow_lan)) => NewState(DisconnectingState::enter(
shared_values,
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(reason),
+ AfterDisconnect::Block(reason, allow_lan),
),
)),
}
@@ -179,7 +182,10 @@ impl TunnelState for ConnectedState {
(
connected_state.close_handle,
connected_state.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetSecurityPolicyError),
+ AfterDisconnect::Block(
+ BlockReason::SetSecurityPolicyError,
+ connected_state.tunnel_parameters.allow_lan,
+ ),
),
)
}
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 184832acaa..8b2867b4fb 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -187,7 +187,10 @@ impl ConnectingState {
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetSecurityPolicyError),
+ AfterDisconnect::Block(
+ BlockReason::SetSecurityPolicyError,
+ allow_lan,
+ ),
),
))
}
@@ -215,12 +218,12 @@ impl ConnectingState {
AfterDisconnect::Nothing,
),
)),
- Ok(TunnelCommand::Block(reason)) => NewState(DisconnectingState::enter(
+ Ok(TunnelCommand::Block(reason, allow_lan)) => NewState(DisconnectingState::enter(
shared_values,
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(reason),
+ AfterDisconnect::Block(reason, allow_lan),
),
)),
}
@@ -276,12 +279,12 @@ impl TunnelState for ConnectingState {
shared_values: &mut SharedTunnelStateValues,
parameters: Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ let allow_lan = parameters.allow_lan;
if let Err(error) =
Self::set_security_policy(shared_values, parameters.endpoint, parameters.allow_lan)
{
error!("{}", error.display_chain());
-
- return BlockedState::enter(shared_values, BlockReason::StartTunnelError);
+ return BlockedState::enter(shared_values, (BlockReason::StartTunnelError, allow_lan));
}
match Self::new(parameters) {
@@ -292,8 +295,7 @@ impl TunnelState for ConnectingState {
Err(error) => {
let chained_error = error.chain_err(|| "Failed to start tunnel");
error!("{}", chained_error.display_chain());
-
- BlockedState::enter(shared_values, BlockReason::StartTunnelError)
+ BlockedState::enter(shared_values, (BlockReason::StartTunnelError, allow_lan))
}
}
}
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 80a7eb5ce0..1a22043f0a 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -47,8 +47,8 @@ impl TunnelState for DisconnectedState {
Ok(TunnelCommand::Connect(parameters)) => {
NewState(ConnectingState::enter(shared_values, parameters))
}
- Ok(TunnelCommand::Block(reason)) => {
- NewState(BlockedState::enter(shared_values, reason))
+ Ok(TunnelCommand::Block(reason, allow_lan)) => {
+ NewState(BlockedState::enter(shared_values, (reason, allow_lan)))
}
Ok(_) => SameState(self),
Err(_) => Finished,
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index 452b8d3ac1..a7f20ca5ea 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -33,14 +33,16 @@ impl DisconnectingState {
self.after_disconnect = match after_disconnect {
AfterDisconnect::Nothing => match event {
Ok(TunnelCommand::Connect(parameters)) => Reconnect(parameters),
- Ok(TunnelCommand::Block(reason)) => Block(reason),
+ Ok(TunnelCommand::Block(reason, allow_lan)) => Block(reason, allow_lan),
_ => Nothing,
},
- AfterDisconnect::Block(reason) => match event {
+ AfterDisconnect::Block(reason, allow_lan) => match event {
Ok(TunnelCommand::Connect(parameters)) => Reconnect(parameters),
Ok(TunnelCommand::Disconnect) => Nothing,
- Ok(TunnelCommand::Block(new_reason)) => Block(new_reason),
- _ => AfterDisconnect::Block(reason),
+ Ok(TunnelCommand::Block(new_reason, new_allow_lan)) => {
+ Block(new_reason, new_allow_lan)
+ }
+ _ => Block(reason, allow_lan),
},
AfterDisconnect::Reconnect(mut tunnel_parameters) => match event {
Ok(TunnelCommand::AllowLan(allow_lan)) => {
@@ -49,7 +51,7 @@ impl DisconnectingState {
}
Ok(TunnelCommand::Connect(parameters)) => Reconnect(parameters),
Ok(TunnelCommand::Disconnect) | Err(_) => Nothing,
- Ok(TunnelCommand::Block(reason)) => Block(reason),
+ Ok(TunnelCommand::Block(reason, allow_lan)) => Block(reason, allow_lan),
},
};
@@ -74,7 +76,9 @@ impl DisconnectingState {
) -> (TunnelStateWrapper, TunnelStateTransition) {
match self.after_disconnect {
AfterDisconnect::Nothing => DisconnectedState::enter(shared_values, ()),
- AfterDisconnect::Block(reason) => BlockedState::enter(shared_values, reason),
+ AfterDisconnect::Block(reason, allow_lan) => {
+ BlockedState::enter(shared_values, (reason, allow_lan))
+ }
AfterDisconnect::Reconnect(tunnel_parameters) => {
ConnectingState::enter(shared_values, tunnel_parameters)
}
@@ -121,6 +125,6 @@ impl TunnelState for DisconnectingState {
/// Which state should be transitioned to after disconnection is complete.
pub enum AfterDisconnect {
Nothing,
- Block(BlockReason),
+ Block(BlockReason, bool),
Reconnect(TunnelParameters),
}
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 433333efa0..aed46f3ab5 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -111,7 +111,7 @@ pub enum TunnelCommand {
/// Close tunnel connection.
Disconnect,
/// Disconnect any open tunnel and block all network access
- Block(BlockReason),
+ Block(BlockReason, bool),
}
/// Information necessary to open a tunnel.