summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2019-06-18 10:04:08 +0200
committerOdd Stranne <odd@mullvad.net>2019-06-26 11:57:31 +0200
commiteb2a4702980c8d0ed7190d26cfcf7cfaac3674b9 (patch)
treea4417af2313cde21165e473a4f4eb5cf6aaa6f86
parent25a9780ce403fbb0589592e07740e752ef199d12 (diff)
downloadmullvadvpn-eb2a4702980c8d0ed7190d26cfcf7cfaac3674b9.tar.xz
mullvadvpn-eb2a4702980c8d0ed7190d26cfcf7cfaac3674b9.zip
Integrate Windows Update settings migrator in Daemon
-rw-r--r--mullvad-daemon/src/lib.rs10
-rw-r--r--mullvad-daemon/src/settings.rs107
-rw-r--r--mullvad-types/src/settings.rs4
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)),
}
}