diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-22 11:59:38 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-22 11:59:38 +0100 |
| commit | 5bfd4f56ea039bf3d21f888aad0ff10f040b05cf (patch) | |
| tree | 121bc84895ae0acceab80e1e40a3de82d25c9f37 | |
| parent | cb1c807d978ae29af1c747e1c73ffc1f4b2a8fe8 (diff) | |
| parent | d773017b19c48fe1019a45438d12e9e7c0951336 (diff) | |
| download | mullvadvpn-5bfd4f56ea039bf3d21f888aad0ff10f040b05cf.tar.xz mullvadvpn-5bfd4f56ea039bf3d21f888aad0ff10f040b05cf.zip | |
Merge branch 'check-wintun-guid'
| -rw-r--r-- | talpid-core/Cargo.toml | 2 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 13 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/windows.rs | 64 |
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() + ); + } + } } |
