diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-15 16:27:21 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-17 12:21:24 +0100 |
| commit | 14f919c3bc03fa2f7a6c0d9211e70b07633193da (patch) | |
| tree | 989bcf2abc09ea7aeca3d8fc0cad318c31a9592f | |
| parent | 53c78ac29e70ef40eead80b3088dc5958ed73c85 (diff) | |
| download | mullvadvpn-14f919c3bc03fa2f7a6c0d9211e70b07633193da.tar.xz mullvadvpn-14f919c3bc03fa2f7a6c0d9211e70b07633193da.zip | |
Determine Wintun alias dynamically for OpenVPN
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs index 8f6766cf37..92e9ceec16 100644 --- a/talpid-core/src/tunnel/openvpn/mod.rs +++ b/talpid-core/src/tunnel/openvpn/mod.rs @@ -30,7 +30,12 @@ use std::{ #[cfg(target_os = "linux")] use std::{collections::HashSet, net::IpAddr}; #[cfg(windows)] -use std::{ffi::OsStr, os::windows::ffi::OsStrExt, sync::Mutex, time::Instant}; +use std::{ + ffi::{OsStr, OsString}, + os::windows::ffi::OsStrExt, + sync::Mutex, + time::Instant, +}; use talpid_types::net::openvpn; #[cfg(any(windows, target_os = "linux"))] use talpid_types::ErrorExt; @@ -48,7 +53,7 @@ use winapi::shared::{ GetUnicastIpAddressTable, MIB_UNICASTIPADDRESS_ROW, MIB_UNICASTIPADDRESS_TABLE, }, nldef::{IpDadStatePreferred, IpDadStateTentative, NL_DAD_STATE}, - winerror::{ERROR_FILE_NOT_FOUND, NO_ERROR}, + winerror::NO_ERROR, ws2def::AF_UNSPEC, }; #[cfg(windows)] @@ -132,6 +137,11 @@ pub enum Error { #[error(display = "Failed to create Wintun adapter")] WintunError(#[error(source)] io::Error), + /// cannot determine adapter name + #[cfg(windows)] + #[error(display = "Failed to determine alias of Wintun adapter")] + WintunFindAlias(#[error(source)] io::Error), + /// cannot create a wintun interface #[cfg(windows)] #[error(display = "Failed to delete existing Wintun adapter")] @@ -354,36 +364,18 @@ impl OpenVpnMonitor<OpenVpnCommand> { let proxy_monitor = Self::start_proxy(¶ms.proxy, &proxy_resources)?; - let cmd = Self::create_openvpn_cmd( - params, - user_pass_file.as_ref(), - match proxy_auth_file { - Some(ref file) => Some(file.as_ref()), - _ => None, - }, - resource_dir, - &proxy_monitor, - )?; - - let plugin_path = Self::get_plugin_path(resource_dir)?; - #[cfg(windows)] let wintun_adapter = { let dll = get_wintun_dll(resource_dir)?; { - match windows::WintunAdapter::open(dll.clone(), &*ADAPTER_ALIAS, &*ADAPTER_POOL) { - Ok(adapter) => { - // Delete existing adapter in case it has residual config - adapter - .delete(false) - .map_err(Error::WintunDeleteExistingError)?; - } - Err(error) => { - if error.raw_os_error() != Some(ERROR_FILE_NOT_FOUND as i32) { - return Err(Error::WintunError(error)); - } - } + if let Ok(adapter) = + windows::WintunAdapter::open(dll.clone(), &*ADAPTER_ALIAS, &*ADAPTER_POOL) + { + // Delete existing adapter in case it has residual config + adapter + .delete(false) + .map_err(Error::WintunDeleteExistingError)?; } } @@ -434,6 +426,26 @@ impl OpenVpnMonitor<OpenVpnCommand> { adapter }; + #[cfg(windows)] + let adapter_alias = wintun_adapter + .adapter() + .name() + .map_err(Error::WintunFindAlias)?; + #[cfg(windows)] + log::debug!("Adapter alias: {}", adapter_alias.to_string_lossy()); + + let cmd = Self::create_openvpn_cmd( + params, + user_pass_file.as_ref(), + proxy_auth_file.as_ref().map(AsRef::as_ref), + resource_dir, + &proxy_monitor, + #[cfg(windows)] + adapter_alias.to_os_string(), + )?; + + let plugin_path = Self::get_plugin_path(resource_dir)?; + Self::new_internal( cmd, on_openvpn_event, @@ -738,6 +750,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> { proxy_auth_file: Option<&Path>, resource_dir: &Path, proxy_monitor: &Option<Box<dyn ProxyMonitor>>, + #[cfg(windows)] alias: OsString, ) -> Result<OpenVpnCommand> { let mut cmd = OpenVpnCommand::new(Self::get_openvpn_bin(resource_dir)?); if let Some(config) = Self::get_config_path(resource_dir) { @@ -752,7 +765,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> { .ca(resource_dir.join("ca.crt")); #[cfg(windows)] { - cmd.tunnel_alias(Some(ADAPTER_ALIAS.to_os_string())); + cmd.tunnel_alias(Some(alias)); cmd.windows_driver(Some(crate::process::openvpn::WindowsDriver::Wintun)); } if let Some(proxy_settings) = params.proxy.clone().take() { |
