diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-06-08 10:18:39 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-06-08 10:18:39 +0200 |
| commit | 96235b29e25ac3c73ee1d0b3ed89674dcc9eede7 (patch) | |
| tree | 8286b3c7fd6cb264af34568967b5b874df816ee3 | |
| parent | 7c6b8b514e428f29dcf27483597e39e48402516f (diff) | |
| parent | 4bb6725c3898aee743b8f686ae170d783cd7a6f5 (diff) | |
| download | mullvadvpn-96235b29e25ac3c73ee1d0b3ed89674dcc9eede7.tar.xz mullvadvpn-96235b29e25ac3c73ee1d0b3ed89674dcc9eede7.zip | |
Merge branch 'refactor-connecting-state'
| -rw-r--r-- | docs/security.md | 7 | ||||
| -rw-r--r-- | talpid-core/src/firewall/linux.rs | 31 | ||||
| -rw-r--r-- | talpid-core/src/firewall/macos.rs | 42 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 51 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows.rs | 48 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/mod.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 34 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.cpp | 15 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.h | 7 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/mullvadguids.cpp | 30 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/mullvadguids.h | 3 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/baseline/permitping.cpp | 118 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/baseline/permitping.h | 30 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.cpp | 30 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.h | 20 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/winfw.vcxproj | 2 |
17 files changed, 58 insertions, 416 deletions
diff --git a/docs/security.md b/docs/security.md index 2fd46e26d8..c34a7d73a0 100644 --- a/docs/security.md +++ b/docs/security.md @@ -148,11 +148,8 @@ Examples: 1. Connecting to `a.b.c.d` port `1234` using WireGuard: Allow `a.b.c.d:1234/UDP` for `mullvad-daemon.exe` or any process running as `root`. -If connecting via WireGuard, this state allows ICMP packets to and from the in-tunnel IPs -(both v4 and v6) of the relay server the app is currently connecting to. That means the private -network IPs where the relay will respond inside the tunnel. It allows this on all interfaces, -since with the current architecture we don't know which network interface is the tunnel interface -at this point. +When using WireGuard, traffic inside the tunnel is permitted immediately after the tunnel device +has been created. See the [connected] state for details on this. ### Connected diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs index 755111a31b..d9f6825431 100644 --- a/talpid-core/src/firewall/linux.rs +++ b/talpid-core/src/firewall/linux.rs @@ -577,12 +577,10 @@ impl<'a> PolicyBatch<'a> { let allow_lan = match policy { FirewallPolicy::Connecting { peer_endpoint, - tunnel_interface, - pingable_hosts, + tunnel, allow_lan, allowed_endpoint, } => { - self.add_allow_icmp_pingable_hosts(&pingable_hosts); self.add_allow_tunnel_endpoint_rules(peer_endpoint); self.add_allow_endpoint_rules(allowed_endpoint); @@ -590,8 +588,8 @@ impl<'a> PolicyBatch<'a> { // over port 53) but before allow LAN (so DNS does not leak to the LAN) self.add_drop_dns_rule(); - if let Some(tunnel_interface) = tunnel_interface { - self.add_allow_tunnel_rules(tunnel_interface)?; + if let Some(tunnel) = tunnel { + self.add_allow_tunnel_rules(&tunnel.interface)?; } *allow_lan } @@ -688,29 +686,6 @@ impl<'a> PolicyBatch<'a> { self.batch.add(&out_rule, nftnl::MsgType::Add); } - fn add_allow_icmp_pingable_hosts(&mut self, pingable_hosts: &[IpAddr]) { - for host in pingable_hosts { - let icmp_proto = match &host { - IpAddr::V4(_) => libc::IPPROTO_ICMP as u8, - IpAddr::V6(_) => libc::IPPROTO_ICMPV6 as u8, - }; - - let mut out_rule = Rule::new(&self.out_chain); - check_ip(&mut out_rule, End::Dst, *host); - out_rule.add_expr(&nft_expr!(meta l4proto)); - out_rule.add_expr(&nft_expr!(cmp == icmp_proto)); - add_verdict(&mut out_rule, &Verdict::Accept); - self.batch.add(&out_rule, nftnl::MsgType::Add); - - let mut in_rule = Rule::new(&self.in_chain); - check_ip(&mut in_rule, End::Src, *host); - in_rule.add_expr(&nft_expr!(meta l4proto)); - in_rule.add_expr(&nft_expr!(cmp == icmp_proto)); - add_verdict(&mut in_rule, &Verdict::Accept); - self.batch.add(&in_rule, nftnl::MsgType::Add); - } - } - fn add_allow_dns_rules( &mut self, tunnel: &tunnel::TunnelMetadata, diff --git a/talpid-core/src/firewall/macos.rs b/talpid-core/src/firewall/macos.rs index f3048d61a8..1a899279ed 100644 --- a/talpid-core/src/firewall/macos.rs +++ b/talpid-core/src/firewall/macos.rs @@ -97,21 +97,19 @@ impl Firewall { match policy { FirewallPolicy::Connecting { peer_endpoint, - tunnel_interface, + tunnel, allow_lan, allowed_endpoint, - pingable_hosts, } => { let mut rules = vec![self.get_allow_relay_rule(peer_endpoint)?]; rules.push(self.get_allowed_endpoint_rule(allowed_endpoint)?); - rules.extend(self.get_allow_pingable_hosts(&pingable_hosts)?); // Important to block DNS after allow relay rule (so the relay can operate // over port 53) but before allow LAN (so DNS does not leak to the LAN) rules.append(&mut self.get_block_dns_rules()?); - if let Some(tunnel_interface) = tunnel_interface { - rules.push(self.get_allow_tunnel_rule(tunnel_interface.as_str())?); + if let Some(tunnel) = tunnel { + rules.push(self.get_allow_tunnel_rule(&tunnel.interface)?); } if allow_lan { @@ -295,40 +293,6 @@ impl Firewall { Ok(vec![block_tcp_dns_rule, block_udp_dns_rule]) } - fn get_allow_pingable_hosts( - &self, - pingable_hosts: &[IpAddr], - ) -> Result<Vec<pfctl::FilterRule>> { - let mut rules = vec![]; - for host in pingable_hosts.iter() { - let icmp_proto = match &host { - IpAddr::V4(_) => pfctl::Proto::Icmp, - IpAddr::V6(_) => pfctl::Proto::IcmpV6, - }; - - let out_rule = self - .create_rule_builder(FilterRuleAction::Pass) - .quick(true) - .direction(pfctl::Direction::Out) - .proto(icmp_proto) - .to(pfctl::Endpoint::new(*host, 0)) - .keep_state(pfctl::StatePolicy::Keep) - .build()?; - rules.push(out_rule); - - let in_rule = self - .create_rule_builder(FilterRuleAction::Pass) - .quick(true) - .direction(pfctl::Direction::In) - .proto(icmp_proto) - .from(pfctl::Endpoint::new(*host, 0)) - .keep_state(pfctl::StatePolicy::Keep) - .build()?; - rules.push(in_rule); - } - Ok(rules) - } - fn get_allow_tunnel_rule(&self, tunnel_interface: &str) -> Result<pfctl::FilterRule> { Ok(self .create_rule_builder(FilterRuleAction::Pass) diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 558b2b6040..a3d4333d6e 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -3,10 +3,10 @@ use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; #[cfg(unix)] use lazy_static::lazy_static; use std::fmt; -#[cfg(windows)] +#[cfg(not(target_os = "android"))] use std::net::IpAddr; #[cfg(unix)] -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::net::{Ipv4Addr, Ipv6Addr}; #[cfg(windows)] use std::path::PathBuf; use talpid_types::net::Endpoint; @@ -103,10 +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>, + /// Metadata about the tunnel and tunnel interface. + tunnel: Option<crate::tunnel::TunnelMetadata>, /// Flag setting if communication with LAN networks should be possible. allow_lan: bool, /// Host that should be reachable by the tunnel client while connecting. @@ -146,26 +144,35 @@ impl fmt::Display for FirewallPolicy { match self { FirewallPolicy::Connecting { peer_endpoint, - tunnel_interface, - pingable_hosts, + tunnel, allow_lan, .. - } => write!( - f, - "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 let Some(alias) = tunnel_interface { - alias + } => { + if let Some(tunnel) = tunnel { + write!( + f, + "Connecting to {} over \"{}\" (ip: {}, v4 gw: {}, v6 gw: {:?}), {} LAN", + peer_endpoint, + tunnel.interface, + tunnel + .ips + .iter() + .map(|ip| ip.to_string()) + .collect::<Vec<_>>() + .join(","), + tunnel.ipv4_gateway, + tunnel.ipv6_gateway, + if *allow_lan { "Allowing" } else { "Blocking" } + ) } else { - "none" + write!( + f, + "Connecting to {}, {} LAN, interface: none", + peer_endpoint, + if *allow_lan { "Allowing" } else { "Blocking" } + ) } - ), + } FirewallPolicy::Connected { peer_endpoint, tunnel, diff --git a/talpid-core/src/firewall/windows.rs b/talpid-core/src/firewall/windows.rs index 6a4fdad186..85ce8810f7 100644 --- a/talpid-core/src/firewall/windows.rs +++ b/talpid-core/src/firewall/windows.rs @@ -1,4 +1,4 @@ -use crate::logging::windows::log_sink; +use crate::{logging::windows::log_sink, tunnel::TunnelMetadata}; use std::{ffi::OsString, iter, net::IpAddr, path::Path, ptr}; @@ -93,8 +93,7 @@ impl FirewallT for Firewall { match policy { FirewallPolicy::Connecting { peer_endpoint, - tunnel_interface, - pingable_hosts, + tunnel, allow_lan, allowed_endpoint, relay_client, @@ -103,9 +102,8 @@ impl FirewallT for Firewall { self.set_connecting_state( &peer_endpoint, &cfg, - &tunnel_interface, + &tunnel, &allowed_endpoint, - &pingable_hosts, &relay_client, ) } @@ -154,9 +152,8 @@ impl Firewall { &mut self, endpoint: &Endpoint, winfw_settings: &WinFwSettings, - tunnel_interface: &Option<String>, + tunnel_metadata: &Option<TunnelMetadata>, allowed_endpoint: &Endpoint, - pingable_hosts: &Vec<IpAddr>, relay_client: &Path, ) -> Result<(), Error> { trace!("Applying 'connecting' firewall policy"); @@ -170,25 +167,6 @@ impl Firewall { let mut relay_client: Vec<u16> = relay_client.as_os_str().encode_wide().collect(); relay_client.push(0u16); - let pingable_addresses = pingable_hosts - .iter() - .map(|ip| widestring_ip(*ip)) - .collect::<Vec<_>>(); - let pingable_address_ptrs = pingable_addresses - .iter() - .map(|ip| ip.as_ptr()) - .collect::<Vec<_>>(); - - let pingable_hosts = if !pingable_address_ptrs.is_empty() { - Some(WinFwPingableHosts { - interfaceAlias: ptr::null(), - addresses: pingable_address_ptrs.as_ptr(), - num_addresses: pingable_addresses.len(), - }) - } else { - None - }; - let allowed_endpoint_ip = widestring_ip(allowed_endpoint.address.ip()); let winfw_allowed_endpoint = Some(WinFwEndpoint { ip: allowed_endpoint_ip.as_ptr(), @@ -196,9 +174,9 @@ impl Firewall { protocol: WinFwProt::from(allowed_endpoint.protocol), }); - let interface_wstr = tunnel_interface - .as_ref() - .map(|alias| WideCString::new(alias.encode_utf16().collect::<Vec<_>>()).unwrap()); + let interface_wstr = tunnel_metadata.as_ref().map(|metadata| { + WideCString::new(metadata.interface.encode_utf16().collect::<Vec<_>>()).unwrap() + }); let interface_wstr_ptr = if let Some(ref wstr) = interface_wstr { wstr.as_ptr() } else { @@ -211,7 +189,6 @@ impl Firewall { &winfw_relay, relay_client.as_ptr(), interface_wstr_ptr, - pingable_hosts.as_ptr(), winfw_allowed_endpoint.as_ptr(), ) .into_result() @@ -223,7 +200,7 @@ impl Firewall { &mut self, endpoint: &Endpoint, winfw_settings: &WinFwSettings, - tunnel_metadata: &crate::tunnel::TunnelMetadata, + tunnel_metadata: &TunnelMetadata, dns_servers: &[IpAddr], relay_client: &Path, ) -> Result<(), Error> { @@ -374,14 +351,6 @@ mod winfw { } } - #[repr(C)] - pub struct WinFwPingableHosts { - // a null pointer implies that all interfaces will be able to ping the supplied addresses - pub interfaceAlias: *const libc::wchar_t, - pub addresses: *const *const libc::wchar_t, - pub num_addresses: usize, - } - #[allow(dead_code)] #[repr(u32)] #[derive(Clone, Copy)] @@ -447,7 +416,6 @@ mod winfw { relay: &WinFwEndpoint, relayClient: *const libc::wchar_t, tunnelIfaceAlias: *const libc::wchar_t, - pingable_hosts: *const WinFwPingableHosts, allowed_endpoint: *const WinFwEndpoint, ) -> WinFwPolicyStatus; diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index 69cd842138..890fc07b67 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -74,7 +74,7 @@ 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), + InterfaceUp(TunnelMetadata), /// 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 0703633b4e..3ffaa9995c 100644 --- a/talpid-core/src/tunnel/wireguard/mod.rs +++ b/talpid-core/src/tunnel/wireguard/mod.rs @@ -175,7 +175,8 @@ impl WireguardMonitor { #[cfg(windows)] let iface_luid = tunnel.get_interface_luid(); - (on_event)(TunnelEvent::InterfaceUp(iface_name.clone())); + let metadata = Self::tunnel_metadata(&iface_name, &config); + (on_event)(TunnelEvent::InterfaceUp(metadata.clone())); #[cfg(target_os = "windows")] route_manager @@ -197,7 +198,6 @@ impl WireguardMonitor { _tcp_proxies: tcp_proxies, }; - let metadata = Self::tunnel_metadata(&iface_name, &config); let gateway = config.ipv4_gateway; let close_sender = monitor.close_msg_sender.clone(); let mut connectivity_monitor = connectivity_check::ConnectivityMonitor::new( diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index fe87d00f0f..8993354916 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -18,7 +18,6 @@ use futures::{ }; use log::{debug, error, info, trace, warn}; use std::{ - net::IpAddr, path::{Path, PathBuf}, thread, time::{Duration, Instant}, @@ -47,7 +46,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_metadata: Option<TunnelMetadata>, tunnel_close_event: TunnelCloseEvent, close_handle: Option<CloseHandle>, retry_attempt: u32, @@ -57,7 +56,7 @@ impl ConnectingState { fn set_firewall_policy( shared_values: &mut SharedTunnelStateValues, params: &TunnelParameters, - tunnel_interface: &Option<String>, + tunnel_metadata: &Option<TunnelMetadata>, ) -> Result<(), FirewallPolicyError> { #[cfg(target_os = "linux")] shared_values.disable_connectivity_check(); @@ -66,8 +65,7 @@ impl ConnectingState { let policy = FirewallPolicy::Connecting { peer_endpoint, - tunnel_interface: tunnel_interface.clone(), - pingable_hosts: gateway_list_from_params(params), + tunnel: tunnel_metadata.clone(), allow_lan: shared_values.allow_lan, allowed_endpoint: shared_values.allowed_endpoint.clone(), #[cfg(windows)] @@ -120,7 +118,7 @@ impl ConnectingState { Ok(ConnectingState { tunnel_events: event_rx.fuse(), tunnel_parameters: parameters, - tunnel_interface: None, + tunnel_metadata: None, tunnel_close_event, close_handle, retry_attempt, @@ -240,7 +238,7 @@ impl ConnectingState { match Self::set_firewall_policy( shared_values, &self.tunnel_parameters, - &self.tunnel_interface, + &self.tunnel_metadata, ) { Ok(()) => { cfg_if! { @@ -263,7 +261,7 @@ impl ConnectingState { if let Err(error) = Self::set_firewall_policy( shared_values, &self.tunnel_parameters, - &self.tunnel_interface, + &self.tunnel_metadata, ) { return self.disconnect( shared_values, @@ -326,12 +324,12 @@ impl ConnectingState { shared_values, AfterDisconnect::Block(ErrorStateCause::AuthFailed(reason)), ), - Some(TunnelEvent::InterfaceUp(interface)) => { - self.tunnel_interface = Some(interface); + Some(TunnelEvent::InterfaceUp(tunnel_metadata)) => { + self.tunnel_metadata = Some(tunnel_metadata); match Self::set_firewall_policy( shared_values, &self.tunnel_parameters, - &self.tunnel_interface, + &self.tunnel_metadata, ) { Ok(()) => SameState(self.into()), Err(error) => self.disconnect( @@ -549,17 +547,3 @@ impl TunnelState for ConnectingState { } } } - -fn gateway_list_from_params(params: &TunnelParameters) -> Vec<IpAddr> { - match params { - TunnelParameters::Wireguard(params) => { - let mut gateways = vec![params.connection.ipv4_gateway.into()]; - if let Some(ipv6_gateway) = params.connection.ipv6_gateway { - gateways.push(ipv6_gateway.into()) - }; - gateways - } - // No gateway list required when connecting to openvpn - TunnelParameters::OpenVpn(_) => vec![], - } -} diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp index d89437d699..6f2667c429 100644 --- a/windows/winfw/src/winfw/fwcontext.cpp +++ b/windows/winfw/src/winfw/fwcontext.cpp @@ -13,7 +13,6 @@ #include "rules/baseline/permitloopback.h" #include "rules/baseline/permitvpntunnel.h" #include "rules/baseline/permitvpntunnelservice.h" -#include "rules/baseline/permitping.h" #include "rules/baseline/permitdns.h" #include "rules/baseline/permitendpoint.h" #include "rules/dns/blockall.h" @@ -179,7 +178,6 @@ bool FwContext::applyPolicyConnecting const WinFwEndpoint &relay, const std::wstring &relayClient, const std::optional<std::wstring> &tunnelInterfaceAlias, - const std::optional<PingableHosts> &pingableHosts, const std::optional<WinFwEndpoint> &allowedEndpoint ) { @@ -205,19 +203,6 @@ bool FwContext::applyPolicyConnecting )); } - // - // Permit pinging the gateway inside the tunnel. - // - if (pingableHosts.has_value()) - { - const auto &ph = pingableHosts.value(); - - ruleset.emplace_back(std::make_unique<baseline::PermitPing>( - ph.tunnelInterfaceAlias, - ph.hosts - )); - } - const auto status = applyRuleset(ruleset); if (status) diff --git a/windows/winfw/src/winfw/fwcontext.h b/windows/winfw/src/winfw/fwcontext.h index cff3e3c823..a3b23f2c8b 100644 --- a/windows/winfw/src/winfw/fwcontext.h +++ b/windows/winfw/src/winfw/fwcontext.h @@ -24,19 +24,12 @@ public: const std::optional<WinFwEndpoint> &allowedEndpoint ); - struct PingableHosts - { - std::optional<std::wstring> tunnelInterfaceAlias; - std::vector<wfp::IpAddress> hosts; - }; - bool applyPolicyConnecting ( const WinFwSettings &settings, const WinFwEndpoint &relay, const std::wstring &relayClient, const std::optional<std::wstring> &tunnelInterfaceAlias, - const std::optional<PingableHosts> &pingableHosts, const std::optional<WinFwEndpoint> &allowedEndpoint ); diff --git a/windows/winfw/src/winfw/mullvadguids.cpp b/windows/winfw/src/winfw/mullvadguids.cpp index 417b157f82..f5693d7751 100644 --- a/windows/winfw/src/winfw/mullvadguids.cpp +++ b/windows/winfw/src/winfw/mullvadguids.cpp @@ -137,8 +137,6 @@ MullvadGuids::DetailedIdentityRegistry MullvadGuids::DetailedRegistry(IdentityQu registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Outbound_Router_Solicitation())); registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Router_Advertisement())); registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitNdp_Inbound_Redirect())); - registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitPing_Outbound_Icmpv4())); - registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitPing_Outbound_Icmpv6())); registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDns_Outbound_Ipv4())); registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Baseline_PermitDns_Outbound_Ipv6())); registry.insert(std::make_pair(WfpObjectType::Filter, Filter_Dns_BlockAll_Outbound_Ipv4())); @@ -757,34 +755,6 @@ const GUID &MullvadGuids::Filter_Baseline_PermitNdp_Inbound_Redirect() } //static -const GUID &MullvadGuids::Filter_Baseline_PermitPing_Outbound_Icmpv4() -{ - static const GUID g = - { - 0x2ecf7ff7, - 0xc951, - 0x4056, - { 0xb0, 0xf7, 0x40, 0xa4, 0x5c, 0x7e, 0xb4, 0xc2 } - }; - - return g; -} - -//static -const GUID &MullvadGuids::Filter_Baseline_PermitPing_Outbound_Icmpv6() -{ - static const GUID g = - { - 0x3deb8cab, - 0x1edb, - 0x4aa1, - { 0xb2, 0x73, 0xec, 0x61, 0x4f, 0x50, 0xdc, 0x13 } - }; - - return g; -} - -//static const GUID &MullvadGuids::Filter_Baseline_PermitDns_Outbound_Ipv4() { static const GUID g = diff --git a/windows/winfw/src/winfw/mullvadguids.h b/windows/winfw/src/winfw/mullvadguids.h index 7f00863811..f8b9fbb770 100644 --- a/windows/winfw/src/winfw/mullvadguids.h +++ b/windows/winfw/src/winfw/mullvadguids.h @@ -81,9 +81,6 @@ public: static const GUID &Filter_Baseline_PermitNdp_Inbound_Router_Advertisement(); static const GUID &Filter_Baseline_PermitNdp_Inbound_Redirect(); - static const GUID &Filter_Baseline_PermitPing_Outbound_Icmpv4(); - static const GUID &Filter_Baseline_PermitPing_Outbound_Icmpv6(); - static const GUID &Filter_Baseline_PermitDns_Outbound_Ipv4(); static const GUID &Filter_Baseline_PermitDns_Outbound_Ipv6(); diff --git a/windows/winfw/src/winfw/rules/baseline/permitping.cpp b/windows/winfw/src/winfw/rules/baseline/permitping.cpp deleted file mode 100644 index d8849590eb..0000000000 --- a/windows/winfw/src/winfw/rules/baseline/permitping.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "stdafx.h" -#include "permitping.h" -#include <winfw/mullvadguids.h> -#include <winfw/rules/shared.h> -#include <libwfp/filterbuilder.h> -#include <libwfp/conditionbuilder.h> -#include <libwfp/conditions/conditionip.h> -#include <libwfp/conditions/conditioninterface.h> -#include <libwfp/conditions/conditionprotocol.h> -#include <libcommon/error.h> - -using namespace wfp::conditions; - -namespace rules::baseline -{ - -PermitPing::PermitPing -( - std::optional<std::wstring> interfaceAlias, - const std::vector<wfp::IpAddress> &hosts -) - : m_interfaceAlias(std::move(interfaceAlias)) -{ - SplitAddresses(hosts, m_hostsIpv4, m_hostsIpv6); -} - -bool PermitPing::apply(IObjectInstaller &objectInstaller) -{ - if (false == m_hostsIpv4.empty()) - { - if (false == applyIcmpv4(objectInstaller)) - { - return false; - } - } - - if (false == m_hostsIpv6.empty()) - { - if (false == applyIcmpv6(objectInstaller)) - { - return false; - } - } - - return true; -} - -bool PermitPing::applyIcmpv4(IObjectInstaller &objectInstaller) const -{ - wfp::FilterBuilder filterBuilder; - - // - // #1 Permit outbound ICMPv4 to %host% on %interface%. - // - - filterBuilder - .key(MullvadGuids::Filter_Baseline_PermitPing_Outbound_Icmpv4()) - .name(L"Permit outbound ICMP to specific host (ICMPv4)") - .description(L"This filter is part of a rule that permits ping") - .provider(MullvadGuids::Provider()) - .layer(FWPM_LAYER_ALE_AUTH_CONNECT_V4) - .sublayer(MullvadGuids::SublayerBaseline()) - .weight(wfp::FilterBuilder::WeightClass::Max) - .permit(); - - wfp::ConditionBuilder conditionBuilder(FWPM_LAYER_ALE_AUTH_CONNECT_V4); - - conditionBuilder.add_condition(ConditionProtocol::Icmp()); - - for (const auto &host : m_hostsIpv4) - { - conditionBuilder.add_condition(ConditionIp::Remote(host)); - } - - if (m_interfaceAlias.has_value()) - { - conditionBuilder.add_condition(ConditionInterface::Alias(m_interfaceAlias.value())); - } - - return objectInstaller.addFilter(filterBuilder, conditionBuilder); -} - -bool PermitPing::applyIcmpv6(IObjectInstaller &objectInstaller) const -{ - wfp::FilterBuilder filterBuilder; - - // - // #1 Permit outbound ICMPv6 to %host% on %interface%. - // - - filterBuilder - .key(MullvadGuids::Filter_Baseline_PermitPing_Outbound_Icmpv6()) - .name(L"Permit outbound ICMP to specific host (ICMPv6)") - .description(L"This filter is part of a rule that permits ping") - .provider(MullvadGuids::Provider()) - .layer(FWPM_LAYER_ALE_AUTH_CONNECT_V6) - .sublayer(MullvadGuids::SublayerBaseline()) - .weight(wfp::FilterBuilder::WeightClass::Max) - .permit(); - - wfp::ConditionBuilder conditionBuilder(FWPM_LAYER_ALE_AUTH_CONNECT_V6); - - conditionBuilder.add_condition(ConditionProtocol::IcmpV6()); - - for (const auto &host : m_hostsIpv6) - { - conditionBuilder.add_condition(ConditionIp::Remote(host)); - } - - if (m_interfaceAlias.has_value()) - { - conditionBuilder.add_condition(ConditionInterface::Alias(m_interfaceAlias.value())); - } - - return objectInstaller.addFilter(filterBuilder, conditionBuilder); -} - -} diff --git a/windows/winfw/src/winfw/rules/baseline/permitping.h b/windows/winfw/src/winfw/rules/baseline/permitping.h deleted file mode 100644 index 438aafc3f9..0000000000 --- a/windows/winfw/src/winfw/rules/baseline/permitping.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include <winfw/rules/ifirewallrule.h> -#include <libwfp/ipaddress.h> -#include <string> -#include <optional> -#include <vector> - -namespace rules::baseline -{ - -class PermitPing : public IFirewallRule -{ -public: - - PermitPing(std::optional<std::wstring> interfaceAlias, const std::vector<wfp::IpAddress> &hosts); - - bool apply(IObjectInstaller &objectInstaller) override; - -private: - - const std::optional<std::wstring> m_interfaceAlias; - std::vector<wfp::IpAddress> m_hostsIpv4; - std::vector<wfp::IpAddress> m_hostsIpv6; - - bool applyIcmpv4(IObjectInstaller &objectInstaller) const; - bool applyIcmpv6(IObjectInstaller &objectInstaller) const; -}; - -} diff --git a/windows/winfw/src/winfw/winfw.cpp b/windows/winfw/src/winfw/winfw.cpp index 119edc4ca6..57610409c4 100644 --- a/windows/winfw/src/winfw/winfw.cpp +++ b/windows/winfw/src/winfw/winfw.cpp @@ -20,34 +20,6 @@ void *g_logSinkContext = nullptr; FwContext *g_fwContext = nullptr; -std::optional<FwContext::PingableHosts> ConvertPingableHosts(const PingableHosts *pingableHosts) -{ - if (nullptr == pingableHosts) - { - return {}; - } - - if (nullptr == pingableHosts->hosts - || 0 == pingableHosts->numHosts) - { - THROW_ERROR("Invalid PingableHosts structure"); - } - - FwContext::PingableHosts converted; - - if (nullptr != pingableHosts->tunnelInterfaceAlias) - { - converted.tunnelInterfaceAlias = pingableHosts->tunnelInterfaceAlias; - } - - for (size_t i = 0; i < pingableHosts->numHosts; ++i) - { - converted.hosts.emplace_back(wfp::IpAddress(pingableHosts->hosts[i])); - } - - return converted; -} - WINFW_POLICY_STATUS HandlePolicyException(const common::error::WindowsException &err) { @@ -261,7 +233,6 @@ WinFw_ApplyPolicyConnecting( const WinFwEndpoint *relay, const wchar_t *relayClient, const wchar_t *tunnelInterfaceAlias, - const PingableHosts *pingableHosts, const WinFwEndpoint *allowedEndpoint ) { @@ -292,7 +263,6 @@ WinFw_ApplyPolicyConnecting( *relay, relayClient, tunnelInterfaceAlias != nullptr ? std::make_optional(tunnelInterfaceAlias) : std::nullopt, - ConvertPingableHosts(pingableHosts), MakeOptional(allowedEndpoint) ) ? WINFW_POLICY_STATUS_SUCCESS : WINFW_POLICY_STATUS_GENERAL_FAILURE; } diff --git a/windows/winfw/src/winfw/winfw.h b/windows/winfw/src/winfw/winfw.h index 5065582e29..5a34b7784b 100644 --- a/windows/winfw/src/winfw/winfw.h +++ b/windows/winfw/src/winfw/winfw.h @@ -118,23 +118,6 @@ WinFw_Deinitialize( WINFW_CLEANUP_POLICY cleanupPolicy ); -// -// PingableHosts: -// -// Specifies a set of IP addresses that should be reachable by ICMP when the connecting -// policy is effective. -// -// The interface alias is optional and can be used to restrict the traffic such -// that it is only allowed on that specific interface. -// -typedef struct tag_PingableHosts -{ - const wchar_t *tunnelInterfaceAlias; - const wchar_t **hosts; - size_t numHosts; -} -PingableHosts; - enum WINFW_POLICY_STATUS { WINFW_POLICY_STATUS_SUCCESS = 0, @@ -148,7 +131,7 @@ enum WINFW_POLICY_STATUS // Apply restrictions in the firewall that block all traffic, except: // - What is specified by settings // - Communication with the relay server -// - ICMP (for ping) to/from tunnel gateway +// - Non-DNS traffic inside the VPN tunnel // extern "C" WINFW_LINKAGE @@ -159,7 +142,6 @@ WinFw_ApplyPolicyConnecting( const WinFwEndpoint *relay, const wchar_t *relayClient, const wchar_t *tunnelInterfaceAlias, - const PingableHosts *pingableHosts, const WinFwEndpoint *allowedEndpoint ); diff --git a/windows/winfw/src/winfw/winfw.vcxproj b/windows/winfw/src/winfw/winfw.vcxproj index 3f9502a10d..72c5eea98a 100644 --- a/windows/winfw/src/winfw/winfw.vcxproj +++ b/windows/winfw/src/winfw/winfw.vcxproj @@ -32,7 +32,6 @@ <ClCompile Include="rules\baseline\permitlanservice.cpp" /> <ClCompile Include="rules\baseline\permitloopback.cpp" /> <ClCompile Include="rules\baseline\permitndp.cpp" /> - <ClCompile Include="rules\baseline\permitping.cpp" /> <ClCompile Include="rules\baseline\permitvpntunnel.cpp" /> <ClCompile Include="rules\baseline\permitvpntunnelservice.cpp" /> <ClCompile Include="rules\dns\blockall.cpp" /> @@ -67,7 +66,6 @@ <ClInclude Include="rules\baseline\permitlanservice.h" /> <ClInclude Include="rules\baseline\permitloopback.h" /> <ClInclude Include="rules\baseline\permitndp.h" /> - <ClInclude Include="rules\baseline\permitping.h" /> <ClInclude Include="rules\baseline\permitvpntunnel.h" /> <ClInclude Include="rules\baseline\permitvpntunnelservice.h" /> <ClInclude Include="rules\dns\blockall.h" /> |
