diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj index 954b3f7..985ac06 100644 --- a/WireGuard/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj @@ -129,7 +129,7 @@ 6FB1BDCA21D50F1700A991BF /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A52180447E0012E523 /* x25519.c */; }; 6FB1BDCB21D50F1700A991BF /* Curve25519.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A7218044FC0012E523 /* Curve25519.swift */; }; 6FB1BDCC21D50F5300A991BF /* TunnelsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */; }; - 6FB1BDCD21D50F5300A991BF /* ActivateOnDemandSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandSetting.swift */; }; + 6FB1BDCD21D50F5300A991BF /* ActivateOnDemandOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */; }; 6FB1BDCE21D50F5300A991BF /* TunnelStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541A821C451D100994C13 /* TunnelStatus.swift */; }; 6FB1BDD021D50F5300A991BF /* TunnelErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */; }; 6FB1BDD121D50F5300A991BF /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; }; @@ -182,7 +182,7 @@ 6FFA5D952194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */; }; 6FFA5D96219446380001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */; }; 6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.swift */; }; - 6FFA5DA42197085D0001E2F7 /* ActivateOnDemandSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandSetting.swift */; }; + 6FFA5DA42197085D0001E2F7 /* ActivateOnDemandOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */; }; 6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */; }; /* End PBXBuildFile section */ @@ -362,7 +362,7 @@ 6FF4AC482120B9E0002C96EB /* WireGuard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WireGuard.entitlements; sourceTree = ""; }; 6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NETunnelProviderProtocol+Extension.swift"; sourceTree = ""; }; 6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorNotifier.swift; sourceTree = ""; }; - 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandSetting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandSetting.swift; sourceTree = ""; }; + 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandOption.swift; sourceTree = ""; }; 6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseError+WireGuardAppError.swift"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -543,7 +543,7 @@ children = ( 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */, 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */, - 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandSetting.swift */, + 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */, 5F4541A821C451D100994C13 /* TunnelStatus.swift */, 6FB1017821C57DE600766195 /* MockTunnels.swift */, 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */, @@ -1158,7 +1158,7 @@ 6FBA101521D613F90051C35F /* Application.swift in Sources */, 6FB1BDCC21D50F5300A991BF /* TunnelsManager.swift in Sources */, 6F8F0D7222258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */, - 6FB1BDCD21D50F5300A991BF /* ActivateOnDemandSetting.swift in Sources */, + 6FB1BDCD21D50F5300A991BF /* ActivateOnDemandOption.swift in Sources */, 6FB1BDCE21D50F5300A991BF /* TunnelStatus.swift in Sources */, 6FB1BDD021D50F5300A991BF /* TunnelErrors.swift in Sources */, 6FB1BDD121D50F5300A991BF /* ZipImporter.swift in Sources */, @@ -1307,7 +1307,7 @@ 5F4541A221C2D6DF00994C13 /* BorderedTextButton.swift in Sources */, 5FF7B96521CC95FA00A7DD74 /* PeerConfiguration.swift in Sources */, 6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */, - 6FFA5DA42197085D0001E2F7 /* ActivateOnDemandSetting.swift in Sources */, + 6FFA5DA42197085D0001E2F7 /* ActivateOnDemandOption.swift in Sources */, 5F4541B221CBFAEE00994C13 /* String+ArrayConversion.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/WireGuard/WireGuard/Tunnel/ActivateOnDemandSetting.swift b/WireGuard/WireGuard/Tunnel/ActivateOnDemandOption.swift similarity index 79% rename from WireGuard/WireGuard/Tunnel/ActivateOnDemandSetting.swift rename to WireGuard/WireGuard/Tunnel/ActivateOnDemandOption.swift index 89edd77..8b39f8c 100644 --- a/WireGuard/WireGuard/Tunnel/ActivateOnDemandSetting.swift +++ b/WireGuard/WireGuard/Tunnel/ActivateOnDemandOption.swift @@ -3,13 +3,8 @@ import NetworkExtension -struct ActivateOnDemandSetting { - var isActivateOnDemandEnabled: Bool - var activateOnDemandOption: ActivateOnDemandOption -} - enum ActivateOnDemandOption: Equatable { - case none // Valid only when isActivateOnDemandEnabled is false + case off case wiFiInterfaceOnly(ActivateOnDemandSSIDOption) case nonWiFiInterfaceOnly case anyInterface(ActivateOnDemandSSIDOption) @@ -29,12 +24,11 @@ enum ActivateOnDemandSSIDOption: Equatable { case exceptSpecificSSIDs([String]) } -extension ActivateOnDemandSetting { +extension ActivateOnDemandOption { func apply(on tunnelProviderManager: NETunnelProviderManager) { - tunnelProviderManager.isOnDemandEnabled = isActivateOnDemandEnabled let rules: [NEOnDemandRule]? - switch activateOnDemandOption { - case .none: + switch self { + case .off: rules = nil case .wiFiInterfaceOnly(let ssidOption): rules = ssidOnDemandRules(option: ssidOption) + [NEOnDemandRuleDisconnect(interfaceType: nonWiFiInterfaceType)] @@ -48,6 +42,7 @@ extension ActivateOnDemandSetting { } } tunnelProviderManager.onDemandRules = rules + tunnelProviderManager.isOnDemandEnabled = self != .off } init(from tunnelProviderManager: NETunnelProviderManager) { @@ -55,7 +50,7 @@ extension ActivateOnDemandSetting { let activateOnDemandOption: ActivateOnDemandOption switch rules.count { case 0: - activateOnDemandOption = .none + activateOnDemandOption = .off case 1: let rule = rules[0] precondition(rule.action == .connect) @@ -90,19 +85,10 @@ extension ActivateOnDemandSetting { fatalError("Unexpected number of onDemandRules set on tunnel provider manager") } - self.activateOnDemandOption = activateOnDemandOption - if activateOnDemandOption == .none { - isActivateOnDemandEnabled = false - } else { - isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled - } + self = activateOnDemandOption } } -extension ActivateOnDemandSetting { - static var defaultSetting = ActivateOnDemandSetting(isActivateOnDemandEnabled: false, activateOnDemandOption: .none) -} - private extension NEOnDemandRuleConnect { convenience init(interfaceType: NEOnDemandRuleInterfaceType, ssids: [String]? = nil) { self.init() @@ -132,13 +118,3 @@ private func ssidOnDemandRules(option: ActivateOnDemandSSIDOption) -> [NEOnDeman NEOnDemandRuleConnect(interfaceType: .wiFi)] } } - -extension ActivateOnDemandSetting { - init(with option: ActivateOnDemandOption) { - if option == .none { - self = ActivateOnDemandSetting(isActivateOnDemandEnabled: false, activateOnDemandOption: option) - } else { - self = ActivateOnDemandSetting(isActivateOnDemandEnabled: true, activateOnDemandOption: option) - } - } -} diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift index 1a467f5..8f4c87c 100644 --- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift +++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift @@ -97,7 +97,7 @@ class TunnelsManager { } } - func add(tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting = ActivateOnDemandSetting.defaultSetting, completionHandler: @escaping (WireGuardResult) -> Void) { + func add(tunnelConfiguration: TunnelConfiguration, onDemandOption: ActivateOnDemandOption = .off, completionHandler: @escaping (WireGuardResult) -> Void) { let tunnelName = tunnelConfiguration.name ?? "" if tunnelName.isEmpty { completionHandler(.failure(TunnelsManagerError.tunnelNameEmpty)) @@ -113,7 +113,7 @@ class TunnelsManager { tunnelProviderManager.setTunnelConfiguration(tunnelConfiguration) tunnelProviderManager.isEnabled = true - activateOnDemandSetting.apply(on: tunnelProviderManager) + onDemandOption.apply(on: tunnelProviderManager) let activeTunnel = tunnels.first { $0.status == .active || $0.status == .activating } @@ -167,7 +167,7 @@ class TunnelsManager { } } - func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting, completionHandler: @escaping (TunnelsManagerError?) -> Void) { + func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration, onDemandOption: ActivateOnDemandOption, completionHandler: @escaping (TunnelsManagerError?) -> Void) { let tunnelName = tunnelConfiguration.name ?? "" if tunnelName.isEmpty { completionHandler(TunnelsManagerError.tunnelNameEmpty) @@ -191,8 +191,8 @@ class TunnelsManager { } tunnelProviderManager.isEnabled = true - let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && activateOnDemandSetting.isActivateOnDemandEnabled - activateOnDemandSetting.apply(on: tunnelProviderManager) + let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && onDemandOption != .off + onDemandOption.apply(on: tunnelProviderManager) tunnelProviderManager.saveToPreferences { [weak self] error in guard error == nil else { @@ -455,8 +455,8 @@ class TunnelContainer: NSObject { return tunnelProvider.tunnelConfiguration } - var activateOnDemandSetting: ActivateOnDemandSetting { - return ActivateOnDemandSetting(from: tunnelProvider) + var onDemandOption: ActivateOnDemandOption { + return ActivateOnDemandOption(from: tunnelProvider) } init(tunnel: NETunnelProviderManager) { diff --git a/WireGuard/WireGuard/UI/ActivateOnDemandViewModel.swift b/WireGuard/WireGuard/UI/ActivateOnDemandViewModel.swift index f38ca6a..2f13f07 100644 --- a/WireGuard/WireGuard/UI/ActivateOnDemandViewModel.swift +++ b/WireGuard/WireGuard/UI/ActivateOnDemandViewModel.swift @@ -49,18 +49,10 @@ class ActivateOnDemandViewModel { } extension ActivateOnDemandViewModel { - convenience init(setting: ActivateOnDemandSetting) { - if setting.isActivateOnDemandEnabled { - self.init(option: setting.activateOnDemandOption) - } else { - self.init(option: .none) - } - } - convenience init(option: ActivateOnDemandOption) { self.init() switch option { - case .none: + case .off: break case .wiFiInterfaceOnly(let onDemandSSIDOption): isWiFiInterfaceEnabled = true @@ -77,7 +69,7 @@ extension ActivateOnDemandViewModel { func toOnDemandOption() -> ActivateOnDemandOption { switch (isWiFiInterfaceEnabled, isNonWiFiInterfaceEnabled) { case (false, false): - return .none + return .off case (false, true): return .nonWiFiInterfaceOnly case (true, false): diff --git a/WireGuard/WireGuard/UI/iOS/ViewController/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/iOS/ViewController/TunnelDetailTableViewController.swift index 19d66e7..4ed75a6 100644 --- a/WireGuard/WireGuard/UI/iOS/ViewController/TunnelDetailTableViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/ViewController/TunnelDetailTableViewController.swift @@ -45,7 +45,7 @@ class TunnelDetailTableViewController: UITableViewController { self.tunnelsManager = tunnelsManager self.tunnel = tunnel tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration) - onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) super.init(style: .grouped) loadSections() loadVisibleFields() @@ -60,7 +60,7 @@ class TunnelDetailTableViewController: UITableViewController { } onDemandObservationToken = tunnel.observe(\.isActivateOnDemandEnabled) { [weak self] tunnel, _ in // Handle On-Demand getting turned on/off outside of the app - self?.onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + self?.onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) self?.updateActivateOnDemandFields() } } @@ -274,7 +274,7 @@ class TunnelDetailTableViewController: UITableViewController { extension TunnelDetailTableViewController: TunnelEditTableViewControllerDelegate { func tunnelSaved(tunnel: TunnelContainer) { tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration) - onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) loadSections() loadVisibleFields() title = tunnel.name diff --git a/WireGuard/WireGuard/UI/iOS/ViewController/TunnelEditTableViewController.swift b/WireGuard/WireGuard/UI/iOS/ViewController/TunnelEditTableViewController.swift index f640414..e5f322a 100644 --- a/WireGuard/WireGuard/UI/iOS/ViewController/TunnelEditTableViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/ViewController/TunnelEditTableViewController.swift @@ -60,7 +60,7 @@ class TunnelEditTableViewController: UITableViewController { self.tunnelsManager = tunnelsManager self.tunnel = tunnel tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration) - onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) super.init(style: .grouped) loadSections() } @@ -113,10 +113,10 @@ class TunnelEditTableViewController: UITableViewController { ErrorPresenter.showErrorAlert(title: alertTitle, message: errorMessage, from: self) tableView.reloadData() // Highlight erroring fields case .saved(let tunnelConfiguration): - let activateOnDemandSetting = ActivateOnDemandSetting(with: onDemandViewModel.toOnDemandOption()) + let onDemandOption = onDemandViewModel.toOnDemandOption() if let tunnel = tunnel { // We're modifying an existing tunnel - tunnelsManager.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: activateOnDemandSetting) { [weak self] error in + tunnelsManager.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] error in if let error = error { ErrorPresenter.showErrorAlert(error: error, from: self) } else { @@ -126,7 +126,7 @@ class TunnelEditTableViewController: UITableViewController { } } else { // We're adding a new tunnel - tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: activateOnDemandSetting) { [weak self] result in + tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] result in if let error = result.error { ErrorPresenter.showErrorAlert(error: error, from: self) } else { diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift index 1cb9e2a..152cbda 100644 --- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift +++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift @@ -97,7 +97,7 @@ class TunnelDetailTableViewController: NSViewController { self.tunnelsManager = tunnelsManager self.tunnel = tunnel tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration) - onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) super.init(nibName: nil, bundle: nil) updateTableViewModelRowsBySection() updateTableViewModelRows() @@ -492,7 +492,7 @@ extension TunnelDetailTableViewController: NSTableViewDelegate { extension TunnelDetailTableViewController: TunnelEditViewControllerDelegate { func tunnelSaved(tunnel: TunnelContainer) { tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnel.tunnelConfiguration) - onDemandViewModel = ActivateOnDemandViewModel(setting: tunnel.activateOnDemandSetting) + onDemandViewModel = ActivateOnDemandViewModel(option: tunnel.onDemandOption) updateTableViewModelRowsBySection() updateTableViewModelRows() updateStatus() diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift index 51b1944..d3c76f5 100644 --- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift +++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift @@ -84,13 +84,6 @@ class TunnelEditViewController: NSViewController { return button }() - let activateOnDemandOptions: [ActivateOnDemandOption] = [ - .none, - .anyInterface(.anySSID), - .wiFiInterfaceOnly(.anySSID), - .nonWiFiInterfaceOnly - ] - let tunnelsManager: TunnelsManager let tunnel: TunnelContainer? var onDemandViewModel: ActivateOnDemandViewModel @@ -106,7 +99,7 @@ class TunnelEditViewController: NSViewController { init(tunnelsManager: TunnelsManager, tunnel: TunnelContainer?) { self.tunnelsManager = tunnelsManager self.tunnel = tunnel - self.onDemandViewModel = tunnel != nil ? ActivateOnDemandViewModel(setting: tunnel!.activateOnDemandSetting) : ActivateOnDemandViewModel() + self.onDemandViewModel = tunnel != nil ? ActivateOnDemandViewModel(option: tunnel!.onDemandOption) : ActivateOnDemandViewModel() super.init(nibName: nil, bundle: nil) } @@ -223,7 +216,7 @@ class TunnelEditViewController: NSViewController { onDemandViewModel.isNonWiFiInterfaceEnabled = onDemandEthernetCheckbox.state == .on onDemandWiFiControls.saveToViewModel() - let onDemandSetting = ActivateOnDemandSetting(with: onDemandViewModel.toOnDemandOption()) + let onDemandOption = onDemandViewModel.toOnDemandOption() let isTunnelModifiedWithoutChangingName = (tunnel != nil && tunnel!.name == name) guard isTunnelModifiedWithoutChangingName || tunnelsManager.tunnel(named: name) == nil else { @@ -259,7 +252,7 @@ class TunnelEditViewController: NSViewController { if let tunnel = tunnel { // We're modifying an existing tunnel - tunnelsManager.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] error in + tunnelsManager.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] error in self?.setUserInteractionEnabled(true) if let error = error { ErrorPresenter.showErrorAlert(error: error, from: self) @@ -271,7 +264,7 @@ class TunnelEditViewController: NSViewController { } else { // We're creating a new tunnel AppStorePrivacyNotice.show(from: self, into: tunnelsManager) { [weak self] in - self?.tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, activateOnDemandSetting: onDemandSetting) { [weak self] result in + self?.tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] result in self?.setUserInteractionEnabled(true) if let error = result.error { ErrorPresenter.showErrorAlert(error: error, from: self)