diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-05-24 13:50:11 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-05-29 12:55:01 +0200 |
| commit | 461bb179af039b2ab9622f8df2c2bffd09a21b77 (patch) | |
| tree | 38f67fdda816084a54d888d3f4df0a5d3754e85a | |
| parent | 2b04fed8d6a486d97af47f1add45b0eeb1071db8 (diff) | |
| download | mullvadvpn-461bb179af039b2ab9622f8df2c2bffd09a21b77.tar.xz mullvadvpn-461bb179af039b2ab9622f8df2c2bffd09a21b77.zip | |
Add error state cause for full disk permissions error
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 6 | ||||
| -rw-r--r-- | gui/src/shared/notifications/error.ts | 17 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 1 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/states.rs | 10 | ||||
| -rw-r--r-- | talpid-core/src/split_tunnel/macos/mod.rs | 17 | ||||
| -rw-r--r-- | talpid-core/src/split_tunnel/macos/process.rs | 10 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 6 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 6 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 8 | ||||
| -rw-r--r-- | talpid-types/src/tunnel.rs | 5 |
10 files changed, 64 insertions, 22 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 10e39f020d..c51524f1ee 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -1046,6 +1046,12 @@ function convertFromTunnelStateError(state: grpcTypes.ErrorState.AsObject): Erro ...baseError, cause: ErrorStateCause.splitTunnelError, }; + case grpcTypes.ErrorState.Cause.NEED_FULL_DISK_PERMISSIONS: + // TODO: handle correctly + return { + ...baseError, + cause: ErrorStateCause.splitTunnelError, + }; case grpcTypes.ErrorState.Cause.VPN_PERMISSION_DENIED: // VPN_PERMISSION_DENIED is only ever created on Android throw invalidErrorStateCause; diff --git a/gui/src/shared/notifications/error.ts b/gui/src/shared/notifications/error.ts index 673d6cea28..1d36b7e1de 100644 --- a/gui/src/shared/notifications/error.ts +++ b/gui/src/shared/notifications/error.ts @@ -183,10 +183,18 @@ function getMessage(errorState: ErrorState): string { 'Your device is offline. The tunnel will automatically connect once your device is back online.', ); case ErrorStateCause.splitTunnelError: - return messages.pgettext( - 'notifications', - 'Unable to communicate with Mullvad kernel driver. Try reconnecting or send a problem report.', - ); + switch (process.platform ?? window.env.platform) { + case 'darwin': + return messages.pgettext( + 'notifications', + 'Failed to enable split tunneling. Please try again or disable it.', + ); + default: + return messages.pgettext( + 'notifications', + 'Unable to communicate with Mullvad kernel driver. Try reconnecting or send a problem report.', + ); + } } } } @@ -265,6 +273,7 @@ function getActions(errorState: ErrorState): InAppNotificationAction | void { }, }; } else if (errorState.cause === ErrorStateCause.splitTunnelError) { + // TODO: macos: handle this and full disk access error return { type: 'troubleshoot-dialog', troubleshoot: { diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index efe9f9eb87..3f9de9b189 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -142,6 +142,7 @@ message ErrorState { IS_OFFLINE = 7; VPN_PERMISSION_DENIED = 8; SPLIT_TUNNEL_ERROR = 9; + NEED_FULL_DISK_PERMISSIONS = 10; } enum AuthFailedError { diff --git a/mullvad-management-interface/src/types/conversions/states.rs b/mullvad-management-interface/src/types/conversions/states.rs index 881cbc6c9a..58766a9925 100644 --- a/mullvad-management-interface/src/types/conversions/states.rs +++ b/mullvad-management-interface/src/types/conversions/states.rs @@ -107,6 +107,10 @@ impl From<mullvad_types::states::TunnelState> for proto::TunnelState { talpid_tunnel::ErrorStateCause::SplitTunnelError => { i32::from(Cause::SplitTunnelError) } + #[cfg(target_os = "macos")] + talpid_tunnel::ErrorStateCause::NeedFullDiskPermissions => { + i32::from(Cause::NeedFullDiskPermissions) + } }, blocking_error: error_state.block_failure().map(map_firewall_error), auth_failed_error: mullvad_types::auth_failed::AuthFailed::try_from( @@ -325,10 +329,14 @@ impl TryFrom<proto::TunnelState> for mullvad_types::states::TunnelState { Ok(proto::error_state::Cause::VpnPermissionDenied) => { talpid_tunnel::ErrorStateCause::VpnPermissionDenied } - #[cfg(target_os = "windows")] + #[cfg(any(target_os = "windows", target_os = "macos"))] Ok(proto::error_state::Cause::SplitTunnelError) => { talpid_tunnel::ErrorStateCause::SplitTunnelError } + #[cfg(target_os = "macos")] + Ok(proto::error_state::Cause::NeedFullDiskPermissions) => { + talpid_tunnel::ErrorStateCause::NeedFullDiskPermissions + } _ => { return Err(FromProtobufTypeError::InvalidArgument( "invalid error cause", diff --git a/talpid-core/src/split_tunnel/macos/mod.rs b/talpid-core/src/split_tunnel/macos/mod.rs index 980097d94b..d43c124043 100644 --- a/talpid-core/src/split_tunnel/macos/mod.rs +++ b/talpid-core/src/split_tunnel/macos/mod.rs @@ -42,6 +42,16 @@ impl Error { } } +impl From<&Error> for ErrorStateCause { + fn from(value: &Error) -> Self { + match value { + Error::Process(error) => ErrorStateCause::from(error), + _v if _v.is_offline() => ErrorStateCause::IsOffline, + _ => ErrorStateCause::SplitTunnelError, + } + } +} + /// Split tunneling actor pub struct SplitTunnel { state: State, @@ -171,6 +181,10 @@ impl SplitTunnel { /// Handle process monitor unexpectedly stopping fn handle_process_monitor_shutdown(&mut self, result: Result<(), process::Error>) { + let cause = match result { + Ok(_) => ErrorStateCause::SplitTunnelError, + Err(ref error) => ErrorStateCause::from(error), + }; match result { Ok(()) => log::error!("Process monitor stopped unexpectedly with no error"), Err(error) => { @@ -185,8 +199,7 @@ impl SplitTunnel { // decisions for new processes if self.state.active() { if let Some(tunnel_tx) = self.tunnel_tx.upgrade() { - let _ = tunnel_tx - .unbounded_send(TunnelCommand::Block(ErrorStateCause::SplitTunnelError)); + let _ = tunnel_tx.unbounded_send(TunnelCommand::Block(cause)); } } diff --git a/talpid-core/src/split_tunnel/macos/process.rs b/talpid-core/src/split_tunnel/macos/process.rs index f913b9bb49..013aca34e4 100644 --- a/talpid-core/src/split_tunnel/macos/process.rs +++ b/talpid-core/src/split_tunnel/macos/process.rs @@ -21,6 +21,7 @@ use std::{ time::Duration, }; use talpid_platform_metadata::MacosVersion; +use talpid_types::tunnel::ErrorStateCause; use tokio::io::{AsyncBufReadExt, BufReader}; const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(3); @@ -56,6 +57,15 @@ pub enum Error { FindProcessPath(#[source] io::Error, u32), } +impl From<&Error> for ErrorStateCause { + fn from(value: &Error) -> Self { + match value { + Error::NeedFullDiskPermissions => ErrorStateCause::NeedFullDiskPermissions, + _ => ErrorStateCause::SplitTunnelError, + } + } +} + pub struct ProcessMonitor(()); #[derive(Debug)] diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 80ca26ec56..395a67a057 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -353,11 +353,9 @@ impl ConnectedState { } } Err(error) => { + let cause = ErrorStateCause::from(&error); let _ = result_tx.send(Err(error)); - return self.disconnect( - shared_values, - AfterDisconnect::Block(ErrorStateCause::SplitTunnelError), - ); + return self.disconnect(shared_values, AfterDisconnect::Block(cause)); } } SameState(self) diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 5df58a6adf..a4267d0d56 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -498,11 +498,9 @@ impl ConnectingState { } } Err(error) => { + let cause = ErrorStateCause::from(&error); let _ = result_tx.send(Err(error)); - return self.disconnect( - shared_values, - AfterDisconnect::Block(ErrorStateCause::SplitTunnelError), - ); + return self.disconnect(shared_values, AfterDisconnect::Block(cause)); } } SameState(self) diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index e31dec3624..a74d7e39b5 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -540,13 +540,7 @@ impl SharedTunnelStateValues { error.display_chain_with_msg("Failed to set VPN interface for split tunnel") ) }) - .map_err(|error| { - if error.is_offline() { - ErrorStateCause::IsOffline - } else { - ErrorStateCause::SplitTunnelError - } - }) + .map_err(|error| ErrorStateCause::from(&error)) } pub fn set_allow_lan(&mut self, allow_lan: bool) -> Result<(), ErrorStateCause> { diff --git a/talpid-types/src/tunnel.rs b/talpid-types/src/tunnel.rs index e67db2f0c4..686f7ae19a 100644 --- a/talpid-types/src/tunnel.rs +++ b/talpid-types/src/tunnel.rs @@ -110,6 +110,9 @@ pub enum ErrorStateCause { /// Error reported by split tunnel module. #[cfg(any(target_os = "windows", target_os = "macos"))] SplitTunnelError, + /// Missing permissions required by macOS split tunneling. + #[cfg(target_os = "macos")] + NeedFullDiskPermissions, } impl ErrorStateCause { @@ -217,6 +220,8 @@ impl fmt::Display for ErrorStateCause { VpnPermissionDenied => "The Android VPN permission was denied when creating the tunnel", #[cfg(any(target_os = "windows", target_os = "macos"))] SplitTunnelError => "The split tunneling module reported an error", + #[cfg(target_os = "macos")] + NeedFullDiskPermissions => "Need full disk access to enable split tunneling", }; write!(f, "{description}") |
