diff options
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 10 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 107 | ||||
| -rw-r--r-- | mullvad-types/src/settings.rs | 4 |
3 files changed, 112 insertions, 9 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 6b3c061398..b3aa513f6e 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -18,6 +18,7 @@ pub mod logging; mod management_interface; mod relays; mod rpc_uniqueness_check; +mod settings; pub mod version; pub use crate::management_interface::ManagementCommand; @@ -40,10 +41,10 @@ use mullvad_types::{ RelayConstraintsUpdate, RelaySettings, RelaySettingsUpdate, TunnelConstraints, }, relay_list::{Relay, RelayList}, - settings::{self, Settings}, states::TargetState, version::{AppVersion, AppVersionInfo}, }; +use settings::Settings; use std::{io, mem, path::PathBuf, sync::mpsc, thread, time::Duration}; use talpid_core::{ mpsc::IntoSender, @@ -75,9 +76,6 @@ pub enum Error { #[error(display = "Unable to create am.i.mullvad client")] InitHttpsClient(#[error(cause)] mullvad_rpc::rest::Error), - #[error(display = "Unable to load settings")] - LoadSettings(#[error(cause)] settings::Error), - #[error(display = "Unable to load account history with wireguard key cache")] LoadAccountHistory(#[error(cause)] account_history::Error), @@ -340,7 +338,9 @@ where &resource_dir, &cache_dir, ); - let settings = Settings::load().map_err(Error::LoadSettings)?; + + let settings = settings::load(); + let account_history = account_history::AccountHistory::new(&cache_dir).map_err(Error::LoadAccountHistory)?; diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs new file mode 100644 index 0000000000..6aeee0223c --- /dev/null +++ b/mullvad-daemon/src/settings.rs @@ -0,0 +1,107 @@ +#[cfg(windows)] +use log::{error, warn}; + +use log::info; + +#[cfg(windows)] +use mullvad_types::settings::Error as SettingsError; + +pub use mullvad_types::settings::*; + +#[cfg(windows)] +use std::io::ErrorKind; + +#[cfg(windows)] +use std::{ + os::raw::{c_char, c_void}, + ptr, +}; + +pub fn load() -> Settings { + match Settings::load() { + Ok(settings) => settings, + #[cfg(windows)] + Err(SettingsError::ReadError(ref _path, ref e)) if e.kind() == ErrorKind::NotFound => { + info!( + "No settings file found. Attempting migration from Windows Update backup location" + ); + if migrate_after_windows_update() { + match Settings::load() { + Ok(settings) => { + info!("Successfully loaded migrated settings"); + settings + } + Err(_) => { + warn!("Failed to load migrated settings, using defaults"); + Settings::default() + } + } + } else { + info!("Failed to migrate settings, using defaults"); + Settings::default() + } + } + Err(_) => { + info!("Failed to load settings, using defaults"); + Settings::default() + } + } +} + +#[cfg(windows)] +fn migrate_after_windows_update() -> bool { + match unsafe { ffi::WinUtil_MigrateAfterWindowsUpdate(Some(log_sink), ptr::null_mut()) } { + ffi::WinUtilMigrationStatus::Success => { + info!("Migration completed successfully"); + true + } + ffi::WinUtilMigrationStatus::Aborted => { + error!("Migration was aborted to avoid overwriting current settings"); + false + } + ffi::WinUtilMigrationStatus::NothingToMigrate => { + info!("Could not migrate settings - no backup present"); + false + } + ffi::WinUtilMigrationStatus::Failed | _ => { + error!("Migration failed"); + false + } + } +} + +#[cfg(windows)] +extern "system" fn log_sink(msg: *const c_char, _ctx: *mut c_void) { + use std::ffi::CStr; + if msg.is_null() { + error!("Log message from FFI boundary is NULL"); + } else { + error!("{}", unsafe { CStr::from_ptr(msg).to_string_lossy() }); + } +} + +#[cfg(windows)] +mod ffi { + use super::*; + + #[allow(dead_code)] + #[repr(u32)] + pub enum WinUtilMigrationStatus { + Success = 0, + Aborted = 1, + NothingToMigrate = 2, + Failed = 3, + Dummy = 9001, + } + + type ErrorSink = extern "system" fn(msg: *const c_char, ctx: *mut c_void); + + #[allow(non_snake_case)] + extern "system" { + #[link_name = "WinUtil_MigrateAfterWindowsUpdate"] + pub fn WinUtil_MigrateAfterWindowsUpdate( + sink: Option<ErrorSink>, + sink_context: *mut c_void, + ) -> WinUtilMigrationStatus; + } +} diff --git a/mullvad-types/src/settings.rs b/mullvad-types/src/settings.rs index 10e5b03298..41f280c973 100644 --- a/mullvad-types/src/settings.rs +++ b/mullvad-types/src/settings.rs @@ -84,10 +84,6 @@ impl Settings { info!("Loading settings from {}", path.display()); Self::read_settings(&mut io::BufReader::new(file)) } - Err(ref e) if e.kind() == io::ErrorKind::NotFound => { - info!("No settings file at {}, using defaults", path.display()); - Ok(Settings::default()) - } Err(e) => Err(Error::ReadError(path.display().to_string(), e)), } } |
