diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-11-04 17:03:40 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-11-07 11:26:32 +0100 |
| commit | 694ef7fd39edfda9639bc56dbefc370505c56b93 (patch) | |
| tree | 85c3570e8a2d8c3b05b691be4a5516af5d7fc893 | |
| parent | d7f18898c50a52a8bc428642fad375f5b9b94713 (diff) | |
| download | mullvadvpn-694ef7fd39edfda9639bc56dbefc370505c56b93.tar.xz mullvadvpn-694ef7fd39edfda9639bc56dbefc370505c56b93.zip | |
Detect whether the Hyper-V firewall is available
| -rw-r--r-- | talpid-core/src/firewall/windows/hyperv.rs | 11 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows/mod.rs | 22 |
2 files changed, 23 insertions, 10 deletions
diff --git a/talpid-core/src/firewall/windows/hyperv.rs b/talpid-core/src/firewall/windows/hyperv.rs index c78d690e72..1fc8bb2578 100644 --- a/talpid-core/src/firewall/windows/hyperv.rs +++ b/talpid-core/src/firewall/windows/hyperv.rs @@ -40,11 +40,18 @@ pub enum Error { /// Initialize WMI connection to the ROOT\StandardCIMV2 namespace, which may be used for /// interacting with Hyper-V rules. pub fn init_wmi() -> Result<wmi::WMIConnection, Error> { - wmi::WMIConnection::with_namespace_path( + let con = wmi::WMIConnection::with_namespace_path( WMI_NAMESPACE, wmi::COMLibrary::new().map_err(Error::InitializeCom)?, ) - .map_err(Error::ConnectWmi) + .map_err(Error::ConnectWmi)?; + + // Test whether the class is available + let _ = con + .get_raw_by_path("MSFT_NetFirewallHyperVRule") + .map_err(Error::ObtainHyperVClass)?; + + Ok(con) } /// Add a Hyper-V rule that blocks all traffic using WMI (Windows Management Instrumentation). diff --git a/talpid-core/src/firewall/windows/mod.rs b/talpid-core/src/firewall/windows/mod.rs index 62701c6d82..d4b0b883d4 100644 --- a/talpid-core/src/firewall/windows/mod.rs +++ b/talpid-core/src/firewall/windows/mod.rs @@ -14,12 +14,21 @@ use windows_sys::Win32::Globalization::{MultiByteToWideChar, CP_ACP}; mod hyperv; +const HYPERV_LEAK_WARNING_MSG: &str = "Hyper-V (e.g. WSL machines) may leak in blocked states."; + // `COMLibrary` must be initialized for per thread, so use TLS thread_local! { - static WMI: Option<wmi::WMIConnection> = consume_and_log_hyperv_err( - "Initialize COM and WMI", - hyperv::init_wmi(), - ); + static WMI: Option<wmi::WMIConnection> = { + let result = hyperv::init_wmi(); + if matches!(&result, Err(hyperv::Error::ObtainHyperVClass(_))) { + log::warn!("The Hyper-V firewall is not available. {HYPERV_LEAK_WARNING_MSG}"); + return None; + } + consume_and_log_hyperv_err( + "Initialize COM and WMI", + result, + ) + }; } /// Enable or disable blocking Hyper-V rule @@ -497,10 +506,7 @@ fn consume_and_log_hyperv_err<T>( .inspect_err(|error| { log::error!( "{}", - error.display_chain_with_msg(&format!( - "Failed: {action}. \ - Hyper-V (e.g. WSL machines) may leak in blocked states." - )) + error.display_chain_with_msg(&format!("{action}. {HYPERV_LEAK_WARNING_MSG}")) ); }) .ok() |
