Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove block_when_disconnected setting on Android #7007

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub enum DaemonCommand {
/// Set the beta program setting.
SetShowBetaReleases(ResponseTx<(), settings::Error>, bool),
/// Set the block_when_disconnected setting.
#[cfg(not(target_os = "android"))]
SetBlockWhenDisconnected(ResponseTx<(), settings::Error>, bool),
/// Set the auto-connect setting.
SetAutoConnect(ResponseTx<(), settings::Error>, bool),
Expand Down Expand Up @@ -757,6 +758,7 @@ impl Daemon {
let tunnel_state_machine_handle = tunnel_state_machine::spawn(
tunnel_state_machine::InitialTunnelState {
allow_lan: settings.allow_lan,
#[cfg(not(target_os = "android"))]
block_when_disconnected: settings.block_when_disconnected,
dns_config: dns::addresses_from_options(&settings.tunnel_options.dns_options),
allowed_endpoint: access_mode_handler
Expand Down Expand Up @@ -820,6 +822,7 @@ impl Daemon {
let daemon = Daemon {
tunnel_state: TunnelState::Disconnected {
location: None,
#[cfg(not(target_os = "android"))]
locked_down: settings.block_when_disconnected,
},
target_state,
Expand Down Expand Up @@ -979,10 +982,13 @@ impl Daemon {
.handle_state_transition(&tunnel_state_transition);

let tunnel_state = match tunnel_state_transition {
#[cfg(not(target_os = "android"))]
TunnelStateTransition::Disconnected { locked_down } => TunnelState::Disconnected {
location: None,
locked_down,
},
#[cfg(target_os = "android")]
TunnelStateTransition::Disconnected => TunnelState::Disconnected { location: None },
TunnelStateTransition::Connecting(endpoint) => {
let feature_indicators = compute_feature_indicators(
&self.settings.to_settings(),
Expand Down Expand Up @@ -1119,7 +1125,8 @@ impl Daemon {
match self.tunnel_state {
TunnelState::Disconnected {
ref mut location,
locked_down: _,
#[cfg(not(target_os = "android"))]
locked_down: _,
} => *location = Some(fetched_location),
TunnelState::Connected {
ref mut location, ..
Expand Down Expand Up @@ -1243,6 +1250,7 @@ impl Daemon {
SetRelaySettings(tx, update) => self.on_set_relay_settings(tx, update).await,
SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan).await,
SetShowBetaReleases(tx, enabled) => self.on_set_show_beta_releases(tx, enabled).await,
#[cfg(not(target_os = "android"))]
SetBlockWhenDisconnected(tx, block_when_disconnected) => {
self.on_set_block_when_disconnected(tx, block_when_disconnected)
.await
Expand Down Expand Up @@ -2118,6 +2126,7 @@ impl Daemon {
}
}

#[cfg(not(target_os = "android"))]
async fn on_set_block_when_disconnected(
&mut self,
tx: ResponseTx<(), settings::Error>,
Expand Down Expand Up @@ -2796,11 +2805,14 @@ impl Daemon {
self.send_tunnel_command(TunnelCommand::SetExcludedApps(tx, vec![]));
}

let (tx, _rx) = oneshot::channel();
self.send_tunnel_command(TunnelCommand::BlockWhenDisconnected(
self.settings.block_when_disconnected,
tx,
));
#[cfg(not(target_os = "android"))]
{
let (tx, _rx) = oneshot::channel();
self.send_tunnel_command(TunnelCommand::BlockWhenDisconnected(
self.settings.block_when_disconnected,
tx,
));
}

let (tx, _rx) = oneshot::channel();
self.send_tunnel_command(TunnelCommand::AllowLan(self.settings.allow_lan, tx));
Expand Down Expand Up @@ -2842,9 +2854,11 @@ impl Daemon {
}
}

#[cfg_attr(target_os = "android", allow(unused_variables))]
fn on_trigger_shutdown(&mut self, user_init_shutdown: bool) {
// Block all traffic before shutting down to ensure that no traffic can leak on boot or
// shutdown.
#[cfg(not(target_os = "android"))]
if !user_init_shutdown
&& (*self.target_state == TargetState::Secured || self.settings.auto_connect)
{
Expand All @@ -2863,7 +2877,7 @@ impl Daemon {
fn on_prepare_restart(&mut self, shutdown: bool) {
// TODO: See if this can be made to also shut down the daemon
// without causing the service to be restarted.

#[cfg(not(target_os = "android"))]
if *self.target_state == TargetState::Secured {
let (tx, _rx) = oneshot::channel();
self.send_tunnel_command(TunnelCommand::BlockWhenDisconnected(true, tx));
Expand Down
9 changes: 9 additions & 0 deletions mullvad-daemon/src/management_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ impl ManagementService for ManagementServiceImpl {
Ok(Response::new(()))
}

#[cfg(not(target_os = "android"))]
async fn set_block_when_disconnected(&self, request: Request<bool>) -> ServiceResult<()> {
let block_when_disconnected = request.into_inner();
log::debug!("set_block_when_disconnected({})", block_when_disconnected);
Expand All @@ -285,6 +286,14 @@ impl ManagementService for ManagementServiceImpl {
Ok(Response::new(()))
}

#[cfg(target_os = "android")]
async fn set_block_when_disconnected(&self, request: Request<bool>) -> ServiceResult<()> {
let block_when_disconnected = request.into_inner();
log::debug!("set_block_when_disconnected({})", block_when_disconnected);
log::warn!("Setting Lockdown mode on Android is not supported - this is handled by the OS, not the daemon");
Ok(Response::new(()))
}

async fn set_auto_connect(&self, request: Request<bool>) -> ServiceResult<()> {
let auto_connect = request.into_inner();
log::debug!("set_auto_connect({})", auto_connect);
Expand Down
22 changes: 10 additions & 12 deletions mullvad-daemon/src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@ impl SettingsPersister {

// Auto-connect is managed by Android itself.
settings.auto_connect = false;

// Lockdown mode is managed by the Android OS.
settings.block_when_disconnected = false;
}
if crate::version::is_beta_version() {
should_save |= !settings.show_beta_releases;
Expand Down Expand Up @@ -171,15 +168,16 @@ impl SettingsPersister {
"{}",
error.display_chain_with_msg("Failed to load settings. Using defaults.")
);
let mut settings = Self::default_settings();

// Protect the user by blocking the internet by default. Previous settings may
// not have caused the daemon to enter the non-blocking disconnected state.
// On android lockdown mode is handled by the OS so setting this to true
// has no effect.
if cfg!(not(target_os = "android")) {
settings.block_when_disconnected = true;
}

let settings = Settings {
// Protect the user by blocking the internet by default. Previous settings may
// not have caused the daemon to enter the non-blocking disconnected state.
// On android lockdown mode is handled by the OS so setting this to true
// has no effect.
#[cfg(not(target_os = "android"))]
block_when_disconnected: true,
..Self::default_settings()
};

LoadSettingsResult {
settings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ impl From<&mullvad_types::settings::Settings> for proto::Settings {
)),
bridge_state: Some(proto::BridgeState::from(settings.bridge_state)),
allow_lan: settings.allow_lan,
#[cfg(not(target_os = "android"))]
block_when_disconnected: settings.block_when_disconnected,
#[cfg(target_os = "android")]
block_when_disconnected: false,
auto_connect: settings.auto_connect,
tunnel_options: Some(proto::TunnelOptions::from(&settings.tunnel_options)),
show_beta_releases: settings.show_beta_releases,
Expand Down Expand Up @@ -175,6 +178,7 @@ impl TryFrom<proto::Settings> for mullvad_types::settings::Settings {
)?,
bridge_state,
allow_lan: settings.allow_lan,
#[cfg(not(target_os = "android"))]
block_when_disconnected: settings.block_when_disconnected,
auto_connect: settings.auto_connect,
tunnel_options: mullvad_types::settings::TunnelOptions::try_from(tunnel_options)?,
Expand Down
6 changes: 6 additions & 0 deletions mullvad-management-interface/src/types/conversions/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ impl From<mullvad_types::states::TunnelState> for proto::TunnelState {
let state = match state {
MullvadTunnelState::Disconnected {
location: disconnected_location,
#[cfg(not(target_os = "android"))]
locked_down,
} => proto::tunnel_state::State::Disconnected(proto::tunnel_state::Disconnected {
disconnected_location: disconnected_location.map(proto::GeoIpLocation::from),
#[cfg(not(target_os = "android"))]
locked_down,
#[cfg(target_os = "android")]
locked_down: false,
}),
MullvadTunnelState::Connecting {
endpoint,
Expand Down Expand Up @@ -224,13 +228,15 @@ impl TryFrom<proto::TunnelState> for mullvad_types::states::TunnelState {
use talpid_types::{net as talpid_net, tunnel as talpid_tunnel};

let state = match state.state {
#[cfg_attr(target_os = "android", allow(unused_variables))]
Some(proto::tunnel_state::State::Disconnected(proto::tunnel_state::Disconnected {
disconnected_location,
locked_down,
})) => MullvadState::Disconnected {
location: disconnected_location
.map(mullvad_types::location::GeoIpLocation::try_from)
.transpose()?,
#[cfg(not(target_os = "android"))]
locked_down,
},
Some(proto::tunnel_state::State::Connecting(proto::tunnel_state::Connecting {
Expand Down
4 changes: 3 additions & 1 deletion mullvad-types/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub fn compute_feature_indicators(
#[cfg(not(any(windows, target_os = "android", target_os = "macos")))]
let split_tunneling = false;

#[cfg(not(target_os = "android"))]
let lockdown_mode = settings.block_when_disconnected;
let lan_sharing = settings.allow_lan;
let dns_content_blockers = settings
Expand All @@ -138,11 +139,12 @@ pub fn compute_feature_indicators(

let generic_features = [
(split_tunneling, FeatureIndicator::SplitTunneling),
(lockdown_mode, FeatureIndicator::LockdownMode),
(lan_sharing, FeatureIndicator::LanSharing),
(dns_content_blockers, FeatureIndicator::DnsContentBlockers),
(custom_dns, FeatureIndicator::CustomDns),
(server_ip_override, FeatureIndicator::ServerIpOverride),
#[cfg(not(target_os = "android"))]
(lockdown_mode, FeatureIndicator::LockdownMode),
];

// Pick protocol-specific features and whether they are currently enabled.
Expand Down
2 changes: 2 additions & 0 deletions mullvad-types/src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub struct Settings {
pub allow_lan: bool,
/// Extra level of kill switch. When this setting is on, the disconnected state will block
/// the firewall to not allow any traffic in or out.
#[cfg(not(target_os = "android"))]
pub block_when_disconnected: bool,
/// If the daemon should connect the VPN tunnel directly on start or not.
pub auto_connect: bool,
Expand Down Expand Up @@ -200,6 +201,7 @@ impl Default for Settings {
custom_lists: CustomListsSettings::default(),
api_access_methods: access_method::Settings::default(),
allow_lan: false,
#[cfg(not(target_os = "android"))]
block_when_disconnected: false,
auto_connect: false,
tunnel_options: TunnelOptions::default(),
Expand Down
1 change: 1 addition & 0 deletions mullvad-types/src/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub enum TunnelState {
Disconnected {
location: Option<GeoIpLocation>,
/// Whether internet access is blocked due to lockdown mode
#[cfg(not(target_os = "android"))]
locked_down: bool,
},
Connecting {
Expand Down
1 change: 1 addition & 0 deletions talpid-core/src/tunnel_state_machine/connected_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ impl ConnectedState {
let _ = complete_tx.send(());
consequence
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(block_when_disconnected, complete_tx)) => {
shared_values.block_when_disconnected = block_when_disconnected;
let _ = complete_tx.send(());
Expand Down
1 change: 1 addition & 0 deletions talpid-core/src/tunnel_state_machine/connecting_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ impl ConnectingState {
let _ = complete_tx.send(());
consequence
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(block_when_disconnected, complete_tx)) => {
shared_values.block_when_disconnected = block_when_disconnected;
let _ = complete_tx.send(());
Expand Down
12 changes: 12 additions & 0 deletions talpid-core/src/tunnel_state_machine/disconnected_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{
ConnectingState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
TunnelCommandReceiver, TunnelState, TunnelStateTransition,
};
#[cfg(not(target_os = "android"))]
use crate::firewall::FirewallPolicy;
#[cfg(target_os = "macos")]
use crate::{dns, tunnel_state_machine::ErrorState};
Expand Down Expand Up @@ -55,6 +56,7 @@ impl DisconnectedState {
Self::construct_state_transition(shared_values)
}

#[cfg_attr(target_os = "android", allow(unused_variables))]
fn construct_state_transition(
shared_values: &mut SharedTunnelStateValues,
) -> (Box<dyn TunnelState>, TunnelStateTransition) {
Expand All @@ -63,11 +65,13 @@ impl DisconnectedState {
TunnelStateTransition::Disconnected {
// Being disconnected and having lockdown mode enabled implies that your internet
// access is locked down
#[cfg(not(target_os = "android"))]
locked_down: shared_values.block_when_disconnected,
},
)
}

#[cfg(not(target_os = "android"))]
fn set_firewall_policy(
shared_values: &mut SharedTunnelStateValues,
should_reset_firewall: bool,
Expand Down Expand Up @@ -98,6 +102,13 @@ impl DisconnectedState {
}
}

// NOTE: There is no firewall on Android, so it is pointless to pretend to enforce firewall
// policies by calling a bunch of functions that will end up being a no-op. The proper
// long-term fix would be to remove the firewall module completely,
// but I leave this for a future developer to clean up.
#[cfg(target_os = "android")]
fn set_firewall_policy(_: &mut SharedTunnelStateValues, _: bool) {}

#[cfg(windows)]
fn register_split_tunnel_addresses(
shared_values: &mut SharedTunnelStateValues,
Expand Down Expand Up @@ -173,6 +184,7 @@ impl TunnelState for DisconnectedState {
let _ = complete_tx.send(());
SameState(self)
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(block_when_disconnected, complete_tx)) => {
if shared_values.block_when_disconnected != block_when_disconnected {
shared_values.block_when_disconnected = block_when_disconnected;
Expand Down
3 changes: 3 additions & 0 deletions talpid-core/src/tunnel_state_machine/disconnecting_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ impl DisconnectingState {
let _ = complete_tx.send(());
AfterDisconnect::Nothing
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(
block_when_disconnected,
complete_tx,
Expand Down Expand Up @@ -109,6 +110,7 @@ impl DisconnectingState {
let _ = complete_tx.send(());
AfterDisconnect::Block(reason)
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(
block_when_disconnected,
complete_tx,
Expand Down Expand Up @@ -167,6 +169,7 @@ impl DisconnectingState {
let _ = complete_tx.send(());
AfterDisconnect::Reconnect(retry_attempt)
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(
block_when_disconnected,
complete_tx,
Expand Down
1 change: 1 addition & 0 deletions talpid-core/src/tunnel_state_machine/error_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ impl TunnelState for ErrorState {
let _ = complete_tx.send(());
consequence
}
#[cfg(not(target_os = "android"))]
Some(TunnelCommand::BlockWhenDisconnected(block_when_disconnected, complete_tx)) => {
shared_values.block_when_disconnected = block_when_disconnected;
let _ = complete_tx.send(());
Expand Down
Loading
Loading