diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-02-04 07:37:26 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-02-06 06:20:23 +0100 |
commit | 8c3557a90723c20329cbdc7eff676787bfcd5872 (patch) | |
tree | 2dd57fd59c1621adcc8784cbf9dd6dbe60793b60 /WireGuard/Shared/Model | |
parent | TunnelsManager: cache access to configuration object (diff) | |
download | wireguard-apple-8c3557a90723c20329cbdc7eff676787bfcd5872.tar.xz wireguard-apple-8c3557a90723c20329cbdc7eff676787bfcd5872.zip |
Keychain: store configurations in keychain instead of providerConfig
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r-- | WireGuard/Shared/Model/LegacyConfigMigration.swift | 32 | ||||
-rw-r--r-- | WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift | 38 |
2 files changed, 49 insertions, 21 deletions
diff --git a/WireGuard/Shared/Model/LegacyConfigMigration.swift b/WireGuard/Shared/Model/LegacyConfigMigration.swift index 16792fa..583e914 100644 --- a/WireGuard/Shared/Model/LegacyConfigMigration.swift +++ b/WireGuard/Shared/Model/LegacyConfigMigration.swift @@ -174,20 +174,32 @@ final class LegacyTunnelConfiguration: LegacyModel { extension NETunnelProviderProtocol { @discardableResult - func migrateConfigurationIfNeeded() -> Bool { - guard let configurationVersion = providerConfiguration?["tunnelConfigurationVersion"] as? Int else { return false } - if configurationVersion == 1 { - migrateFromConfigurationV1() - } else { - fatalError("No migration from configuration version \(configurationVersion) exists.") + func migrateConfigurationIfNeeded(called name: String) -> Bool { + var ret = false + if migrateFromConfigurationV1() { + ret = true } + if migrateFromConfigurationV2(called: name) { + ret = true + } + return ret + } + + private func migrateFromConfigurationV1() -> Bool { + guard let configurationVersion = providerConfiguration?["tunnelConfigurationVersion"] as? Int else { return false } + guard configurationVersion == 1 else { return false } + guard let serializedTunnelConfiguration = providerConfiguration?["tunnelConfiguration"] as? Data else { return false } + guard let configuration = try? JSONDecoder().decode(LegacyTunnelConfiguration.self, from: serializedTunnelConfiguration) else { return false } + providerConfiguration = ["WgQuickConfig": configuration.migrated.asWgQuickConfig()] return true } - private func migrateFromConfigurationV1() { - guard let serializedTunnelConfiguration = providerConfiguration?["tunnelConfiguration"] as? Data else { return } - guard let configuration = try? JSONDecoder().decode(LegacyTunnelConfiguration.self, from: serializedTunnelConfiguration) else { return } - providerConfiguration = [Keys.wgQuickConfig.rawValue: configuration.migrated.asWgQuickConfig()] + private func migrateFromConfigurationV2(called name: String) -> Bool { + guard let oldConfig = providerConfiguration?["WgQuickConfig"] as? String else { return false } + providerConfiguration = nil + guard passwordReference == nil else { return true } + passwordReference = Keychain.makeReference(containing: oldConfig, called: name) + return true } } diff --git a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift b/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift index 7b3142e..3b7cd1e 100644 --- a/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift +++ b/WireGuard/Shared/Model/NETunnelProviderProtocol+Extension.swift @@ -12,17 +12,16 @@ enum PacketTunnelProviderError: String, Error { } extension NETunnelProviderProtocol { - - enum Keys: String { - case wgQuickConfig = "WgQuickConfig" - } - - convenience init?(tunnelConfiguration: TunnelConfiguration) { + convenience init?(tunnelConfiguration: TunnelConfiguration, previouslyFrom old: NEVPNProtocol? = nil) { self.init() - let appId = Bundle.main.bundleIdentifier! + guard let name = tunnelConfiguration.name else { return nil } + guard let appId = Bundle.main.bundleIdentifier else { return nil } providerBundleIdentifier = "\(appId).network-extension" - providerConfiguration = [Keys.wgQuickConfig.rawValue: tunnelConfiguration.asWgQuickConfig()] + 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 { @@ -35,9 +34,26 @@ extension NETunnelProviderProtocol { } func asTunnelConfiguration(called name: String? = nil) -> TunnelConfiguration? { - migrateConfigurationIfNeeded() - guard let serializedConfig = providerConfiguration?[Keys.wgQuickConfig.rawValue] as? String else { return nil } - return try? TunnelConfiguration(fromWgQuickConfig: serializedConfig, called: name) + migrateConfigurationIfNeeded(called: name ?? "unknown") + //TODO: in the case where migrateConfigurationIfNeeded is called by the network extension, + // before the app has started, and when there is, in fact, configuration that needs to be + // put into the keychain, this will generate one new keychain item every time it is started, + // until finally the app is open. Would it be possible to call saveToPreferences here? Or is + // that generally not available to network extensions? In which case, what should our + // behavior be? + + guard let passwordReference = passwordReference else { return nil } + guard let config = Keychain.openReference(called: passwordReference) else { return nil } + return try? TunnelConfiguration(fromWgQuickConfig: config, called: name) } + func destroyConfigurationReference() { + guard let ref = passwordReference else { return } + Keychain.deleteReference(called: ref) + } + + func verifyConfigurationReference() -> Data? { + guard let ref = passwordReference else { return nil } + return Keychain.verifyReference(called: ref) ? ref : nil + } } |