From 922a715bfd13b71462e2c2f50cb19a557f8dbda2 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Tue, 9 Apr 2019 22:45:39 +0200 Subject: [PATCH] Inject external resources into configuration --- Passepartout/Sources/GroupConstants.swift | 2 ++ .../Profiles/ProviderConnectionProfile.swift | 8 +++++- .../Sources/Services/Infrastructure.swift | 4 +++ .../Services/InfrastructurePreset.swift | 26 +++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Passepartout/Sources/GroupConstants.swift b/Passepartout/Sources/GroupConstants.swift index 54cf1574..a6120a51 100644 --- a/Passepartout/Sources/GroupConstants.swift +++ b/Passepartout/Sources/GroupConstants.swift @@ -73,6 +73,8 @@ public class GroupConstants { try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) return url }() + + public static let externalURL = cachesURL.appendingPathComponent("External") } public class VPN { diff --git a/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift index 9516ed4c..b83b3641 100644 --- a/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift +++ b/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift @@ -120,6 +120,12 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable { builder.shouldDebug = configuration.shouldDebug builder.debugLogFormat = configuration.debugLogFormat builder.masksPrivateData = configuration.masksPrivateData + + do { + try preset.injectExternalConfiguration(&builder, with: name, pool: pool) + } catch { + fatalError("Could not find external preset resources") + } if let address = manualAddress { builder.prefersResolvedAddresses = true @@ -137,7 +143,7 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable { } else { // restrict "Any" protocol to UDP, unless there are no UDP endpoints - let allEndpoints = preset.configuration.sessionConfiguration.endpointProtocols + let allEndpoints = builder.sessionConfiguration.endpointProtocols var endpoints = allEndpoints?.filter { $0.socketType == .udp } if endpoints?.isEmpty ?? true { endpoints = allEndpoints diff --git a/Passepartout/Sources/Services/Infrastructure.swift b/Passepartout/Sources/Services/Infrastructure.swift index 260425d1..2a72d041 100644 --- a/Passepartout/Sources/Services/Infrastructure.swift +++ b/Passepartout/Sources/Services/Infrastructure.swift @@ -42,6 +42,10 @@ public struct Infrastructure: Codable { return rawValue.lowercased() } + public var externalURL: URL { + return GroupConstants.App.externalURL.appendingPathComponent(webName) + } + public static func <(lhs: Name, rhs: Name) -> Bool { return lhs.webName < rhs.webName } diff --git a/Passepartout/Sources/Services/InfrastructurePreset.swift b/Passepartout/Sources/Services/InfrastructurePreset.swift index 29b25907..d37d581d 100644 --- a/Passepartout/Sources/Services/InfrastructurePreset.swift +++ b/Passepartout/Sources/Services/InfrastructurePreset.swift @@ -96,6 +96,32 @@ public struct InfrastructurePreset: Codable { return configuration.sessionConfiguration.endpointProtocols?.firstIndex(of: proto) != nil } + public func injectExternalConfiguration(_ configuration: inout TunnelKitProvider.ConfigurationBuilder, with name: Infrastructure.Name, pool: Pool) throws { + guard let external = external, !external.isEmpty else { + return + } + + let baseURL = name.externalURL + + var sessionBuilder = configuration.sessionConfiguration.builder() + if let pattern = external[.ca] { + let filename = pattern.replacingOccurrences(of: "${id}", with: pool.id) + let caURL = baseURL.appendingPathComponent(filename) + sessionBuilder.ca = CryptoContainer(pem: try String(contentsOf: caURL)) + } + if let pattern = external[.wrapKeyData] { + let filename = pattern.replacingOccurrences(of: "${id}", with: pool.id) + let tlsKeyURL = baseURL.appendingPathComponent(filename) + if let dummyWrap = sessionBuilder.tlsWrap { + let file = try String(contentsOf: tlsKeyURL) + if let staticKey = StaticKey(file: file, direction: .client) { + sessionBuilder.tlsWrap = SessionProxy.TLSWrap(strategy: dummyWrap.strategy, key: staticKey) + } + } + } + configuration.sessionConfiguration = sessionBuilder.build() + } + // MARK: Codable public init(from decoder: Decoder) throws {