summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-02-22 11:59:38 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-02-22 11:59:38 +0100
commit5bfd4f56ea039bf3d21f888aad0ff10f040b05cf (patch)
tree121bc84895ae0acceab80e1e40a3de82d25c9f37
parentcb1c807d978ae29af1c747e1c73ffc1f4b2a8fe8 (diff)
parentd773017b19c48fe1019a45438d12e9e7c0951336 (diff)
downloadmullvadvpn-5bfd4f56ea039bf3d21f888aad0ff10f040b05cf.tar.xz
mullvadvpn-5bfd4f56ea039bf3d21f888aad0ff10f040b05cf.zip
Merge branch 'check-wintun-guid'
-rw-r--r--talpid-core/Cargo.toml2
-rw-r--r--talpid-core/src/tunnel/openvpn/mod.rs13
-rw-r--r--talpid-core/src/tunnel/openvpn/windows.rs64
3 files changed, 75 insertions, 4 deletions
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index b61de15494..1b2123a06e 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -72,7 +72,7 @@ tun = "0.5"
[target.'cfg(windows)'.dependencies]
widestring = "0.4"
winreg = { version = "0.7", features = ["transactions"] }
-winapi = { version = "0.3.6", features = [ "combaseapi", "handleapi", "ifdef", "libloaderapi", "netioapi", "stringapiset", "synchapi", "winbase", "winuser"] }
+winapi = { version = "0.3.6", features = ["combaseapi", "handleapi", "ifdef", "libloaderapi", "netioapi", "stringapiset", "synchapi", "winbase", "winerror", "winuser"] }
socket2 = "0.3"
pnet_packet = "0.26"
talpid-platform-metadata = { path = "../talpid-platform-metadata" }
diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs
index 7fdde6cdf0..6210b61d8b 100644
--- a/talpid-core/src/tunnel/openvpn/mod.rs
+++ b/talpid-core/src/tunnel/openvpn/mod.rs
@@ -68,7 +68,6 @@ lazy_static! {
static ref WINTUN_DLL: Mutex<Option<Arc<windows::WintunDll>>> = Mutex::new(None);
static ref ADAPTER_ALIAS: U16CString = U16CString::from_str("Mullvad").unwrap();
static ref ADAPTER_POOL: U16CString = U16CString::from_str("Mullvad").unwrap();
- static ref ADAPTER_GUID_STR: String = windows::string_from_guid(&ADAPTER_GUID);
}
#[cfg(windows)]
@@ -391,10 +390,20 @@ impl OpenVpnMonitor<OpenVpnCommand> {
log::warn!("You may need to restart Windows to complete the install of Wintun");
}
+ let assigned_guid = adapter.adapter().guid();
+ let assigned_guid = assigned_guid.as_ref().unwrap_or_else(|error| {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Cannot identify adapter guid")
+ );
+ &ADAPTER_GUID
+ });
+ let assigned_guid_string = windows::string_from_guid(assigned_guid);
+
// Workaround: OpenVPN looks up "ComponentId" to identify tunnel devices.
// If Wintun fails to create this registry value, create it here.
let adapter_key =
- windows::find_adapter_registry_key(&*ADAPTER_GUID_STR, KEY_READ | KEY_WRITE);
+ windows::find_adapter_registry_key(&assigned_guid_string, KEY_READ | KEY_WRITE);
match adapter_key {
Ok(adapter_key) => {
let component_id: io::Result<String> = adapter_key.get_value("ComponentId");
diff --git a/talpid-core/src/tunnel/openvpn/windows.rs b/talpid-core/src/tunnel/openvpn/windows.rs
index ae150a1117..a97b923f92 100644
--- a/talpid-core/src/tunnel/openvpn/windows.rs
+++ b/talpid-core/src/tunnel/openvpn/windows.rs
@@ -1,6 +1,6 @@
use std::{
ffi::CStr,
- fmt, io, iter,
+ fmt, io, iter, mem,
os::windows::{ffi::OsStrExt, io::RawHandle},
path::Path,
ptr,
@@ -11,7 +11,10 @@ use widestring::{U16CStr, U16CString};
use winapi::{
shared::{
guiddef::GUID,
+ ifdef::NET_LUID,
minwindef::{BOOL, FARPROC, HINSTANCE, HMODULE},
+ netioapi::ConvertInterfaceLuidToGuid,
+ winerror::NO_ERROR,
},
um::{
libloaderapi::{
@@ -47,6 +50,8 @@ type WintunDeleteAdapterFn = unsafe extern "stdcall" fn(
type WintunGetAdapterNameFn =
unsafe extern "stdcall" fn(adapter: RawHandle, name: *mut u16) -> BOOL;
+type WintunGetAdapterLuidFn = unsafe extern "stdcall" fn(adapter: RawHandle, luid: *mut NET_LUID);
+
pub struct WintunDll {
handle: HINSTANCE,
@@ -55,6 +60,7 @@ pub struct WintunDll {
func_free: WintunFreeAdapterFn,
func_delete: WintunDeleteAdapterFn,
func_get_adapter_name: WintunGetAdapterNameFn,
+ func_get_adapter_luid: WintunGetAdapterLuidFn,
}
unsafe impl Send for WintunDll {}
@@ -144,6 +150,19 @@ impl WintunAdapter {
pub fn name(&self) -> io::Result<U16CString> {
unsafe { self.dll_handle.get_adapter_name(self.handle) }
}
+
+ pub fn luid(&self) -> NET_LUID {
+ unsafe { self.dll_handle.get_adapter_luid(self.handle) }
+ }
+
+ pub fn guid(&self) -> io::Result<GUID> {
+ let mut guid = mem::MaybeUninit::zeroed();
+ let result = unsafe { ConvertInterfaceLuidToGuid(&self.luid(), guid.as_mut_ptr()) };
+ if result != NO_ERROR {
+ return Err(io::Error::last_os_error());
+ }
+ Ok(unsafe { guid.assume_init() })
+ }
}
impl Drop for WintunAdapter {
@@ -211,6 +230,12 @@ impl WintunDll {
CStr::from_bytes_with_nul(b"WintunGetAdapterName\0").unwrap(),
)?)
},
+ func_get_adapter_luid: unsafe {
+ std::mem::transmute(get_proc_fn(
+ handle,
+ CStr::from_bytes_with_nul(b"WintunGetAdapterLUID\0").unwrap(),
+ )?)
+ },
})
}
@@ -277,6 +302,12 @@ impl WintunDll {
Ok(U16CString::from_vec_with_nul(alias_buffer)
.map_err(|_| io::Error::new(io::ErrorKind::Other, "missing null terminator"))?)
}
+
+ pub unsafe fn get_adapter_luid(&self, adapter: RawHandle) -> NET_LUID {
+ let mut luid = mem::MaybeUninit::<NET_LUID>::zeroed();
+ (self.func_get_adapter_luid)(adapter, luid.as_mut_ptr());
+ luid.assume_init()
+ }
}
impl Drop for WintunDll {
@@ -342,4 +373,35 @@ mod tests {
fn test_wintun_imports() {
WintunDll::new_inner(ptr::null_mut(), get_proc_fn).unwrap();
}
+
+ #[test]
+ fn guid_to_string() {
+ let guids = [
+ (
+ "{AFE43773-E1F8-4EBB-8536-576AB86AFE9A}",
+ GUID {
+ Data1: 0xAFE43773,
+ Data2: 0xE1F8,
+ Data3: 0x4EBB,
+ Data4: [0x85, 0x36, 0x57, 0x6A, 0xB8, 0x6A, 0xFE, 0x9A],
+ },
+ ),
+ (
+ "{00000000-0000-0000-0000-000000000000}",
+ GUID {
+ Data1: 0,
+ Data2: 0,
+ Data3: 0,
+ Data4: [0; 8],
+ },
+ ),
+ ];
+
+ for (expected_str, guid) in &guids {
+ assert_eq!(
+ string_from_guid(guid).as_str().to_lowercase(),
+ expected_str.to_lowercase()
+ );
+ }
+ }
}