summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-09-06 13:43:43 +0200
committerLinus Färnstrand <linus@mullvad.net>2018-09-06 13:43:43 +0200
commitcd6631606dd3f7264f7cbc57c29350a07440aacb (patch)
treed9e20cb8fd778847a6a129989aa16217336d78d1
parent45dd1085b79d1ced73c3202de4f2fe7b58fb4f41 (diff)
parent44aabbfa79175df1ea4230276e83162b6b73cd9c (diff)
downloadmullvadvpn-cd6631606dd3f7264f7cbc57c29350a07440aacb.tar.xz
mullvadvpn-cd6631606dd3f7264f7cbc57c29350a07440aacb.zip
Merge branch 'move-firewall-logging'
-rw-r--r--talpid-core/src/security/linux/mod.rs12
-rw-r--r--talpid-core/src/security/macos/mod.rs10
-rw-r--r--talpid-core/src/security/mod.rs101
-rw-r--r--talpid-core/src/security/windows/mod.rs15
-rw-r--r--talpid-core/src/tunnel_state_machine/blocked_state.rs3
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs4
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs4
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs2
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs6
-rw-r--r--talpid-types/src/net.rs6
10 files changed, 113 insertions, 50 deletions
diff --git a/talpid-core/src/security/linux/mod.rs b/talpid-core/src/security/linux/mod.rs
index de29219298..455e4cc755 100644
--- a/talpid-core/src/security/linux/mod.rs
+++ b/talpid-core/src/security/linux/mod.rs
@@ -18,7 +18,7 @@ use std::io;
use std::net::{IpAddr, Ipv4Addr};
use std::path::Path;
-use super::{NetworkSecurity, SecurityPolicy};
+use super::{NetworkSecurityT, SecurityPolicy};
mod dns;
use self::dns::DnsSettings;
@@ -71,17 +71,17 @@ enum End {
Dst,
}
-/// The Linux implementation for the `NetworkSecurity` trait.
-pub struct LinuxNetworkSecurity {
+/// The Linux implementation for the firewall and DNS.
+pub struct NetworkSecurity {
dns_settings: DnsSettings,
table_name: CString,
}
-impl NetworkSecurity for LinuxNetworkSecurity {
+impl NetworkSecurityT for NetworkSecurity {
type Error = Error;
fn new(_cache_dir: impl AsRef<Path>) -> Result<Self> {
- Ok(LinuxNetworkSecurity {
+ Ok(NetworkSecurity {
dns_settings: DnsSettings::new()?,
table_name: TABLE_NAME.clone(),
})
@@ -117,7 +117,7 @@ impl NetworkSecurity for LinuxNetworkSecurity {
}
}
-impl LinuxNetworkSecurity {
+impl NetworkSecurity {
fn send_and_process(&self, batch: &FinalizedBatch) -> Result<()> {
let socket =
mnl::Socket::new(mnl::Bus::Netfilter).chain_err(|| ErrorKind::NetlinkOpenError)?;
diff --git a/talpid-core/src/security/macos/mod.rs b/talpid-core/src/security/macos/mod.rs
index 331f2f29ec..abcfd8e404 100644
--- a/talpid-core/src/security/macos/mod.rs
+++ b/talpid-core/src/security/macos/mod.rs
@@ -1,7 +1,7 @@
extern crate pfctl;
extern crate tokio_core;
-use super::{NetworkSecurity, SecurityPolicy};
+use super::{NetworkSecurityT, SecurityPolicy};
use ipnetwork::IpNetwork;
@@ -26,17 +26,17 @@ error_chain! {
const ANCHOR_NAME: &'static str = "mullvad";
/// The macOS firewall and DNS implementation.
-pub struct MacosNetworkSecurity {
+pub struct NetworkSecurity {
pf: pfctl::PfCtl,
pf_was_enabled: Option<bool>,
dns_monitor: DnsMonitor,
}
-impl NetworkSecurity for MacosNetworkSecurity {
+impl NetworkSecurityT for NetworkSecurity {
type Error = Error;
fn new(_cache_dir: impl AsRef<Path>) -> Result<Self> {
- Ok(MacosNetworkSecurity {
+ Ok(NetworkSecurity {
pf: pfctl::PfCtl::new()?,
pf_was_enabled: None,
dns_monitor: DnsMonitor::new()?,
@@ -61,7 +61,7 @@ impl NetworkSecurity for MacosNetworkSecurity {
}
}
-impl MacosNetworkSecurity {
+impl NetworkSecurity {
fn set_rules(&mut self, policy: SecurityPolicy) -> Result<()> {
let mut new_filter_rules = vec![];
diff --git a/talpid-core/src/security/mod.rs b/talpid-core/src/security/mod.rs
index 5dcbc87dd3..9e5fadeab9 100644
--- a/talpid-core/src/security/mod.rs
+++ b/talpid-core/src/security/mod.rs
@@ -1,10 +1,27 @@
#[cfg(unix)]
use ipnetwork::Ipv4Network;
+use std::fmt;
#[cfg(unix)]
use std::net::Ipv4Addr;
use std::path::Path;
use talpid_types::net::Endpoint;
+
+#[cfg(target_os = "macos")]
+#[path = "macos/mod.rs"]
+mod imp;
+
+#[cfg(target_os = "linux")]
+#[path = "linux/mod.rs"]
+mod imp;
+
+#[cfg(windows)]
+#[path = "windows/mod.rs"]
+mod imp;
+
+pub use self::imp::{Error, ErrorKind};
+
+
#[cfg(unix)]
lazy_static! {
static ref PRIVATE_NETS: [Ipv4Network; 3] = [
@@ -44,8 +61,72 @@ pub enum SecurityPolicy {
},
}
-/// Abstract firewall interaction trait
-pub trait NetworkSecurity: Sized {
+impl fmt::Display for SecurityPolicy {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ match self {
+ SecurityPolicy::Connecting {
+ relay_endpoint,
+ allow_lan,
+ } => write!(
+ f,
+ "Connecting to {}, {} LAN",
+ relay_endpoint,
+ if *allow_lan { "Allowing" } else { "Blocking" }
+ ),
+ SecurityPolicy::Connected {
+ relay_endpoint,
+ tunnel,
+ allow_lan,
+ } => write!(
+ f,
+ "Connected to {} over \"{}\" (ip: {}, gw: {}), {} LAN",
+ relay_endpoint,
+ tunnel.interface,
+ tunnel.ip,
+ tunnel.gateway,
+ if *allow_lan { "Allowing" } else { "Blocking" }
+ ),
+ SecurityPolicy::Blocked { allow_lan } => write!(
+ f,
+ "Blocked, {} LAN",
+ if *allow_lan { "Allowing" } else { "Blocking" }
+ ),
+ }
+ }
+}
+
+/// Manages network security of the computer/device. Can apply and enforce security policies
+/// by manipulating the OS firewall and DNS settings.
+pub struct NetworkSecurity {
+ inner: imp::NetworkSecurity,
+}
+
+impl NetworkSecurity {
+ /// Returns a new `NetworkSecurity`, ready to apply policies.
+ pub fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Error> {
+ Ok(NetworkSecurity {
+ inner: imp::NetworkSecurity::new(cache_dir)?,
+ })
+ }
+
+ /// Applies and starts enforcing the given `SecurityPolicy` Makes sure it is being kept in place
+ /// until this method is called again with another policy, or until `reset_policy` is called.
+ pub fn apply_policy(&mut self, policy: SecurityPolicy) -> Result<(), Error> {
+ info!("Applying security policy: {}", policy);
+ self.inner.apply_policy(policy)
+ }
+
+ /// Resets/removes any currently enforced `SecurityPolicy`. Returns the system to the same state
+ /// it had before any policy was applied through this `NetworkSecurity` instance.
+ pub fn reset_policy(&mut self) -> Result<(), Error> {
+ info!("Resetting security policy");
+ self.inner.reset_policy()
+ }
+}
+
+
+/// Abstract firewall interaction trait. Used by the OS specific implementations.
+trait NetworkSecurityT: Sized {
/// The error type thrown by the implementer of this trait
type Error: ::std::error::Error;
@@ -59,19 +140,3 @@ pub trait NetworkSecurity: Sized {
/// modifying the system.
fn reset_policy(&mut self) -> ::std::result::Result<(), Self::Error>;
}
-
-
-#[cfg(target_os = "macos")]
-mod macos;
-#[cfg(target_os = "macos")]
-pub use self::macos::{Error, ErrorKind, MacosNetworkSecurity as NetworkSecurityImpl, Result};
-
-#[cfg(target_os = "linux")]
-mod linux;
-#[cfg(target_os = "linux")]
-pub use self::linux::{Error, ErrorKind, LinuxNetworkSecurity as NetworkSecurityImpl, Result};
-
-#[cfg(windows)]
-mod windows;
-#[cfg(windows)]
-pub use self::windows::{Error, ErrorKind, Result, WindowsNetworkSecurity as NetworkSecurityImpl};
diff --git a/talpid-core/src/security/windows/mod.rs b/talpid-core/src/security/windows/mod.rs
index 16fd707030..e762a4887a 100644
--- a/talpid-core/src/security/windows/mod.rs
+++ b/talpid-core/src/security/windows/mod.rs
@@ -1,6 +1,6 @@
extern crate widestring;
-use super::{NetworkSecurity, SecurityPolicy};
+use super::{NetworkSecurityT, SecurityPolicy};
use std::net::IpAddr;
use std::path::Path;
use std::ptr;
@@ -60,12 +60,12 @@ error_chain! {
const WINFW_TIMEOUT_SECONDS: u32 = 2;
-/// The Windows implementation for the `NetworkSecurity` trait.
-pub struct WindowsNetworkSecurity {
+/// The Windows implementation for the firewall and DNS.
+pub struct NetworkSecurity {
dns: WinDns,
}
-impl NetworkSecurity for WindowsNetworkSecurity {
+impl NetworkSecurityT for NetworkSecurity {
type Error = Error;
fn new(cache_dir: impl AsRef<Path>) -> Result<Self> {
@@ -78,7 +78,7 @@ impl NetworkSecurity for WindowsNetworkSecurity {
).into_result()?
};
trace!("Successfully initialized windows firewall module");
- Ok(WindowsNetworkSecurity { dns: windns })
+ Ok(NetworkSecurity { dns: windns })
}
fn apply_policy(&mut self, policy: SecurityPolicy) -> Result<()> {
@@ -106,14 +106,13 @@ impl NetworkSecurity for WindowsNetworkSecurity {
}
fn reset_policy(&mut self) -> Result<()> {
- trace!("Resetting firewall policy");
self.dns.reset_dns()?;
unsafe { WinFw_Reset().into_result() }?;
Ok(())
}
}
-impl Drop for WindowsNetworkSecurity {
+impl Drop for NetworkSecurity {
fn drop(&mut self) {
if unsafe { WinFw_Deinitialize().into_result().is_ok() } {
trace!("Successfully deinitialized windows firewall module");
@@ -123,7 +122,7 @@ impl Drop for WindowsNetworkSecurity {
}
}
-impl WindowsNetworkSecurity {
+impl NetworkSecurity {
fn set_connecting_state(
&mut self,
endpoint: &Endpoint,
diff --git a/talpid-core/src/tunnel_state_machine/blocked_state.rs b/talpid-core/src/tunnel_state_machine/blocked_state.rs
index 57203db275..6c50e2b9f7 100644
--- a/talpid-core/src/tunnel_state_machine/blocked_state.rs
+++ b/talpid-core/src/tunnel_state_machine/blocked_state.rs
@@ -8,7 +8,7 @@ use super::{
ConnectingState, DisconnectedState, EventConsequence, ResultExt, SharedTunnelStateValues,
TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
-use security::{NetworkSecurity, SecurityPolicy};
+use security::SecurityPolicy;
/// No tunnel is running and all network connections are blocked.
pub struct BlockedState;
@@ -16,7 +16,6 @@ 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)
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index b9856dbedc..224fce3e91 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -10,7 +10,7 @@ use super::{
SharedTunnelStateValues, TunnelCommand, TunnelParameters, TunnelState, TunnelStateTransition,
TunnelStateWrapper,
};
-use security::{NetworkSecurity, SecurityPolicy};
+use security::SecurityPolicy;
use tunnel::{CloseHandle, TunnelEvent, TunnelMetadata};
pub struct ConnectedStateBootstrap {
@@ -50,8 +50,6 @@ impl ConnectedState {
tunnel: self.metadata.clone(),
allow_lan: self.tunnel_parameters.allow_lan,
};
-
- debug!("Setting security policy: {:?}", policy);
shared_values
.security
.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 8b2867b4fb..80fd94f364 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -18,7 +18,7 @@ use super::{
TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
use logging;
-use security::{NetworkSecurity, SecurityPolicy};
+use security::SecurityPolicy;
use tunnel::{CloseHandle, TunnelEvent, TunnelMetadata, TunnelMonitor};
const MIN_TUNNEL_ALIVE_TIME: Duration = Duration::from_millis(1000);
@@ -63,8 +63,6 @@ impl ConnectingState {
relay_endpoint: endpoint.to_endpoint(),
allow_lan,
};
-
- debug!("Setting security policy: {:?}", policy);
shared_values
.security
.apply_policy(policy)
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 1a22043f0a..d65f8f63de 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -6,14 +6,12 @@ use super::{
BlockedState, ConnectingState, Error, EventConsequence, SharedTunnelStateValues, TunnelCommand,
TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
-use security::NetworkSecurity;
/// No tunnel is running.
pub struct DisconnectedState;
impl DisconnectedState {
fn reset_security_policy(shared_values: &mut SharedTunnelStateValues) {
- debug!("Resetting security policy");
if let Err(error) = shared_values.security.reset_policy() {
let chained_error = Error::with_chain(error, "Failed to reset security policy");
error!("{}", chained_error.display_chain());
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index aed46f3ab5..f1ab145137 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -26,7 +26,7 @@ use self::connecting_state::ConnectingState;
use self::disconnected_state::DisconnectedState;
use self::disconnecting_state::{AfterDisconnect, DisconnectingState};
use super::mpsc::IntoSender;
-use super::security::{NetworkSecurity, NetworkSecurityImpl};
+use super::security::NetworkSecurity;
error_chain! {
errors {
@@ -149,7 +149,7 @@ impl TunnelStateMachine {
commands: mpsc::UnboundedReceiver<TunnelCommand>,
) -> Result<Self> {
let security =
- NetworkSecurityImpl::new(cache_dir).chain_err(|| ErrorKind::NetworkSecurityError)?;
+ NetworkSecurity::new(cache_dir).chain_err(|| ErrorKind::NetworkSecurityError)?;
let mut shared_values = SharedTunnelStateValues { security };
let initial_state = TunnelStateWrapper::new(&mut shared_values, ());
@@ -214,7 +214,7 @@ impl<T: TunnelState> From<EventConsequence<T>> for TunnelStateMachineAction {
/// Values that are common to all tunnel states.
struct SharedTunnelStateValues {
- security: NetworkSecurityImpl,
+ security: NetworkSecurity,
}
/// Asynchronous result of an attempt to progress a state.
diff --git a/talpid-types/src/net.rs b/talpid-types/src/net.rs
index 554b1e5917..65c43e4ae4 100644
--- a/talpid-types/src/net.rs
+++ b/talpid-types/src/net.rs
@@ -80,6 +80,12 @@ impl Endpoint {
}
}
+impl fmt::Display for Endpoint {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(f, "{}:{}", self.address, self.protocol)
+ }
+}
+
/// Representation of a transport protocol, either UDP or TCP.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]