summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-11-04 17:03:40 +0100
committerDavid Lönnhager <david.l@mullvad.net>2024-11-07 11:26:32 +0100
commit694ef7fd39edfda9639bc56dbefc370505c56b93 (patch)
tree85c3570e8a2d8c3b05b691be4a5516af5d7fc893
parentd7f18898c50a52a8bc428642fad375f5b9b94713 (diff)
downloadmullvadvpn-694ef7fd39edfda9639bc56dbefc370505c56b93.tar.xz
mullvadvpn-694ef7fd39edfda9639bc56dbefc370505c56b93.zip
Detect whether the Hyper-V firewall is available
-rw-r--r--talpid-core/src/firewall/windows/hyperv.rs11
-rw-r--r--talpid-core/src/firewall/windows/mod.rs22
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()