summaryrefslogtreecommitdiffhomepage
path: root/gui/src/shared
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-08-04 10:53:53 +0200
committerDavid Lönnhager <david.l@mullvad.net>2020-08-04 10:53:53 +0200
commit61d14531b61cc78d951add7b3cdfd3623e45410b (patch)
tree50fce79818d21f8ad497b64243a14a4c84b2a347 /gui/src/shared
parentabf7bb0dd3021daef52593515a98b0ebb189d9a0 (diff)
parent3496937abc7e6347e057a39ec6a40f49dd71e6a2 (diff)
downloadmullvadvpn-61d14531b61cc78d951add7b3cdfd3623e45410b.tar.xz
mullvadvpn-61d14531b61cc78d951add7b3cdfd3623e45410b.zip
Merge branch 'win-firewall-errors'
Diffstat (limited to 'gui/src/shared')
-rw-r--r--gui/src/shared/daemon-rpc-types.ts14
-rw-r--r--gui/src/shared/notifications/error.ts130
2 files changed, 94 insertions, 50 deletions
diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts
index bec0275e9b..1f1779a4b0 100644
--- a/gui/src/shared/daemon-rpc-types.ts
+++ b/gui/src/shared/daemon-rpc-types.ts
@@ -15,6 +15,16 @@ export interface ILocation {
bridgeHostname?: string;
}
+export type FirewallPolicyError =
+ | { reason: 'generic' }
+ | {
+ reason: 'locked';
+ details?: {
+ name: string;
+ pid: number;
+ };
+ };
+
export type TunnelParameterError =
| 'no_matching_relay'
| 'no_matching_bridge_relay'
@@ -25,12 +35,12 @@ export type ErrorStateCause =
| {
reason:
| 'ipv6_unavailable'
- | 'set_firewall_policy_error'
| 'set_dns_error'
| 'start_tunnel_error'
| 'is_offline'
| 'tap_adapter_problem';
}
+ | { reason: 'set_firewall_policy_error'; details: FirewallPolicyError }
| { reason: 'tunnel_parameter_error'; details: TunnelParameterError }
| { reason: 'auth_failed'; details?: string };
@@ -102,7 +112,7 @@ export type TunnelState =
| { state: 'error'; details: IErrorState };
export interface IErrorState {
- isBlocking: boolean;
+ blockFailure?: FirewallPolicyError;
cause: ErrorStateCause;
}
diff --git a/gui/src/shared/notifications/error.ts b/gui/src/shared/notifications/error.ts
index 1a8499739e..7b438edb54 100644
--- a/gui/src/shared/notifications/error.ts
+++ b/gui/src/shared/notifications/error.ts
@@ -1,7 +1,13 @@
import { sprintf } from 'sprintf-js';
import { hasExpired } from '../account-expiry';
import { AuthFailureKind, parseAuthFailure } from '../auth-failure';
-import { IErrorState, TunnelState, TunnelParameterError } from '../daemon-rpc-types';
+import {
+ IErrorState,
+ TunnelState,
+ TunnelParameterError,
+ ErrorStateCause,
+ FirewallPolicyError,
+} from '../daemon-rpc-types';
import { messages } from '../gettext';
import {
InAppNotification,
@@ -27,7 +33,7 @@ export class ErrorNotificationProvider
this.context.tunnelState,
this.context.accountExpiry,
),
- critical: !this.context.tunnelState.details.isBlocking,
+ critical: !!this.context.tunnelState.details.blockFailure,
}
: undefined;
}
@@ -36,7 +42,7 @@ export class ErrorNotificationProvider
return this.context.tunnelState.state === 'error'
? {
indicator: 'error',
- title: this.context.tunnelState.details.isBlocking
+ title: !this.context.tunnelState.details.blockFailure
? messages.pgettext('in-app-notifications', 'BLOCKING INTERNET')
: messages.pgettext('in-app-notifications', 'YOU MIGHT BE LEAKING NETWORK TRAFFIC'),
subtitle: getInAppNotificationSubtitle(this.context.tunnelState),
@@ -49,7 +55,7 @@ function getSystemNotificationMessage(
tunnelState: { state: 'error'; details: IErrorState },
accountExpiry?: string,
) {
- if (!tunnelState.details.isBlocking) {
+ if (tunnelState.details.blockFailure) {
return messages.pgettext('notifications', 'Critical error (your attention is required)');
} else if (
(tunnelState.details.cause.reason === 'auth_failed' &&
@@ -75,57 +81,85 @@ function getSystemNotificationMessage(
}
function getInAppNotificationSubtitle(tunnelState: { state: 'error'; details: IErrorState }) {
- if (!tunnelState.details.isBlocking) {
- return messages.pgettext(
+ let blockFailureMessage = null;
+ if (tunnelState.details.blockFailure) {
+ const extraMessage = getPolicyMessage(tunnelState.details.blockFailure);
+ blockFailureMessage = `${messages.pgettext(
'in-app-notifications',
- 'Failed to block all network traffic. Please troubleshoot or report the problem to us.',
- );
- } else {
- const blockReason = tunnelState.details.cause;
- switch (blockReason.reason) {
- case 'auth_failed':
- return parseAuthFailure(blockReason.details).message;
- case 'ipv6_unavailable':
- return messages.pgettext(
- 'in-app-notifications',
- 'Could not configure IPv6, please enable it on your system or disable it in the app',
- );
- case 'set_firewall_policy_error': {
- let extraMessage = null;
- switch (process.platform) {
- case 'linux':
- extraMessage = messages.pgettext('in-app-notifications', 'Your kernel may be outdated');
- break;
- case 'win32':
+ 'Failed to block all network traffic',
+ )}${extraMessage ? '. ' + extraMessage : ''}`;
+ }
+
+ const blockMessage = getBlockMessage(tunnelState.details.cause);
+ return blockFailureMessage
+ ? `${blockFailureMessage}. ${messages.pgettext(
+ 'in-app-notifications',
+ 'Original block reason',
+ )}: ${blockMessage}`
+ : blockMessage;
+}
+
+function getBlockMessage(blockReason: ErrorStateCause): string {
+ switch (blockReason.reason) {
+ case 'auth_failed':
+ return parseAuthFailure(blockReason.details).message;
+ case 'ipv6_unavailable':
+ return messages.pgettext(
+ 'in-app-notifications',
+ 'Could not configure IPv6, please enable it on your system or disable it in the app',
+ );
+ case 'set_firewall_policy_error': {
+ const extraMessage = getPolicyMessage(blockReason.details);
+ return `${messages.pgettext(
+ 'in-app-notifications',
+ 'Failed to apply firewall rules. The device might currently be unsecured',
+ )}${extraMessage ? '. ' + extraMessage : ''}`;
+ }
+ case 'set_dns_error':
+ return messages.pgettext('in-app-notifications', 'Failed to set system DNS server');
+ case 'start_tunnel_error':
+ return messages.pgettext('in-app-notifications', 'Failed to start tunnel connection');
+ case 'tunnel_parameter_error':
+ return getTunnelParameterMessage(blockReason.details);
+ case 'is_offline':
+ return messages.pgettext(
+ 'in-app-notifications',
+ 'This device is offline, no tunnels can be established',
+ );
+ case 'tap_adapter_problem':
+ return messages.pgettext(
+ 'in-app-notifications',
+ "Unable to detect a working TAP adapter on this device. If you've disabled it, enable it again. Otherwise, please reinstall the app",
+ );
+ }
+}
+
+function getPolicyMessage(err: FirewallPolicyError): string | null {
+ let extraMessage = null;
+ switch (process.platform) {
+ case 'linux':
+ extraMessage = messages.pgettext('in-app-notifications', 'Your kernel may be outdated');
+ break;
+ case 'win32':
+ switch (err.reason) {
+ case 'locked':
+ if (err.details) {
+ // TODO: Check if this message is ok
+ extraMessage = `${messages.pgettext(
+ 'in-app-notifications',
+ 'An application prevented the policy from being set',
+ )}: ${err.details.name}`;
+ } else {
extraMessage = messages.pgettext(
'in-app-notifications',
'This might be caused by third party security software',
);
- break;
- }
- return `${messages.pgettext(
- 'in-app-notifications',
- 'Failed to apply firewall rules. The device might currently be unsecured',
- )}${extraMessage ? '. ' + extraMessage : ''}`;
+ }
+ break;
}
- case 'set_dns_error':
- return messages.pgettext('in-app-notifications', 'Failed to set system DNS server');
- case 'start_tunnel_error':
- return messages.pgettext('in-app-notifications', 'Failed to start tunnel connection');
- case 'tunnel_parameter_error':
- return getTunnelParameterMessage(blockReason.details);
- case 'is_offline':
- return messages.pgettext(
- 'in-app-notifications',
- 'This device is offline, no tunnels can be established',
- );
- case 'tap_adapter_problem':
- return messages.pgettext(
- 'in-app-notifications',
- "Unable to detect a working TAP adapter on this device. If you've disabled it, enable it again. Otherwise, please reinstall the app",
- );
- }
+ break;
}
+ return extraMessage;
}
function getTunnelParameterMessage(err: TunnelParameterError): string {