wireguard-apple/WireGuard/Shared/Model/NETunnelProviderProtocol+Ex...

71 lines
2.8 KiB
Swift

// SPDX-License-Identifier: MIT
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
import NetworkExtension
enum PacketTunnelProviderError: String, Error {
case savedProtocolConfigurationIsInvalid
case dnsResolutionFailure
case couldNotStartBackend
case couldNotDetermineFileDescriptor
case couldNotSetNetworkSettings
}
extension NETunnelProviderProtocol {
convenience init?(tunnelConfiguration: TunnelConfiguration, previouslyFrom old: NEVPNProtocol? = nil) {
self.init()
guard let name = tunnelConfiguration.name else { return nil }
guard let appId = Bundle.main.bundleIdentifier else { return nil }
providerBundleIdentifier = "\(appId).network-extension"
passwordReference = Keychain.makeReference(containing: tunnelConfiguration.asWgQuickConfig(), called: name, previouslyReferencedBy: old?.passwordReference)
if passwordReference == nil {
return nil
}
let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
if endpoints.count == 1 {
serverAddress = endpoints[0].stringRepresentation
} else if endpoints.isEmpty {
serverAddress = "Unspecified"
} else {
serverAddress = "Multiple endpoints"
}
}
func asTunnelConfiguration(called name: String? = nil) -> TunnelConfiguration? {
if let passwordReference = passwordReference,
let config = Keychain.openReference(called: passwordReference) {
return try? TunnelConfiguration(fromWgQuickConfig: config, called: name)
}
if let oldConfig = providerConfiguration?["WgQuickConfig"] as? String {
return try? TunnelConfiguration(fromWgQuickConfig: oldConfig, called: name)
}
return nil
}
func destroyConfigurationReference() {
guard let ref = passwordReference else { return }
Keychain.deleteReference(called: ref)
}
func verifyConfigurationReference() -> Bool {
guard let ref = passwordReference else { return false }
return Keychain.verifyReference(called: ref)
}
@discardableResult
func migrateConfigurationIfNeeded(called name: String) -> Bool {
/* This is how we did things before we switched to putting items
* in the keychain. But it's still useful to keep the migration
* around so that .mobileconfig files are easier.
*/
guard let oldConfig = providerConfiguration?["WgQuickConfig"] as? String else { return false }
providerConfiguration = nil
guard passwordReference == nil else { return true }
wg_log(.debug, message: "Migrating tunnel configuration '\(name)'")
passwordReference = Keychain.makeReference(containing: oldConfig, called: name)
return true
}
}