diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-12-02 17:36:39 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-01-04 16:50:18 +0100 |
| commit | 29260429f5cdf04ef4e51a42a4abd11f5e2e03b7 (patch) | |
| tree | 35db7806efabbf85c79cc919dc2fea07f30578ff | |
| parent | 1680065e267b84f1443317ae942cd0c609e86b14 (diff) | |
| download | mullvadvpn-29260429f5cdf04ef4e51a42a4abd11f5e2e03b7.tar.xz mullvadvpn-29260429f5cdf04ef4e51a42a4abd11f5e2e03b7.zip | |
Always prefer the last used API address
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt | 6 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt | 2 | ||||
| -rwxr-xr-x | dist-assets/pkg-scripts/preinstall | 3 | ||||
| -rwxr-xr-x | dist-assets/uninstall_macos.sh | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 6 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 3 | ||||
| -rw-r--r-- | mullvad-jni/src/lib.rs | 1 | ||||
| -rw-r--r-- | mullvad-jni/src/problem_report.rs | 8 | ||||
| -rw-r--r-- | mullvad-paths/src/cache.rs | 23 | ||||
| -rw-r--r-- | mullvad-paths/src/lib.rs | 2 | ||||
| -rw-r--r-- | mullvad-problem-report/src/lib.rs | 8 | ||||
| -rw-r--r-- | mullvad-problem-report/src/main.rs | 4 | ||||
| -rw-r--r-- | mullvad-rpc/src/address_cache.rs | 150 | ||||
| -rw-r--r-- | mullvad-rpc/src/lib.rs | 48 | ||||
| -rw-r--r-- | mullvad-rpc/src/rest.rs | 15 | ||||
| -rw-r--r-- | mullvad-setup/src/daemon_paths.rs | 14 | ||||
| -rw-r--r-- | mullvad-setup/src/main.rs | 44 | ||||
| -rw-r--r-- | windows/nsis-plugins/src/cleanup/cleaningops.cpp | 8 |
18 files changed, 219 insertions, 128 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt index ae2d1b2df2..52795f0964 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt @@ -22,7 +22,7 @@ class MullvadProblemReport { } val logDirectory = CompletableDeferred<File>() - val resourcesDirectory = CompletableDeferred<File>() + val cacheDirectory = CompletableDeferred<File>() private val commandChannel = spawnActor() @@ -112,7 +112,7 @@ class MullvadProblemReport { userEmail, userMessage, problemReportPath.await().absolutePath, - resourcesDirectory.await().absolutePath + cacheDirectory.await().absolutePath ) if (result) { @@ -132,6 +132,6 @@ class MullvadProblemReport { userEmail: String, userMessage: String, reportPath: String, - resourcesDirectory: String + cacheDirectory: String ): Boolean } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index 44996b55b8..613927fe49 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -88,7 +88,7 @@ class MainActivity : FragmentActivity() { problemReport.apply { logDirectory.complete(filesDir) - resourcesDirectory.complete(filesDir) + cacheDirectory.complete(cacheDir) } setContentView(R.layout.main) diff --git a/dist-assets/pkg-scripts/preinstall b/dist-assets/pkg-scripts/preinstall index 5b56185a58..6c0ee99ff3 100755 --- a/dist-assets/pkg-scripts/preinstall +++ b/dist-assets/pkg-scripts/preinstall @@ -80,7 +80,10 @@ fi # Remove the existing relay and API address cache lists. # There is a risk that they're incompatible with the format this version wants rm "$NEW_CACHE_DIR/relays.json" || true +# Old API IP cache rm "$NEW_CACHE_DIR/api-ip-address.txt" || true +# New API IP cache +rm "/Library/Caches/mullvad-vpn/api-ip-address.txt" || true # Notify the running daemon that we are going to kill it and replace it with a newer version. # This will make the daemon save it's state to a file and then lock the firewall to prevent diff --git a/dist-assets/uninstall_macos.sh b/dist-assets/uninstall_macos.sh index 622457f994..4c02245a30 100755 --- a/dist-assets/uninstall_macos.sh +++ b/dist-assets/uninstall_macos.sh @@ -40,7 +40,7 @@ sudo pkgutil --forget net.mullvad.vpn || true read -p "Do you want to delete the log and cache files the app has created? (y/n) " if [[ "$REPLY" =~ [Yy]$ ]]; then - sudo rm -rf /var/log/mullvad-vpn /var/root/Library/Caches/mullvad-vpn + sudo rm -rf /var/log/mullvad-vpn /var/root/Library/Caches/mullvad-vpn /Library/Caches/mullvad-vpn for user in /Users/*; do user_log_dir="$user/Library/Logs/Mullvad VPN" if [[ -d "$user_log_dir" ]]; then diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 290fdaa9ee..b182686e19 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -483,6 +483,7 @@ where resource_dir: PathBuf, settings_dir: PathBuf, cache_dir: PathBuf, + user_cache_dir: PathBuf, event_listener: L, command_channel: DaemonCommandChannel, #[cfg(target_os = "android")] android_context: AndroidContext, @@ -492,8 +493,9 @@ where let mut rpc_runtime = mullvad_rpc::MullvadRpcRuntime::with_cache( tokio::runtime::Handle::current(), - &resource_dir, - Some(&cache_dir), + Some(&resource_dir), + &user_cache_dir, + true, ) .await .map_err(Error::InitRpcFactory)?; diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 4e055183b9..bd91729af1 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -123,6 +123,8 @@ async fn create_daemon( .map_err(|e| e.display_chain_with_msg("Unable to get settings dir"))?; let cache_dir = mullvad_paths::cache_dir() .map_err(|e| e.display_chain_with_msg("Unable to get cache dir"))?; + let user_cache_dir = mullvad_paths::user_cache_dir() + .map_err(|e| e.display_chain_with_msg("Unable to get user cache dir"))?; let command_channel = DaemonCommandChannel::new(); let event_listener = spawn_management_interface(command_channel.sender()).await?; @@ -132,6 +134,7 @@ async fn create_daemon( resource_dir, settings_dir, cache_dir, + user_cache_dir, event_listener, command_channel, ) diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 35fe78dd01..0b95495746 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -236,6 +236,7 @@ fn spawn_daemon( Some(resource_dir.clone()), resource_dir.clone(), resource_dir, + cache_dir.clone(), cache_dir, listener, command_channel, diff --git a/mullvad-jni/src/problem_report.rs b/mullvad-jni/src/problem_report.rs index fb83c06bdc..f1a7e884db 100644 --- a/mullvad-jni/src/problem_report.rs +++ b/mullvad-jni/src/problem_report.rs @@ -43,21 +43,21 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_dataproxy_MullvadProblemRepor userEmail: JString<'_>, userMessage: JString<'_>, outputPath: JString<'_>, - resourcesDirectory: JString<'_>, + cacheDirectory: JString<'_>, ) -> jboolean { let env = JnixEnv::from(env); let user_email = String::from_java(&env, userEmail); let user_message = String::from_java(&env, userMessage); let output_path_string = String::from_java(&env, outputPath); let output_path = Path::new(&output_path_string); - let resources_directory_string = String::from_java(&env, resourcesDirectory); - let resources_directory = Path::new(&resources_directory_string); + let cache_directory_string = String::from_java(&env, cacheDirectory); + let cache_directory = Path::new(&cache_directory_string); let send_result = mullvad_problem_report::send_problem_report( &user_email, &user_message, output_path, - resources_directory, + cache_directory, ); match send_result { diff --git a/mullvad-paths/src/cache.rs b/mullvad-paths/src/cache.rs index 35b99738f0..490fe9f702 100644 --- a/mullvad-paths/src/cache.rs +++ b/mullvad-paths/src/cache.rs @@ -33,3 +33,26 @@ pub fn get_default_cache_dir() -> Result<PathBuf> { Ok(std::path::Path::new(crate::APP_PATH).join("cache")) } } + +/// Creates and returns a cache directory that is readable by all users. +pub fn user_cache_dir() -> Result<PathBuf> { + #[cfg(not(target_os = "macos"))] + let permissions = None; + #[cfg(target_os = "macos")] + let permissions = Some(std::os::unix::fs::PermissionsExt::from_mode(0o755)); + crate::create_and_return(get_user_cache_dir, permissions) +} + +pub fn get_user_cache_dir() -> Result<PathBuf> { + #[cfg(windows)] + { + let dir = crate::get_allusersprofile_dir(); + dir.map(|dir| dir.join(crate::PRODUCT_NAME)) + } + #[cfg(target_os = "macos")] + { + Ok(std::path::Path::new("/Library/Caches").join(crate::PRODUCT_NAME)) + } + #[cfg(not(any(target_os = "macos", windows)))] + get_cache_dir() +} diff --git a/mullvad-paths/src/lib.rs b/mullvad-paths/src/lib.rs index 7b06c9937d..03453e9adc 100644 --- a/mullvad-paths/src/lib.rs +++ b/mullvad-paths/src/lib.rs @@ -56,7 +56,7 @@ fn create_and_return( } mod cache; -pub use crate::cache::{cache_dir, get_default_cache_dir}; +pub use crate::cache::{cache_dir, get_default_cache_dir, get_user_cache_dir, user_cache_dir}; mod logs; pub use crate::logs::{get_default_log_dir, get_log_dir, log_dir}; diff --git a/mullvad-problem-report/src/lib.rs b/mullvad-problem-report/src/lib.rs index 276a1557b1..4601a810ea 100644 --- a/mullvad-problem-report/src/lib.rs +++ b/mullvad-problem-report/src/lib.rs @@ -69,6 +69,9 @@ pub enum Error { #[error(display = "Unable to spawn Tokio runtime")] CreateRuntime(#[error(source)] io::Error), + + #[error(display = "Unable to find cache directory")] + ObtainCacheDirectory(#[error(source)] mullvad_paths::Error), } /// These are errors that can happen during problem report collection. @@ -253,7 +256,7 @@ pub fn send_problem_report( user_email: &str, user_message: &str, report_path: &Path, - resource_dir: &Path, + user_cache_dir: &Path, ) -> Result<(), Error> { let report_content = normalize_newlines( read_file_lossy(report_path, REPORT_MAX_SIZE).map_err(|source| { @@ -275,8 +278,9 @@ pub fn send_problem_report( let mut rpc_manager = runtime .block_on(mullvad_rpc::MullvadRpcRuntime::with_cache( runtime.handle().clone(), - resource_dir, None, + user_cache_dir, + false, )) .map_err(Error::CreateRpcClientError)?; let rpc_client = mullvad_rpc::ProblemReportProxy::new(rpc_manager.mullvad_rest_handle()); diff --git a/mullvad-problem-report/src/main.rs b/mullvad-problem-report/src/main.rs index 7090cecd6d..4f0dfb0265 100644 --- a/mullvad-problem-report/src/main.rs +++ b/mullvad-problem-report/src/main.rs @@ -113,8 +113,8 @@ fn run() -> Result<(), Error> { let report_path = Path::new(send_matches.value_of_os("report").unwrap()); let user_email = send_matches.value_of("email").unwrap_or(""); let user_message = send_matches.value_of("message").unwrap_or(""); - let resource_dir = mullvad_paths::get_resource_dir(); - send_problem_report(user_email, user_message, report_path, &resource_dir) + let user_cache_dir = mullvad_paths::get_user_cache_dir()?; + send_problem_report(user_email, user_message, report_path, &user_cache_dir) } else { unreachable!("No sub command given"); } diff --git a/mullvad-rpc/src/address_cache.rs b/mullvad-rpc/src/address_cache.rs index b2181c763b..73b85e4998 100644 --- a/mullvad-rpc/src/address_cache.rs +++ b/mullvad-rpc/src/address_cache.rs @@ -6,6 +6,7 @@ use std::{ path::Path, sync::{Arc, Mutex}, }; +use talpid_types::ErrorExt; use tokio::{ fs, io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, @@ -20,6 +21,9 @@ pub enum Error { #[error(display = "Failed to read the address cache file")] ReadAddressCache(#[error(source)] io::Error), + #[error(display = "Failed to update the address cache file")] + WriteAddressCache(#[error(source)] io::Error), + #[error(display = "The address cache is empty")] EmptyAddressCache, } @@ -27,34 +31,41 @@ pub enum Error { #[derive(Clone)] pub struct AddressCache { inner: Arc<Mutex<AddressCacheInner>>, - cache_path: Option<Arc<Path>>, + write_path: Option<Arc<Path>>, } impl AddressCache { - /// Initialize cache using the given list, and write changes to `cache_path`. - pub fn new(addresses: Vec<SocketAddr>, cache_path: Option<Box<Path>>) -> Result<Self, Error> { - log::trace!("API address cache: {:?}", addresses); - - let cache = AddressCacheInner::from_addresses(addresses)?; + /// Initialize cache using the given list, and write changes to `write_path`. + pub fn new(addresses: Vec<SocketAddr>, write_path: Option<Box<Path>>) -> Result<Self, Error> { + let mut cache = AddressCacheInner::from_addresses(addresses)?; + cache.shuffle_tail(); + log::trace!("API address cache: {:?}", cache.addresses); log::debug!("Using API address: {:?}", Self::get_address_inner(&cache)); let address_cache = Self { inner: Arc::new(Mutex::new(cache)), - cache_path: cache_path.map(|cache| Arc::from(cache)), + write_path: write_path.map(|cache| Arc::from(cache)), }; Ok(address_cache) } - /// Initialize cache using `read_path`, and write changes to `cache_path`. - pub async fn from_file(read_path: &Path, cache_path: Option<Box<Path>>) -> Result<Self, Error> { + /// Initialize cache using `read_path`, and write changes to `write_path`. + pub async fn from_file(read_path: &Path, write_path: Option<Box<Path>>) -> Result<Self, Error> { log::debug!("Loading API addresses from {:?}", read_path); - Self::new(read_address_file(read_path).await?, cache_path) + Self::new(read_address_file(read_path).await?, write_path) } + /// Returns the currently selected address. pub fn get_address(&self) -> SocketAddr { let mut inner = self.inner.lock().unwrap(); - inner.last_try = Some(inner.choice); + inner.tried_current = true; + Self::get_address_inner(&inner) + } + /// Returns the current address without registering it as "tried" + /// in [`has_tried_current_address`]. + pub fn peek_address(&self) -> SocketAddr { + let inner = self.inner.lock().unwrap(); Self::get_address_inner(&inner) } @@ -68,26 +79,38 @@ impl AddressCache { .unwrap_or(&API_ADDRESS.into()) } - pub fn register_failure(&self, failed_addr: SocketAddr, err: &dyn std::error::Error) { - let mut inner = self.inner.lock().unwrap(); + pub fn has_tried_current_address(&self) -> bool { + let inner = self.inner.lock().unwrap(); + inner.tried_current + } - let current_address = Self::get_address_inner(&inner); - // Only choose the next server if the current one has been tried before and it failed - if failed_addr == current_address - && inner - .last_try - .map(|last_try| last_try == inner.choice) - .unwrap_or(false) - { + pub async fn select_new_address(&self) { + let (new_choice, old_choice) = { + let mut inner = self.inner.lock().unwrap(); + let old_choice = inner.choice; inner.choice = inner.choice.wrapping_add(1); - let new_address = Self::get_address_inner(&inner); - log::error!( - "HTTP request failed: {}, using address {}. Trying next API address: {}", - err, - failed_addr, - new_address - ); + (inner.choice, old_choice) + }; + + if new_choice == old_choice { + return; + } + + if let Err(error) = self.save_to_disk().await { + log::error!("{}", error.display_chain()); + } + } + + /// Forgets the currently selected address and randomizes + /// the entire list. + pub async fn randomize(&self) -> Result<(), Error> { + { + let mut inner = self.inner.lock().unwrap(); + inner.shuffle(); + inner.choice = 0; + inner.tried_current = false; } + self.save_to_disk().await.map_err(Error::WriteAddressCache) } pub async fn set_addresses(&self, mut addresses: Vec<SocketAddr>) -> io::Result<()> { @@ -97,9 +120,20 @@ impl AddressCache { let mut current_sorted = inner.addresses.clone(); current_sorted.sort(); if addresses != current_sorted { + let current_address = Self::get_address_inner(&inner); + inner.addresses = addresses.clone(); inner.shuffle(); - inner.choice = 0; + + // Prefer a likely-working address + let choice = inner.addresses.iter().position(|&addr| addr == current_address); + if let Some(choice) = choice { + inner.choice = choice; + } else { + inner.choice = 0; + inner.tried_current = false; + } + true } else { false @@ -107,26 +141,41 @@ impl AddressCache { }; if should_update { log::trace!("API address cache: {:?}", addresses); - self.save_to_disk(addresses).await?; + self.save_to_disk().await?; } Ok(()) } - async fn save_to_disk(&self, addresses: Vec<SocketAddr>) -> io::Result<()> { - if let Some(cache_path) = self.cache_path.as_ref() { - let mut file = fs::File::create(cache_path).await?; - let mut contents = addresses - .iter() - .map(ToString::to_string) - .collect::<Vec<String>>() - .join("\n"); - contents += "\n"; + async fn save_to_disk(&self) -> io::Result<()> { + let write_path = match self.write_path.as_ref() { + Some(write_path) => write_path, + None => return Ok(()), + }; + + let (mut addresses, choice) = { + let inner = self.inner.lock().unwrap(); + (inner.addresses.clone(), inner.choice) + }; - file.write_all(contents.as_bytes()).await?; - file.sync_data().await?; + // Place the current choice on top + if !addresses.is_empty() { + let addresses_len = addresses.len(); + addresses.swap(0, choice % addresses_len); } - Ok(()) + let temp_path = write_path.with_file_name("api-cache.temp"); + + let mut file = fs::File::create(&temp_path).await?; + let mut contents = addresses + .iter() + .map(ToString::to_string) + .collect::<Vec<String>>() + .join("\n"); + contents += "\n"; + file.write_all(contents.as_bytes()).await?; + file.sync_data().await?; + + fs::rename(&temp_path, write_path).await } } @@ -144,7 +193,7 @@ impl crate::rest::AddressProvider for AddressCache { struct AddressCacheInner { addresses: Vec<SocketAddr>, choice: usize, - last_try: Option<usize>, + tried_current: bool, } impl AddressCacheInner { @@ -152,19 +201,23 @@ impl AddressCacheInner { if addresses.is_empty() { return Err(Error::EmptyAddressCache); } - let mut cache = Self { + Ok(Self { addresses, choice: 0, - last_try: None, - }; - cache.shuffle(); - Ok(cache) + tried_current: false, + }) } fn shuffle(&mut self) { let mut rng = rand::thread_rng(); (&mut self.addresses[..]).shuffle(&mut rng); } + + /// Shuffle all but the first element + fn shuffle_tail(&mut self) { + let mut rng = rand::thread_rng(); + (&mut self.addresses[1..]).shuffle(&mut rng); + } } async fn read_address_file(path: &Path) -> Result<Vec<SocketAddr>, Error> { @@ -178,7 +231,6 @@ async fn read_address_file(path: &Path) -> Result<Vec<SocketAddr>, Error> { .await .map_err(|error| Error::ReadAddressCache(error))? { - // for line in lines.next_line() { match line.trim().parse() { Ok(address) => addresses.push(address), Err(err) => { diff --git a/mullvad-rpc/src/lib.rs b/mullvad-rpc/src/lib.rs index d92be6e8be..10c5ca74a8 100644 --- a/mullvad-rpc/src/lib.rs +++ b/mullvad-rpc/src/lib.rs @@ -69,31 +69,41 @@ impl MullvadRpcRuntime { /// if it fails. pub async fn with_cache( handle: tokio::runtime::Handle, - resource_dir: &Path, - cache_dir: Option<&Path>, + resource_dir: Option<&Path>, + cache_dir: &Path, + write_changes: bool, ) -> Result<Self, Error> { - let resource_file = resource_dir.join(API_IP_CACHE_FILENAME); + let cache_file = cache_dir.join(API_IP_CACHE_FILENAME); + let write_file = if write_changes { + Some(cache_file.clone().into_boxed_path()) + } else { + None + }; - let address_cache = if let Some(cache_dir) = cache_dir { - let cache_file = cache_dir.join(API_IP_CACHE_FILENAME); - let cache_file_boxed = cache_file.clone().into_boxed_path(); + let address_cache = match AddressCache::from_file(&cache_file, write_file.clone()).await { + Ok(cache) => cache, + Err(error) => { + let cache_exists = cache_file.exists(); + if cache_exists { + log::error!( + "{}", + error.display_chain_with_msg( + "Failed to load cached API addresses. Falling back on bundled list" + ) + ); + } - match AddressCache::from_file(&cache_file, Some(cache_file_boxed.clone())).await { - Ok(cache) => cache, - Err(error) => { - if cache_file.exists() { - log::error!( - "{}", - error.display_chain_with_msg( - "Failed to load cached API addresses. Falling back on bundled list" - ) - ); + // Initialize the cache directory cache using the resource directory + match resource_dir { + Some(resource_dir) => { + let read_file = resource_dir.join(API_IP_CACHE_FILENAME); + let cache = AddressCache::from_file(&read_file, write_file).await?; + cache.randomize().await?; + cache } - AddressCache::from_file(&resource_file, Some(cache_file_boxed)).await? + None => return Err(Error::AddressCacheError(error)), } } - } else { - AddressCache::from_file(&resource_file, None).await? }; let https_connector = HttpsConnectorWithSni::new(); diff --git a/mullvad-rpc/src/rest.rs b/mullvad-rpc/src/rest.rs index 2bf8511d24..12bc10263e 100644 --- a/mullvad-rpc/src/rest.rs +++ b/mullvad-rpc/src/rest.rs @@ -139,7 +139,20 @@ impl<C: Connect + Clone + Send + Sync + 'static> RequestService<C> { if let Err(err) = &response { match err { Error::HyperError(_) | Error::TimeoutError(_) => { - address_cache.register_failure(host_addr, err); + let current_address = address_cache.peek_address(); + if current_address == host_addr + && address_cache.has_tried_current_address() + { + address_cache.select_new_address().await; + let new_address = address_cache.peek_address(); + + log::error!( + "HTTP request failed: {}, using address {}. Trying next API address: {}", + err, + current_address, + new_address, + ); + } } _ => (), } diff --git a/mullvad-setup/src/daemon_paths.rs b/mullvad-setup/src/daemon_paths.rs index 6f00952703..fce81ede8c 100644 --- a/mullvad-setup/src/daemon_paths.rs +++ b/mullvad-setup/src/daemon_paths.rs @@ -15,9 +15,7 @@ use winapi::{ um::{ combaseapi::CoTaskMemFree, handleapi::CloseHandle, - knownfolders::{ - FOLDERID_LocalAppData, FOLDERID_ProgramFiles, FOLDERID_RoamingAppData, FOLDERID_System, - }, + knownfolders::{FOLDERID_LocalAppData, FOLDERID_System}, processthreadsapi::{GetCurrentThread, OpenProcess, OpenProcessToken, OpenThreadToken}, psapi::K32EnumProcesses, securitybaseapi::{AdjustTokenPrivileges, ImpersonateSelf, RevertToSelf}, @@ -37,16 +35,6 @@ pub fn get_mullvad_daemon_settings_path() -> io::Result<PathBuf> { .map(|settings| settings.join(mullvad_paths::PRODUCT_NAME)) } -pub fn get_mullvad_resource_path() -> io::Result<PathBuf> { - get_known_folder_path(FOLDERID_ProgramFiles, KF_FLAG_DEFAULT, ptr::null_mut()) - .map(|settings| settings.join(mullvad_paths::PRODUCT_NAME).join("resources")) -} - -pub fn get_mullvad_daemon_cache_path() -> io::Result<PathBuf> { - get_system_service_known_folder(FOLDERID_RoamingAppData) - .map(|settings| settings.join(mullvad_paths::PRODUCT_NAME)) -} - /// Get local AppData path for the system service user. Requires elevated privileges to work. /// Useful for deducing the config path for the daemon on Windows when running as a user that diff --git a/mullvad-setup/src/main.rs b/mullvad-setup/src/main.rs index 2e109089a4..7afb1fad16 100644 --- a/mullvad-setup/src/main.rs +++ b/mullvad-setup/src/main.rs @@ -24,11 +24,11 @@ enum ExitStatus { #[cfg(windows)] mod daemon_paths; -#[cfg(not(windows))] -type PathError = mullvad_paths::Error; - #[cfg(windows)] -type PathError = std::io::Error; +type SettingsPathErrorType = std::io::Error; + +#[cfg(not(windows))] +type SettingsPathErrorType = mullvad_paths::Error; #[derive(err_derive::Error, Debug)] #[error(no_from)] @@ -49,14 +49,10 @@ pub enum Error { RpcInitializationError(#[error(source)] mullvad_rpc::Error), #[error(display = "Failed to obtain settings directory path")] - SettingsPathError(#[error(source)] PathError), - - #[cfg(windows)] - #[error(display = "Failed to obtain resource directory path")] - ResourcePathError(#[error(source)] PathError), + SettingsPathError(#[error(source)] SettingsPathErrorType), #[error(display = "Failed to obtain cache directory path")] - CachePathError(#[error(source)] PathError), + CachePathError(#[error(source)] mullvad_paths::Error), #[error(display = "Failed to initialize account history")] InitializeAccountHistoryError(#[error(source)] account_history::Error), @@ -155,18 +151,19 @@ async fn reset_firewall() -> Result<(), Error> { } async fn clear_history() -> Result<(), Error> { - let (cache_path, resource_path, settings_path) = get_paths()?; + let (user_cache_path, settings_path) = get_paths()?; let mut rpc_runtime = MullvadRpcRuntime::with_cache( tokio::runtime::Handle::current(), - &resource_path, - Some(&cache_path), + None, + &user_cache_path, + false, ) .await .map_err(Error::RpcInitializationError)?; let mut account_history = account_history::AccountHistory::new( - &cache_path, + &user_cache_path, &settings_path, rpc_runtime.mullvad_rest_handle(), ) @@ -180,21 +177,16 @@ async fn clear_history() -> Result<(), Error> { } #[cfg(not(windows))] -fn get_paths() -> Result<(PathBuf, PathBuf, PathBuf), Error> { - let cache_path = mullvad_paths::cache_dir().map_err(Error::CachePathError)?; - let resource_path = mullvad_paths::get_resource_dir(); +fn get_paths() -> Result<(PathBuf, PathBuf), Error> { + let user_cache_path = mullvad_paths::user_cache_dir().map_err(Error::CachePathError)?; let settings_path = mullvad_paths::settings_dir().map_err(Error::SettingsPathError)?; - Ok((cache_path, resource_path, settings_path)) + Ok((user_cache_path, settings_path)) } #[cfg(windows)] -fn get_paths() -> Result<(PathBuf, PathBuf, PathBuf), Error> { +fn get_paths() -> Result<(PathBuf, PathBuf), Error> { + let user_cache_path = mullvad_paths::user_cache_dir().map_err(Error::CachePathError)?; let settings_path = - daemon_paths::get_mullvad_daemon_settings_path().map_err(Error::CachePathError)?; - let resource_path = - daemon_paths::get_mullvad_resource_path().map_err(Error::ResourcePathError)?; - let cache_path = - daemon_paths::get_mullvad_daemon_cache_path().map_err(Error::SettingsPathError)?; - - Ok((cache_path, resource_path, settings_path)) + daemon_paths::get_mullvad_daemon_settings_path().map_err(Error::SettingsPathError)?; + Ok((user_cache_path, settings_path)) } diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.cpp b/windows/nsis-plugins/src/cleanup/cleaningops.cpp index 475c78d8b7..1a711bf3d8 100644 --- a/windows/nsis-plugins/src/cleanup/cleaningops.cpp +++ b/windows/nsis-plugins/src/cleanup/cleaningops.cpp @@ -333,14 +333,14 @@ void RemoveRelayCacheServiceUser() void RemoveApiAddressCacheServiceUser() { - const auto localAppData = GetSystemUserLocalAppData(); - const auto mullvadAppData = std::filesystem::path(localAppData).append(L"Mullvad VPN"); + const auto programData = common::fs::GetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr); + const auto mullvadProgramData = std::filesystem::path(programData).append(L"Mullvad VPN"); common::fs::ScopedNativeFileSystem nativeFileSystem; - common::security::AddAdminToObjectDacl(mullvadAppData, SE_FILE_OBJECT); + common::security::AddAdminToObjectDacl(mullvadProgramData, SE_FILE_OBJECT); - const auto cacheFile = std::filesystem::path(mullvadAppData).append(L"api-ip-address.txt"); + const auto cacheFile = std::filesystem::path(mullvadProgramData).append(L"api-ip-address.txt"); std::filesystem::remove(cacheFile); } |
