summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2024-09-17 13:56:37 +0200
committerBug Magnet <marco.nikic@mullvad.net>2024-09-19 15:59:59 +0200
commitf45f874316fa7d953a0dbfe7ea9dcf7db4be20e1 (patch)
treefaf03546441fc27afc2d398767a368f1704b07a5
parent795877885d934e7800426c94a7688825b3de224d (diff)
downloadmullvadvpn-f45f874316fa7d953a0dbfe7ea9dcf7db4be20e1.tar.xz
mullvadvpn-f45f874316fa7d953a0dbfe7ea9dcf7db4be20e1.zip
Make the packet tunnel enter error state when failing device check
-rw-r--r--ios/MullvadVPNTests/MullvadVPN/PacketTunnel/DeviceCheck/DeviceCheckOperationTests.swift2
-rw-r--r--ios/PacketTunnel/DeviceCheck/DeviceCheckOperation.swift4
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/DeviceChecker.swift8
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift44
4 files changed, 36 insertions, 22 deletions
diff --git a/ios/MullvadVPNTests/MullvadVPN/PacketTunnel/DeviceCheck/DeviceCheckOperationTests.swift b/ios/MullvadVPNTests/MullvadVPN/PacketTunnel/DeviceCheck/DeviceCheckOperationTests.swift
index a5fc35fc84..a0e8d3830f 100644
--- a/ios/MullvadVPNTests/MullvadVPN/PacketTunnel/DeviceCheck/DeviceCheckOperationTests.swift
+++ b/ios/MullvadVPNTests/MullvadVPN/PacketTunnel/DeviceCheck/DeviceCheckOperationTests.swift
@@ -241,7 +241,7 @@ class DeviceCheckOperationTests: XCTestCase {
waitForExpectations(timeout: .UnitTest.timeout)
}
- func testShouldReportFailedKeyRotataionAttempt() {
+ func testShouldReportFailedKeyRotationAttempt() {
let expect = expectation(description: "Wait for operation to complete")
let currentKey = PrivateKey()
diff --git a/ios/PacketTunnel/DeviceCheck/DeviceCheckOperation.swift b/ios/PacketTunnel/DeviceCheck/DeviceCheckOperation.swift
index f3270c8a8d..6c4e00b156 100644
--- a/ios/PacketTunnel/DeviceCheck/DeviceCheckOperation.swift
+++ b/ios/PacketTunnel/DeviceCheck/DeviceCheckOperation.swift
@@ -278,14 +278,14 @@ final class DeviceCheckOperation: ResultOperation<DeviceCheck> {
}
/// An error used internally by `DeviceCheckOperation`.
-private enum DeviceCheckError: LocalizedError, Equatable {
+public enum DeviceCheckError: LocalizedError, Equatable {
/// Device is no longer logged in.
case invalidDeviceState
/// Main process has likely performed key rotation at the same time when packet tunnel was doing so.
case keyRotationRace
- var errorDescription: String? {
+ public var errorDescription: String? {
switch self {
case .invalidDeviceState:
return "Cannot complete device check because device is no longer logged in."
diff --git a/ios/PacketTunnel/PacketTunnelProvider/DeviceChecker.swift b/ios/PacketTunnel/PacketTunnelProvider/DeviceChecker.swift
index a1933510bd..6a31675dbc 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/DeviceChecker.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/DeviceChecker.swift
@@ -35,7 +35,7 @@ final class DeviceChecker {
key.
4. Rotate WireGuard key on key mismatch.
*/
- func start(rotateKeyOnMismatch: Bool) async throws -> DeviceCheck {
+ func start(rotateKeyOnMismatch: Bool) async -> Result<DeviceCheck, Error> {
let checkOperation = DeviceCheckOperation(
dispatchQueue: dispatchQueue,
remoteSevice: DeviceCheckRemoteService(accountsProxy: accountsProxy, devicesProxy: devicesProxy),
@@ -43,10 +43,10 @@ final class DeviceChecker {
rotateImmediatelyOnKeyMismatch: rotateKeyOnMismatch
)
- return try await withTaskCancellationHandler {
- return try await withCheckedThrowingContinuation { continuation in
+ return await withTaskCancellationHandler {
+ return await withCheckedContinuation { continuation in
checkOperation.completionHandler = { result in
- continuation.resume(with: result)
+ continuation.resume(with: .success(result))
}
operationQueue.addOperation(checkOperation)
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index d76bf3b81e..34be39d589 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -289,26 +289,40 @@ extension PacketTunnelProvider {
extension PacketTunnelProvider {
private func startDeviceCheck(rotateKeyOnMismatch: Bool = false) {
Task {
- do {
- try await startDeviceCheckInner(rotateKeyOnMismatch: rotateKeyOnMismatch)
- } catch {
- providerLogger.error(error: error, message: "Failed to perform device check.")
- }
+ await startDeviceCheckInner(rotateKeyOnMismatch: rotateKeyOnMismatch)
}
}
- private func startDeviceCheckInner(rotateKeyOnMismatch: Bool) async throws {
- let result = try await deviceChecker.start(rotateKeyOnMismatch: rotateKeyOnMismatch)
+ private func startDeviceCheckInner(rotateKeyOnMismatch: Bool) async {
+ let result = await deviceChecker.start(rotateKeyOnMismatch: rotateKeyOnMismatch)
- if let blockedStateReason = result.blockedStateReason {
- actor.setErrorState(reason: blockedStateReason)
- }
+ switch result {
+ case let .failure(error):
+ switch error {
+ case is DeviceCheckError:
+ providerLogger.error("\(error.localizedDescription) Forcing a log out")
+ actor.setErrorState(reason: .deviceLoggedOut)
+ default:
+ providerLogger
+ .error(
+ "Entering blocked state because device check encountered a generic error: \(error.localizedDescription)"
+ )
+ actor.setErrorState(reason: .unknown)
+ }
- switch result.keyRotationStatus {
- case let .attempted(date), let .succeeded(date):
- actor.notifyKeyRotation(date: date)
- case .noAction:
- break
+ case let .success(keyRotationResult):
+ if let blockedStateReason = keyRotationResult.blockedStateReason {
+ providerLogger.error("Entering blocked state after unsuccessful device check: \(blockedStateReason)")
+ actor.setErrorState(reason: blockedStateReason)
+ return
+ }
+
+ switch keyRotationResult.keyRotationStatus {
+ case let .attempted(date), let .succeeded(date):
+ actor.notifyKeyRotation(date: date)
+ case .noAction:
+ break
+ }
}
}
}