summaryrefslogtreecommitdiffhomepage
path: root/mullvad-daemon/src
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2023-12-22 11:50:55 +0100
committerMarkus Pettersson <markus.pettersson@mullvad.net>2024-01-03 09:43:12 +0100
commit2fda59b1164e3d2a627cd3fd5960c2d7e0abb848 (patch)
tree19abe0cb48d8b9b9a898230b8798fe8e3d0d1e13 /mullvad-daemon/src
parent4e424284c511e646fb81d256b2ba8fa4dc3d08f9 (diff)
downloadmullvadvpn-2fda59b1164e3d2a627cd3fd5960c2d7e0abb848.tar.xz
mullvadvpn-2fda59b1164e3d2a627cd3fd5960c2d7e0abb848.zip
Prevent the last access method from being disabled
Add proper checks around disabling the last enabled access method. If the daemon detects that any one access method update would cause the last enabled access method to become disabled, it will find & toggle the `Direct` access method setting to be enabled.
Diffstat (limited to 'mullvad-daemon/src')
-rw-r--r--mullvad-daemon/src/access_method.rs35
1 files changed, 25 insertions, 10 deletions
diff --git a/mullvad-daemon/src/access_method.rs b/mullvad-daemon/src/access_method.rs
index 028e54f462..3bea2c4c7d 100644
--- a/mullvad-daemon/src/access_method.rs
+++ b/mullvad-daemon/src/access_method.rs
@@ -81,7 +81,7 @@ where
) -> Result<(), Error> {
// Make sure that we are not trying to remove a built-in API access
// method
- let command = match self.settings.api_access_methods.find(&access_method) {
+ let command = match self.settings.api_access_methods.find_by_id(&access_method) {
Some(api_access_method) => {
if api_access_method.is_builtin() {
Err(Error::RemoveBuiltIn)
@@ -131,7 +131,7 @@ where
) -> Result<AccessMethodSetting, Error> {
self.settings
.api_access_methods
- .find(&access_method)
+ .find_by_id(&access_method)
.ok_or(Error::NoSuchMethod(access_method))
.cloned()
}
@@ -147,22 +147,37 @@ where
&mut self,
access_method_update: AccessMethodSetting,
) -> Result<(), Error> {
- // We have to be a bit careful. If we are about to disable the last
- // remaining enabled access method, we would cause an inconsistent state
- // in the daemon's settings. Therefore, we have to safeguard against
- // this by explicitly checking for & disallow any update which would
- // cause the last enabled access method to become disabled.
+ // If the currently active access method is updated, we need to re-set
+ // it after updating the settings.
let current = self.get_current_access_method().await?;
let mut command = Command::Nothing;
let settings_update = |settings: &mut Settings| {
- if let Some(access_method) = settings
- .api_access_methods
- .find_mut(&access_method_update.get_id())
+ let access_methods = &mut settings.api_access_methods;
+ if let Some(access_method) =
+ access_methods.find_by_id_mut(&access_method_update.get_id())
{
*access_method = access_method_update;
if access_method.get_id() == current.get_id() {
command = Command::Set(access_method.get_id())
}
+ // We have to be a bit careful. If we are about to disable the last
+ // remaining enabled access method, we would cause an inconsistent state
+ // in the daemon's settings. Therefore, we have to safeguard against
+ // this by explicitly checking for any update which would cause the last
+ // enabled access method to become disabled. In that case, we should
+ // re-enable the `Direct` access method.
+ if access_methods.collect_enabled().is_empty() {
+ if let Some(direct) = access_methods.get_direct() {
+ direct.enabled = true;
+ } else {
+ // If the `Direct` access method does not exist within the
+ // settings for some reason, the settings are in an
+ // inconsistent state. We don't have much choice but to
+ // reset these settings to their default value.
+ log::warn!("The built-in access methods can not be found. This might be due to a corrupt settings file");
+ *access_methods = access_method::Settings::default();
+ }
+ }
}
};