From 0d0d3b95ebdd8f1e2bbe7d3761314403f3b5f252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B6nnhager?= Date: Mon, 18 Nov 2024 11:01:29 +0100 Subject: [PATCH 1/2] Restart daemon when full-disk access message has been shown --- desktop/packages/mullvad-vpn/src/main/index.ts | 8 +++++--- desktop/packages/mullvad-vpn/src/main/tunnel-state.ts | 9 +++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/desktop/packages/mullvad-vpn/src/main/index.ts b/desktop/packages/mullvad-vpn/src/main/index.ts index c9067c78e218..57984b6092de 100644 --- a/desktop/packages/mullvad-vpn/src/main/index.ts +++ b/desktop/packages/mullvad-vpn/src/main/index.ts @@ -324,7 +324,7 @@ class ApplicationMain }; private onBeforeQuit = async (event: Electron.Event) => { - if (this.tunnelState.hasReceivedFullDiskAccessError) { + if (this.tunnelState.needFullDiskAccess) { await this.daemonRpc.prepareRestart(true); } @@ -832,8 +832,10 @@ class ApplicationMain splitTunneling!.removeApplicationFromCache(application); return Promise.resolve(); }); - IpcMainEventChannel.macOsSplitTunneling.handleNeedFullDiskPermissions(() => { - return this.daemonRpc.needFullDiskPermissions(); + IpcMainEventChannel.macOsSplitTunneling.handleNeedFullDiskPermissions(async () => { + const fullDiskState = await this.daemonRpc.needFullDiskPermissions(); + this.tunnelState.needFullDiskAccess = fullDiskState; + return fullDiskState; }); IpcMainEventChannel.app.handleQuit(() => this.disconnectAndQuit()); diff --git a/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts b/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts index 43ebe97ad6a8..b83b88a0f8ba 100644 --- a/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts +++ b/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts @@ -11,6 +11,8 @@ export interface TunnelStateHandlerDelegate { } export default class TunnelStateHandler { + public needFullDiskAccess = false; + // The current tunnel state private tunnelStateValue: TunnelState = { state: 'disconnected' }; // When pressing connect/disconnect/reconnect the app assumes what the next state will be before @@ -20,15 +22,10 @@ export default class TunnelStateHandler { // Scheduler for discarding the assumed next state. private tunnelStateFallbackScheduler = new Scheduler(); - private receivedFullDiskAccessError = false; - private lastKnownDisconnectedLocation: Partial | undefined; public constructor(private delegate: TunnelStateHandlerDelegate) {} - public get hasReceivedFullDiskAccessError() { - return this.receivedFullDiskAccessError; - } public get tunnelState() { return this.tunnelStateValue; } @@ -60,7 +57,7 @@ export default class TunnelStateHandler { public handleNewTunnelState(newState: TunnelState) { if (newState.state === 'error' && newState.details) { if (newState.details.cause === ErrorStateCause.needFullDiskPermissions) { - this.receivedFullDiskAccessError = true; + this.needFullDiskAccess = true; } } From 13aba42812fe251823c5ca4501bfdccb8d8e2239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20L=C3=B6nnhager?= Date: Tue, 19 Nov 2024 13:28:43 +0100 Subject: [PATCH 2/2] Move 'needFullDiskAccess' out of tunnel-state.ts --- .../packages/mullvad-vpn/src/main/index.ts | 23 +++++++++++++++---- .../mullvad-vpn/src/main/tunnel-state.ts | 10 +------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/desktop/packages/mullvad-vpn/src/main/index.ts b/desktop/packages/mullvad-vpn/src/main/index.ts index 57984b6092de..8f5c8cbb64f2 100644 --- a/desktop/packages/mullvad-vpn/src/main/index.ts +++ b/desktop/packages/mullvad-vpn/src/main/index.ts @@ -14,6 +14,7 @@ import { AccessMethodSetting, DaemonEvent, DeviceEvent, + ErrorStateCause, IRelayListWithEndpointData, ISettings, TunnelState, @@ -130,6 +131,10 @@ class ApplicationMain private currentApiAccessMethod?: AccessMethodSetting; + // If set to true, the GUI should restart the daemon when it exits. + // This is to make sure that the daemon is granted full-disk access. + private needFullDiskAccess = false; + public constructor() { this.daemonRpc = new DaemonRpc( new ConnectionObserver(this.onDaemonConnected, this.onDaemonDisconnected), @@ -324,7 +329,7 @@ class ApplicationMain }; private onBeforeQuit = async (event: Electron.Event) => { - if (this.tunnelState.needFullDiskAccess) { + if (this.needFullDiskAccess) { await this.daemonRpc.prepareRestart(true); } @@ -537,7 +542,7 @@ class ApplicationMain // fetch the tunnel state try { - this.tunnelState.handleNewTunnelState(await this.daemonRpc.getState()); + this.handleNewTunnelState(await this.daemonRpc.getState()); } catch (e) { const error = e as Error; log.error(`Failed to fetch the tunnel state: ${error.message}`); @@ -692,7 +697,7 @@ class ApplicationMain const daemonEventListener = new SubscriptionListener( (daemonEvent: DaemonEvent) => { if ('tunnelState' in daemonEvent) { - this.tunnelState.handleNewTunnelState(daemonEvent.tunnelState); + this.handleNewTunnelState(daemonEvent.tunnelState); } else if ('settings' in daemonEvent) { this.setSettings(daemonEvent.settings); } else if ('relayList' in daemonEvent) { @@ -738,6 +743,16 @@ class ApplicationMain void this.updateSplitTunnelingApplications(newSettings.splitTunnel.appsList); } + private handleNewTunnelState(newState: TunnelState) { + this.tunnelState.handleNewTunnelState(newState); + if ( + newState.state === 'error' && + newState.details?.cause === ErrorStateCause.needFullDiskPermissions + ) { + this.needFullDiskAccess = true; + } + } + private setRelayList(relayList: IRelayListWithEndpointData) { this.relayList = relayList; IpcMainEventChannel.relays.notify?.(relayList); @@ -834,7 +849,7 @@ class ApplicationMain }); IpcMainEventChannel.macOsSplitTunneling.handleNeedFullDiskPermissions(async () => { const fullDiskState = await this.daemonRpc.needFullDiskPermissions(); - this.tunnelState.needFullDiskAccess = fullDiskState; + this.needFullDiskAccess = fullDiskState; return fullDiskState; }); diff --git a/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts b/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts index b83b88a0f8ba..41305ac582ac 100644 --- a/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts +++ b/desktop/packages/mullvad-vpn/src/main/tunnel-state.ts @@ -1,5 +1,5 @@ import { connectEnabled, disconnectEnabled, reconnectEnabled } from '../shared/connect-helper'; -import { ErrorStateCause, ILocation, TunnelState } from '../shared/daemon-rpc-types'; +import { ILocation, TunnelState } from '../shared/daemon-rpc-types'; import { Scheduler } from '../shared/scheduler'; export interface TunnelStateProvider { @@ -11,8 +11,6 @@ export interface TunnelStateHandlerDelegate { } export default class TunnelStateHandler { - public needFullDiskAccess = false; - // The current tunnel state private tunnelStateValue: TunnelState = { state: 'disconnected' }; // When pressing connect/disconnect/reconnect the app assumes what the next state will be before @@ -55,12 +53,6 @@ export default class TunnelStateHandler { } public handleNewTunnelState(newState: TunnelState) { - if (newState.state === 'error' && newState.details) { - if (newState.details.cause === ErrorStateCause.needFullDiskPermissions) { - this.needFullDiskAccess = true; - } - } - // If there's a fallback state set then the app is in an assumed next state and need to check // if it's now reached or if the current state should be ignored and set as the fallback state. if (this.tunnelStateFallback) {