Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2909fdf41e | |||
| 3149c50299 |
@@ -206,7 +206,6 @@ class TunnelsManager {
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, renamed: "modify(tunnel:tunnelConfiguration:onDemandOption:shouldEnsureOnDemandEnabled:)")
|
||||
func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration,
|
||||
onDemandOption: ActivateOnDemandOption,
|
||||
shouldEnsureOnDemandEnabled: Bool = false,
|
||||
@@ -300,22 +299,6 @@ class TunnelsManager {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, macOS 10.15.0, *)
|
||||
func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration,
|
||||
onDemandOption: ActivateOnDemandOption,
|
||||
shouldEnsureOnDemandEnabled: Bool = false) async throws {
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption, shouldEnsureOnDemandEnabled: shouldEnsureOnDemandEnabled) { error in
|
||||
if let error = error {
|
||||
continuation.resume(throwing: error)
|
||||
return
|
||||
}
|
||||
|
||||
continuation.resume(returning: ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func remove(tunnel: TunnelContainer, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
|
||||
let tunnelProviderManager = tunnel.tunnelProvider
|
||||
#if os(macOS)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import UIKit
|
||||
import os.log
|
||||
import AppIntents
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -12,10 +11,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
var mainVC: MainViewController?
|
||||
var isLaunchedForSpecificAction = false
|
||||
|
||||
var tunnelsManager: TunnelsManager?
|
||||
|
||||
static let tunnelsManagerReadyNotificationName: Notification.Name = Notification.Name(rawValue: "com.wireguard.ios.tunnelsManagerReadyNotification")
|
||||
|
||||
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
Logger.configureGlobal(tagged: "APP", withFilePath: FileManager.logFileURL?.path)
|
||||
|
||||
@@ -34,29 +29,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
self.mainVC = mainVC
|
||||
|
||||
// Create the tunnels manager, and when it's ready, inform tunnelsListVC
|
||||
TunnelsManager.create { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
ErrorPresenter.showErrorAlert(error: error, from: self.mainVC)
|
||||
case .success(let tunnelsManager):
|
||||
self.tunnelsManager = tunnelsManager
|
||||
self.mainVC?.tunnelsListVC?.setTunnelsManager(tunnelsManager: tunnelsManager)
|
||||
|
||||
tunnelsManager.activationDelegate = self.mainVC
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
AppDependencyManager.shared.add(dependency: tunnelsManager)
|
||||
}
|
||||
|
||||
NotificationCenter.default.post(name: AppDelegate.tunnelsManagerReadyNotificationName,
|
||||
object: self,
|
||||
userInfo: nil)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
@@ -64,6 +64,8 @@
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
@@ -72,22 +74,17 @@
|
||||
<string>$(VERSION_NAME)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(VERSION_ID)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Localized</string>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Localized</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array/>
|
||||
<array>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
@@ -126,6 +123,8 @@
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Localized</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.$(APP_ID_IOS)</string>
|
||||
</dict>
|
||||
|
||||
@@ -5,9 +5,7 @@ import UIKit
|
||||
|
||||
class MainViewController: UISplitViewController {
|
||||
|
||||
var tunnelsManager: TunnelsManager? {
|
||||
return (UIApplication.shared.delegate as? AppDelegate)?.tunnelsManager
|
||||
}
|
||||
var tunnelsManager: TunnelsManager?
|
||||
var onTunnelsManagerReady: ((TunnelsManager) -> Void)?
|
||||
var tunnelsListVC: TunnelsListTableViewController?
|
||||
|
||||
@@ -40,24 +38,29 @@ class MainViewController: UISplitViewController {
|
||||
// On iPad, always show both masterVC and detailVC, even in portrait mode, like the Settings app
|
||||
preferredDisplayMode = .allVisible
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleTunnelsManagerReady(_:)),
|
||||
name: AppDelegate.tunnelsManagerReadyNotificationName, object: nil)
|
||||
// Create the tunnels manager, and when it's ready, inform tunnelsListVC
|
||||
TunnelsManager.create { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||
case .success(let tunnelsManager):
|
||||
self.tunnelsManager = tunnelsManager
|
||||
self.tunnelsListVC?.setTunnelsManager(tunnelsManager: tunnelsManager)
|
||||
|
||||
tunnelsManager.activationDelegate = self
|
||||
|
||||
self.onTunnelsManagerReady?(tunnelsManager)
|
||||
self.onTunnelsManagerReady = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func allTunnelNames() -> [String]? {
|
||||
guard let tunnelsManager = self.tunnelsManager else { return nil }
|
||||
return tunnelsManager.mapTunnels { $0.name }
|
||||
}
|
||||
|
||||
@objc
|
||||
func handleTunnelsManagerReady(_ notification: Notification) {
|
||||
guard let tunnelsManager = self.tunnelsManager else { return }
|
||||
|
||||
self.onTunnelsManagerReady?(tunnelsManager)
|
||||
self.onTunnelsManagerReady = nil
|
||||
|
||||
NotificationCenter.default.removeObserver(self, name: AppDelegate.tunnelsManagerReadyNotificationName, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
extension MainViewController: TunnelsManagerActivationDelegate {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import Cocoa
|
||||
import ServiceManagement
|
||||
import AppIntents
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
@@ -59,10 +58,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
self.tunnelsTracker = tunnelsTracker
|
||||
self.statusItemController = statusItemController
|
||||
|
||||
if #available(macOS 13.0, *) {
|
||||
AppDependencyManager.shared.add(dependency: tunnelsManager)
|
||||
}
|
||||
|
||||
if !isLaunchedAtLogin {
|
||||
self.showManageTunnelsWindow(completion: nil)
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ public class WireGuardAdapter {
|
||||
/// Packet tunnel provider.
|
||||
private weak var packetTunnelProvider: NEPacketTunnelProvider?
|
||||
|
||||
/// KVO observer for `NEProvider.defaultPath`.
|
||||
private var defaultPathObserver: NSKeyValueObservation?
|
||||
|
||||
/// Last known default path.
|
||||
private var currentDefaultPath: NetworkExtension.NWPath?
|
||||
|
||||
/// Log handler closure.
|
||||
private let logHandler: LogHandler
|
||||
|
||||
@@ -181,11 +187,7 @@ public class WireGuardAdapter {
|
||||
return
|
||||
}
|
||||
|
||||
let networkMonitor = NWPathMonitor()
|
||||
networkMonitor.pathUpdateHandler = { [weak self] path in
|
||||
self?.didReceivePathUpdate(path: path)
|
||||
}
|
||||
networkMonitor.start(queue: self.workQueue)
|
||||
self.addDefaultPathObserver()
|
||||
|
||||
do {
|
||||
let settingsGenerator = try self.makeSettingsGenerator(with: tunnelConfiguration)
|
||||
@@ -198,10 +200,10 @@ public class WireGuardAdapter {
|
||||
try self.startWireGuardBackend(wgConfig: wgConfig),
|
||||
settingsGenerator
|
||||
)
|
||||
self.networkMonitor = networkMonitor
|
||||
|
||||
completionHandler(nil)
|
||||
} catch let error as WireGuardAdapterError {
|
||||
networkMonitor.cancel()
|
||||
self.removeDefaultPathObserver()
|
||||
completionHandler(error)
|
||||
} catch {
|
||||
fatalError()
|
||||
@@ -225,8 +227,7 @@ public class WireGuardAdapter {
|
||||
return
|
||||
}
|
||||
|
||||
self.networkMonitor?.cancel()
|
||||
self.networkMonitor = nil
|
||||
self.removeDefaultPathObserver()
|
||||
|
||||
self.state = .stopped
|
||||
|
||||
@@ -313,26 +314,29 @@ public class WireGuardAdapter {
|
||||
/// - Returns: `PacketTunnelSettingsGenerator`.
|
||||
private func setNetworkSettings(_ networkSettings: NEPacketTunnelNetworkSettings) throws {
|
||||
var systemError: Error?
|
||||
let condition = NSCondition()
|
||||
|
||||
// Activate the condition
|
||||
condition.lock()
|
||||
defer { condition.unlock() }
|
||||
let dispatchGroup = DispatchGroup()
|
||||
|
||||
dispatchGroup.enter()
|
||||
|
||||
self.packetTunnelProvider?.setTunnelNetworkSettings(networkSettings) { error in
|
||||
systemError = error
|
||||
condition.signal()
|
||||
dispatchGroup.leave()
|
||||
}
|
||||
|
||||
// Packet tunnel's `setTunnelNetworkSettings` times out in certain
|
||||
// scenarios & never calls the given callback.
|
||||
let setTunnelNetworkSettingsTimeout: TimeInterval = 5 // seconds
|
||||
let setTunnelNetworkSettingsTimeout: Int = 5 // seconds
|
||||
|
||||
if condition.wait(until: Date().addingTimeInterval(setTunnelNetworkSettingsTimeout)) {
|
||||
let waitResult = dispatchGroup.wait(wallTimeout: .now() + .seconds(setTunnelNetworkSettingsTimeout))
|
||||
|
||||
switch waitResult {
|
||||
case .success:
|
||||
if let systemError = systemError {
|
||||
throw WireGuardAdapterError.setNetworkSettings(systemError)
|
||||
}
|
||||
} else {
|
||||
|
||||
case .timedOut:
|
||||
self.logHandler(.error, "setTunnelNetworkSettings timed out after 5 seconds; proceeding anyway")
|
||||
}
|
||||
}
|
||||
@@ -411,19 +415,48 @@ public class WireGuardAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper method used by network path monitor.
|
||||
private func addDefaultPathObserver() {
|
||||
guard let packetTunnelProvider = packetTunnelProvider else { return }
|
||||
|
||||
defaultPathObserver?.invalidate()
|
||||
defaultPathObserver = packetTunnelProvider.observe(\.defaultPath, options: [.new]) { [weak self] _, change in
|
||||
guard let self = self, let defaultPath = change.newValue?.flatMap({ $0 }) else { return }
|
||||
|
||||
self.workQueue.async {
|
||||
self.didReceivePathUpdate(path: defaultPath)
|
||||
}
|
||||
}
|
||||
|
||||
currentDefaultPath = packetTunnelProvider.defaultPath
|
||||
}
|
||||
|
||||
private func removeDefaultPathObserver() {
|
||||
defaultPathObserver?.invalidate()
|
||||
defaultPathObserver = nil
|
||||
currentDefaultPath = nil
|
||||
}
|
||||
|
||||
/// Method invoked by KVO observer when new network path is received.
|
||||
/// - Parameter path: new network path
|
||||
private func didReceivePathUpdate(path: Network.NWPath) {
|
||||
self.logHandler(.verbose, "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
||||
private func didReceivePathUpdate(path: NetworkExtension.NWPath) {
|
||||
let isSamePath = currentDefaultPath?.isEqual(to: path) ?? false
|
||||
|
||||
currentDefaultPath = path
|
||||
|
||||
self.logHandler(.verbose, "Network change detected with \(path.status)")
|
||||
|
||||
#if os(macOS)
|
||||
if case .started(let handle, _) = self.state {
|
||||
if case .started(let handle, _) = self.state, !isSamePath {
|
||||
wgBumpSockets(handle)
|
||||
}
|
||||
#elseif os(iOS)
|
||||
let isSatisfiable = path.status == .satisfied || path.status == .satisfiable
|
||||
|
||||
switch self.state {
|
||||
case .started(let handle, let settingsGenerator):
|
||||
if path.status.isSatisfiable {
|
||||
if isSatisfiable {
|
||||
guard !isSamePath else { return }
|
||||
|
||||
let (wgConfig, resolutionResults) = settingsGenerator.endpointUapiConfiguration()
|
||||
self.logEndpointResolutionResults(resolutionResults)
|
||||
|
||||
@@ -438,7 +471,7 @@ public class WireGuardAdapter {
|
||||
}
|
||||
|
||||
case .temporaryShutdown(let settingsGenerator):
|
||||
guard path.status.isSatisfiable else { return }
|
||||
guard isSatisfiable else { return }
|
||||
|
||||
self.logHandler(.verbose, "Connectivity online, resuming backend.")
|
||||
|
||||
@@ -472,16 +505,19 @@ public enum WireGuardLogLevel: Int32 {
|
||||
case error = 1
|
||||
}
|
||||
|
||||
private extension Network.NWPath.Status {
|
||||
/// Returns `true` if the path is potentially satisfiable.
|
||||
var isSatisfiable: Bool {
|
||||
extension NetworkExtension.NWPathStatus: CustomDebugStringConvertible {
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .requiresConnection, .satisfied:
|
||||
return true
|
||||
case .unsatisfied:
|
||||
return false
|
||||
return "unsatisfied"
|
||||
case .satisfied:
|
||||
return "satisfied"
|
||||
case .satisfiable:
|
||||
return "satisfiable"
|
||||
case .invalid:
|
||||
return "invalid"
|
||||
@unknown default:
|
||||
return true
|
||||
return "unknown (rawValue = \(rawValue))"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
// App Intents Common
|
||||
"wireguardAppIntentsWrongTunnelError %@" = "Cannot find a tunnel with the name \"%1$@\"";
|
||||
"wireguardAppIntentsMissingConfigurationError" = "The selected tunnel has no configuration.";
|
||||
|
||||
// Get peers Intent
|
||||
"getPeersIntentName" = "Get Peers";
|
||||
"getPeersIntentDescription" = "Get list of public keys of peers in the selected configuration";
|
||||
"getPeersIntentTunnelParameterTitle" = "Tunnel";
|
||||
"getPeersIntentSummary ${tunnelName}" = "Get peers of ${tunnelName}";
|
||||
|
||||
// Tunnel Configuration Update
|
||||
"updateTunnelConfigurationIntentName" = "Update Tunnel Configuration";
|
||||
"updateTunnelConfigurationDescription" = "Update peers configuration of the selected tunnel.";
|
||||
"updateTunnelConfigurationIntentTunnelParameterTitle" = "Tunnel";
|
||||
"updateTunnelConfigurationIntentPeersParameterTitle" = "Peers";
|
||||
"updateTunnelConfigurationIntentMergeParameterTitle" = "Merge configuration";
|
||||
"updateTunnelConfigurationIntentSummary ${tunnelName}" = "Update ${tunnelName} configuration";
|
||||
|
||||
"updateTunnelConfigurationIntentPeerOptionsUnavailableError" = "Use the output of \"Build Peer Configuration\" action to update tunnel configuration. To update multiple peers at once, you can use the \"Add to Variable\" action and pass the resulting Variable in this field.";
|
||||
"updateTunnelConfigurationIntentMalformedPublicKeyError %@" = "The key \"%1$@\" is not a valid Public Key encoded in Base64 format.";
|
||||
|
||||
// Build Peer Configuration
|
||||
"buildPeerConfigurationUpdateIntentName" = "Build Peer Configuration";
|
||||
"buildPeerConfigurationUpdateIntentDescription" = "Build an item that contains the informations needed to update an peer's configuration.";
|
||||
"buildPeerConfigurationUpdateIntentSummary ${publicKey}" = "Build configuration for peer ${publicKey}";
|
||||
"buildPeerConfigurationUpdateIntentPublicKeyParameterTitle" = "Peer Public Key";
|
||||
"buildPeerConfigurationUpdateIntentEndpointParameterTitle" = "Endpoint";
|
||||
|
||||
// Peer Configuration Update Entity
|
||||
"peerConfigurationUpdateEntityName" = "Configuration Update - Peer";
|
||||
"peerConfigurationUpdateEntityPropertyPublicKeyTitle" = "Public Key";
|
||||
"peerConfigurationUpdateEntityPropertyEndpointTitle" = "Endpoint";
|
||||
@@ -1,77 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import AppIntents
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct BuildPeerConfigurationUpdate: AppIntent {
|
||||
|
||||
static var title = LocalizedStringResource("buildPeerConfigurationUpdateIntentName", table: "AppIntents")
|
||||
static var description = IntentDescription(
|
||||
LocalizedStringResource("buildPeerConfigurationUpdateIntentDescription", table: "AppIntents")
|
||||
)
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("buildPeerConfigurationUpdateIntentPublicKeyParameterTitle", table: "AppIntents")
|
||||
)
|
||||
var publicKey: String
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("buildPeerConfigurationUpdateIntentEndpointParameterTitle", table: "AppIntents")
|
||||
)
|
||||
var endpoint: String
|
||||
|
||||
func perform() async throws -> some IntentResult & ReturnsValue<AppIntentsPeer> {
|
||||
let peerConfigurationUpdate = AppIntentsPeer()
|
||||
peerConfigurationUpdate.publicKey = publicKey
|
||||
peerConfigurationUpdate.endpoint = endpoint
|
||||
|
||||
return .result(value: peerConfigurationUpdate)
|
||||
}
|
||||
|
||||
static var parameterSummary: some ParameterSummary {
|
||||
Summary("buildPeerConfigurationUpdateIntentSummary \(\.$publicKey)", table: "AppIntents") {
|
||||
\.$endpoint
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct AppIntentsPeer: TransientAppEntity {
|
||||
|
||||
static let kEndpointConfigUpdateDictionaryKey = "Endpoint"
|
||||
|
||||
static var typeDisplayRepresentation = TypeDisplayRepresentation(
|
||||
name: LocalizedStringResource("peerConfigurationUpdateEntityName", table: "AppIntents")
|
||||
)
|
||||
|
||||
@Property(
|
||||
title: LocalizedStringResource("peerConfigurationUpdateEntityPropertyPublicKeyTitle", table: "AppIntents")
|
||||
)
|
||||
var publicKey: String
|
||||
|
||||
@Property(
|
||||
title: LocalizedStringResource("peerConfigurationUpdateEntityPropertyEndpointTitle", table: "AppIntents")
|
||||
)
|
||||
var endpoint: String?
|
||||
|
||||
var displayRepresentation: DisplayRepresentation {
|
||||
var dictionary: [String: [String: String]] = [:]
|
||||
dictionary[publicKey] = [:]
|
||||
|
||||
if let endpoint {
|
||||
dictionary[publicKey]?.updateValue(endpoint, forKey: Self.kEndpointConfigUpdateDictionaryKey)
|
||||
}
|
||||
|
||||
let jsonData: Data
|
||||
do {
|
||||
jsonData = try JSONSerialization.data(withJSONObject: dictionary)
|
||||
} catch {
|
||||
return DisplayRepresentation(stringLiteral: error.localizedDescription)
|
||||
}
|
||||
|
||||
let jsonString = String(data: jsonData, encoding: .utf8)!
|
||||
|
||||
return DisplayRepresentation(stringLiteral: jsonString)
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Foundation
|
||||
import AppIntents
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct GetPeers: AppIntent {
|
||||
|
||||
static var title = LocalizedStringResource("getPeersIntentName", table: "AppIntents")
|
||||
static var description = IntentDescription(
|
||||
LocalizedStringResource("getPeersIntentDescription", table: "AppIntents")
|
||||
)
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("getPeersIntentTunnelParameterTitle", table: "AppIntents"),
|
||||
optionsProvider: TunnelsOptionsProvider()
|
||||
)
|
||||
var tunnelName: String
|
||||
|
||||
@Dependency
|
||||
var tunnelsManager: TunnelsManager
|
||||
|
||||
func perform() async throws -> some IntentResult & ReturnsValue<[String]> {
|
||||
guard let tunnelContainer = tunnelsManager.tunnel(named: tunnelName) else {
|
||||
throw GetPeersIntentError.wrongTunnel(name: tunnelName)
|
||||
}
|
||||
|
||||
guard let tunnelConfiguration = tunnelContainer.tunnelConfiguration else {
|
||||
throw GetPeersIntentError.missingConfiguration
|
||||
}
|
||||
|
||||
let publicKeys = tunnelConfiguration.peers.map { $0.publicKey.base64Key }
|
||||
return .result(value: publicKeys)
|
||||
}
|
||||
|
||||
static var parameterSummary: some ParameterSummary {
|
||||
Summary("getPeersIntentSummary \(\.$tunnelName)", table: "AppIntents")
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
enum GetPeersIntentError: Swift.Error, CustomLocalizedStringResourceConvertible {
|
||||
case wrongTunnel(name: String)
|
||||
case missingConfiguration
|
||||
|
||||
var localizedStringResource: LocalizedStringResource {
|
||||
switch self {
|
||||
case .wrongTunnel(let name):
|
||||
return LocalizedStringResource("wireguardAppIntentsWrongTunnelError \(name)", table: "AppIntents")
|
||||
case .missingConfiguration:
|
||||
return LocalizedStringResource("wireguardAppIntentsMissingConfigurationError", table: "AppIntents")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import AppIntents
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct TunnelsOptionsProvider: DynamicOptionsProvider {
|
||||
@Dependency
|
||||
var tunnelsManager: TunnelsManager
|
||||
|
||||
func results() async throws -> [String] {
|
||||
let tunnelsNames = tunnelsManager.mapTunnels { $0.name }
|
||||
return tunnelsNames
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import AppIntents
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct UpdateTunnelConfiguration: AppIntent {
|
||||
|
||||
static var title = LocalizedStringResource("updateTunnelConfigurationIntentName", table: "AppIntents")
|
||||
static var description = IntentDescription(
|
||||
LocalizedStringResource("updateTunnelConfigurationDescription", table: "AppIntents")
|
||||
)
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("updateTunnelConfigurationIntentTunnelParameterTitle", table: "AppIntents"),
|
||||
optionsProvider: TunnelsOptionsProvider()
|
||||
)
|
||||
var tunnelName: String
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("updateTunnelConfigurationIntentPeersParameterTitle", table: "AppIntents"),
|
||||
optionsProvider: AppIntentsPeerOptionsProvider()
|
||||
)
|
||||
var peers: [AppIntentsPeer]?
|
||||
|
||||
@Parameter(
|
||||
title: LocalizedStringResource("updateTunnelConfigurationIntentMergeParameterTitle", table: "AppIntents"),
|
||||
default: true
|
||||
)
|
||||
var mergeConfiguration: Bool
|
||||
|
||||
@Dependency
|
||||
var tunnelsManager: TunnelsManager
|
||||
|
||||
func perform() async throws -> some IntentResult {
|
||||
let peers = peers ?? []
|
||||
|
||||
guard let tunnelContainer = tunnelsManager.tunnel(named: tunnelName) else {
|
||||
throw AppIntentConfigurationUpdateError.wrongTunnel(name: tunnelName)
|
||||
}
|
||||
|
||||
guard let tunnelConfiguration = tunnelContainer.tunnelConfiguration else {
|
||||
throw AppIntentConfigurationUpdateError.missingConfiguration
|
||||
}
|
||||
|
||||
let newConfiguration = try buildNewConfiguration(from: tunnelConfiguration, peersUpdates: peers, mergeChanges: mergeConfiguration)
|
||||
|
||||
do {
|
||||
try await tunnelsManager.modify(tunnel: tunnelContainer, tunnelConfiguration: newConfiguration, onDemandOption: tunnelContainer.onDemandOption)
|
||||
} catch {
|
||||
wg_log(.error, message: error.localizedDescription)
|
||||
throw error
|
||||
}
|
||||
|
||||
wg_log(.debug, message: "Updated configuration of tunnel \(tunnelName)")
|
||||
|
||||
return .result()
|
||||
}
|
||||
|
||||
static var parameterSummary: some ParameterSummary {
|
||||
Summary("updateTunnelConfigurationIntentSummary \(\.$tunnelName)", table: "AppIntents") {
|
||||
\.$peers
|
||||
\.$mergeConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
private func buildNewConfiguration(from oldConfiguration: TunnelConfiguration, peersUpdates: [AppIntentsPeer], mergeChanges: Bool) throws -> TunnelConfiguration {
|
||||
var peers = oldConfiguration.peers
|
||||
|
||||
for peerUpdate in peersUpdates {
|
||||
let peerIndex: Array<PeerConfiguration>.Index
|
||||
if let foundIndex = peers.firstIndex(where: { $0.publicKey.base64Key == peerUpdate.publicKey }) {
|
||||
peerIndex = foundIndex
|
||||
if mergeChanges == false {
|
||||
peers[peerIndex] = PeerConfiguration(publicKey: peers[peerIndex].publicKey)
|
||||
}
|
||||
} else {
|
||||
wg_log(.debug, message: "Failed to find peer \(peerUpdate.publicKey) in tunnel with name \(tunnelName). Adding it.")
|
||||
|
||||
guard let pubKeyEncoded = PublicKey(base64Key: peerUpdate.publicKey) else {
|
||||
throw AppIntentConfigurationUpdateError.malformedPublicKey(key: peerUpdate.publicKey)
|
||||
}
|
||||
let newPeerConfig = PeerConfiguration(publicKey: pubKeyEncoded)
|
||||
peerIndex = peers.endIndex
|
||||
peers.append(newPeerConfig)
|
||||
}
|
||||
|
||||
if let endpointString = peerUpdate.endpoint {
|
||||
if let newEntpoint = Endpoint(from: endpointString) {
|
||||
peers[peerIndex].endpoint = newEntpoint
|
||||
} else {
|
||||
wg_log(.debug, message: "Failed to convert \(endpointString) to Endpoint")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let newConfiguration = TunnelConfiguration(name: oldConfiguration.name, interface: oldConfiguration.interface, peers: peers)
|
||||
return newConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
struct AppIntentsPeerOptionsProvider: DynamicOptionsProvider {
|
||||
|
||||
func results() async throws -> ItemCollection<AppIntentsPeer> {
|
||||
// The error thrown here is not displayed correctly to the user. A Feedback
|
||||
// has been opened (FB12098463).
|
||||
throw AppIntentConfigurationUpdateError.peerOptionsUnavailable
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
|
||||
enum AppIntentConfigurationUpdateError: Swift.Error, CustomLocalizedStringResourceConvertible {
|
||||
case wrongTunnel(name: String)
|
||||
case missingConfiguration
|
||||
case peerOptionsUnavailable
|
||||
case malformedPublicKey(key: String)
|
||||
|
||||
var localizedStringResource: LocalizedStringResource {
|
||||
switch self {
|
||||
case .wrongTunnel(let name):
|
||||
return LocalizedStringResource("wireguardAppIntentsWrongTunnelError \(name)", table: "AppIntents")
|
||||
case .missingConfiguration:
|
||||
return LocalizedStringResource("wireguardAppIntentsMissingConfigurationError", table: "AppIntents")
|
||||
case .peerOptionsUnavailable:
|
||||
return LocalizedStringResource("updateTunnelConfigurationIntentPeerOptionsUnavailableError", table: "AppIntents")
|
||||
case .malformedPublicKey(let malformedKey):
|
||||
return LocalizedStringResource("updateTunnelConfigurationIntentMalformedPublicKeyError \(malformedKey)", table: "AppIntents")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,16 +205,6 @@
|
||||
6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.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 */; };
|
||||
A25DF37029E60E870094E89B /* BuildPeerConfigurationUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */; };
|
||||
A25DF37129E60E8C0094E89B /* UpdateTunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */; };
|
||||
A25DF37229E60E8F0094E89B /* GetPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625F05029C4C627005EF23D /* GetPeers.swift */; };
|
||||
A25DF37329E60E930094E89B /* AppIntents.strings in Resources */ = {isa = PBXBuildFile; fileRef = A6E361F729D8758500FFF234 /* AppIntents.strings */; };
|
||||
A25DF37429E60E960094E89B /* TunnelsOptionsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */; };
|
||||
A625F05529C4C627005EF23D /* GetPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625F05029C4C627005EF23D /* GetPeers.swift */; };
|
||||
A6E361F829D8758500FFF234 /* AppIntents.strings in Resources */ = {isa = PBXBuildFile; fileRef = A6E361F729D8758500FFF234 /* AppIntents.strings */; };
|
||||
A6E361FA29D9821200FFF234 /* UpdateTunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */; };
|
||||
A6E361FC29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */; };
|
||||
A6E361FE29D9B18C00FFF234 /* TunnelsOptionsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -357,6 +347,8 @@
|
||||
6F6483E6229293300075BA15 /* LaunchedAtLoginDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchedAtLoginDetector.swift; sourceTree = "<group>"; };
|
||||
6F689999218043390012E523 /* WireGuard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuard-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
6F70E20D221058DF008BDFB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
6F70E20D221058DF008BDFBA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
6F70E20D221058DF008BDFC6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuardLoginItemHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6F70E23222106A31008BDFB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
6F70E23922109BEF008BDFB4 /* LoginItemHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LoginItemHelper.entitlements; sourceTree = "<group>"; };
|
||||
@@ -412,24 +404,24 @@
|
||||
6FDEF801218646B900D8FBF6 /* ZipArchive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = "<group>"; };
|
||||
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Sources/WireGuardApp/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EC /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = Sources/WireGuardApp/pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690ED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Sources/WireGuardApp/es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EF /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F2 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F4 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F6 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F7 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F8 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690FA /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690FC /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hant; path = Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hans; path = Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690FB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = Sources/WireGuardApp/id.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690FC /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F2 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Sources/WireGuardApp/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F4 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690FA /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EC /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = Sources/WireGuardApp/pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EF /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F7 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F6 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F8 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690F1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765521C90BBE002690ED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Sources/WireGuardApp/es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; };
|
||||
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
|
||||
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
|
||||
@@ -448,11 +440,6 @@
|
||||
6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorNotifier.swift; sourceTree = "<group>"; };
|
||||
6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandOption.swift; sourceTree = "<group>"; };
|
||||
6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseError+WireGuardAppError.swift"; sourceTree = "<group>"; };
|
||||
A625F05029C4C627005EF23D /* GetPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetPeers.swift; sourceTree = "<group>"; };
|
||||
A6E361F729D8758500FFF234 /* AppIntents.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = AppIntents.strings; sourceTree = "<group>"; };
|
||||
A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateTunnelConfiguration.swift; sourceTree = "<group>"; };
|
||||
A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildPeerConfigurationUpdate.swift; sourceTree = "<group>"; };
|
||||
A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsOptionsProvider.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -775,7 +762,6 @@
|
||||
6FF4AC0B211EC46F002C96EB = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A625F04C29C4C627005EF23D /* WireguardAppIntents */,
|
||||
6F70E20C221058DF008BDFB4 /* InfoPlist.strings */,
|
||||
6FE1765421C90BBE002690EA /* Localizable.strings */,
|
||||
6F5D0C432183B4A4000F85AD /* Shared */,
|
||||
@@ -827,19 +813,6 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A625F04C29C4C627005EF23D /* WireguardAppIntents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */,
|
||||
A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */,
|
||||
A625F05029C4C627005EF23D /* GetPeers.swift */,
|
||||
A6E361F729D8758500FFF234 /* AppIntents.strings */,
|
||||
A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */,
|
||||
);
|
||||
name = WireguardAppIntents;
|
||||
path = Sources/WireguardAppIntents;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXLegacyTarget section */
|
||||
@@ -987,7 +960,7 @@
|
||||
6FF4AC0C211EC46F002C96EB /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1320;
|
||||
LastSwiftUpdateCheck = 1010;
|
||||
LastUpgradeCheck = 1010;
|
||||
ORGANIZATIONNAME = "WireGuard LLC";
|
||||
TargetAttributes = {
|
||||
@@ -1105,7 +1078,6 @@
|
||||
files = (
|
||||
6FB1BD6221D2607E00A991BF /* Assets.xcassets in Resources */,
|
||||
6F70E20F221058E1008BDFB4 /* InfoPlist.strings in Resources */,
|
||||
A25DF37329E60E930094E89B /* AppIntents.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1125,7 +1097,6 @@
|
||||
6FE1765621C90BBE002690EA /* Localizable.strings in Resources */,
|
||||
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */,
|
||||
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */,
|
||||
A6E361F829D8758500FFF234 /* AppIntents.strings in Resources */,
|
||||
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */,
|
||||
6F919EDB218C65C50023B400 /* wireguard_doc_logo_64x64.png in Resources */,
|
||||
6F919EDC218C65C50023B400 /* wireguard_doc_logo_320x320.png in Resources */,
|
||||
@@ -1334,7 +1305,6 @@
|
||||
6FB1BDD121D50F5300A991BF /* ZipImporter.swift in Sources */,
|
||||
6FB1BDD221D50F5300A991BF /* ZipExporter.swift in Sources */,
|
||||
585B10642577E294004F691E /* DNSServer.swift in Sources */,
|
||||
A25DF37129E60E8C0094E89B /* UpdateTunnelConfiguration.swift in Sources */,
|
||||
585B108C2577E294004F691E /* Endpoint.swift in Sources */,
|
||||
6FBA104621D7EBFA0051C35F /* TunnelsListTableViewController.swift in Sources */,
|
||||
6FB1BDD321D50F5300A991BF /* ZipArchive.swift in Sources */,
|
||||
@@ -1372,13 +1342,11 @@
|
||||
6FE3661D21F64F6B00F78C7D /* ConfTextColorTheme.swift in Sources */,
|
||||
6F3E02E9228000F6001FE7E3 /* MainMenu.swift in Sources */,
|
||||
5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */,
|
||||
A25DF37229E60E8F0094E89B /* GetPeers.swift in Sources */,
|
||||
6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */,
|
||||
6F6483E7229293300075BA15 /* LaunchedAtLoginDetector.swift in Sources */,
|
||||
6FB1BDBF21D50F0200A991BF /* TunnelConfiguration+WgQuickConfig.swift in Sources */,
|
||||
6FADE96C2254B8C300B838A4 /* UnusableTunnelDetailViewController.swift in Sources */,
|
||||
6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */,
|
||||
A25DF37029E60E870094E89B /* BuildPeerConfigurationUpdate.swift in Sources */,
|
||||
6FB1BDC021D50F0200A991BF /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
||||
6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */,
|
||||
6FBA101821D656000051C35F /* StatusMenu.swift in Sources */,
|
||||
@@ -1389,7 +1357,6 @@
|
||||
6FBA104021D6B7040051C35F /* ErrorPresenterProtocol.swift in Sources */,
|
||||
6FCD99AA21E0E14700BA4C82 /* ButtonedDetailViewController.swift in Sources */,
|
||||
6FBA104321D6BC250051C35F /* ErrorPresenter.swift in Sources */,
|
||||
A25DF37429E60E960094E89B /* TunnelsOptionsProvider.swift in Sources */,
|
||||
6F2449E8226587B90047B9E9 /* MacAppStoreUpdateDetector.swift in Sources */,
|
||||
585B105C2577E293004F691E /* InterfaceConfiguration.swift in Sources */,
|
||||
6F907C9D224663A2003CED21 /* LogViewHelper.swift in Sources */,
|
||||
@@ -1440,7 +1407,6 @@
|
||||
6FF3527221C2616C0008484E /* ringlogger.c in Sources */,
|
||||
6F0F44CB222D55FD00B0FF04 /* EditableTextCell.swift in Sources */,
|
||||
585B105E2577E293004F691E /* PeerConfiguration.swift in Sources */,
|
||||
A6E361FA29D9821200FFF234 /* UpdateTunnelConfiguration.swift in Sources */,
|
||||
6FF3527321C2616C0008484E /* Logger.swift in Sources */,
|
||||
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
|
||||
585B108E2577E294004F691E /* x25519.c in Sources */,
|
||||
@@ -1455,10 +1421,8 @@
|
||||
6FDB6D18224CC05A00EE4BC3 /* LogViewController.swift in Sources */,
|
||||
6FFA5D952194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
||||
5F4541A921C451D100994C13 /* TunnelStatus.swift in Sources */,
|
||||
A625F05529C4C627005EF23D /* GetPeers.swift in Sources */,
|
||||
6F8F0D7422267AD2000E8335 /* ChevronCell.swift in Sources */,
|
||||
6F61F1E921B932F700483816 /* WireGuardAppError.swift in Sources */,
|
||||
A6E361FE29D9B18C00FFF234 /* TunnelsOptionsProvider.swift in Sources */,
|
||||
6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */,
|
||||
6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */,
|
||||
6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */,
|
||||
@@ -1473,7 +1437,6 @@
|
||||
6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */,
|
||||
6B62E45F220A6FA900EF34A6 /* PrivateDataConfirmation.swift in Sources */,
|
||||
6F5A2B4821AFF49A0081EDD8 /* FileManager+Extension.swift in Sources */,
|
||||
A6E361FC29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift in Sources */,
|
||||
5F45418C21C2D48200994C13 /* TunnelEditKeyValueCell.swift in Sources */,
|
||||
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */,
|
||||
585B107E2577E294004F691E /* PrivateKey.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user