Merge branch 'refactor-tunnel-configuration'
This commit is contained in:
commit
205bef822e
|
@ -33,10 +33,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
|
|||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
override init() {
|
||||
AppConstants.Log.configure()
|
||||
super.init()
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
InfrastructureFactory.shared.loadCache()
|
||||
Theme.current.applyAppearance()
|
||||
|
||||
// Override point for customization after application launch.
|
||||
let splitViewController = window!.rootViewController as! UISplitViewController
|
||||
|
@ -50,8 +54,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
|
|||
// splitViewController.preferredDisplayMode = .primaryOverlay
|
||||
}
|
||||
|
||||
Theme.current.applyAppearance()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import Foundation
|
|||
import TunnelKit
|
||||
|
||||
protocol ConfigurationModificationDelegate: class {
|
||||
func configuration(didUpdate newConfiguration: TunnelKitProvider.Configuration)
|
||||
func configuration(didUpdate newConfiguration: SessionProxy.Configuration)
|
||||
|
||||
func configurationShouldReinstall()
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ class ConfigurationViewController: UIViewController, TableModelHost {
|
|||
|
||||
private lazy var itemRefresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(refresh))
|
||||
|
||||
var initialConfiguration: TunnelKitProvider.Configuration!
|
||||
var initialConfiguration: SessionProxy.Configuration!
|
||||
|
||||
private lazy var configuration: TunnelKitProvider.ConfigurationBuilder = initialConfiguration.builder()
|
||||
private lazy var configuration: SessionProxy.ConfigurationBuilder = initialConfiguration.builder()
|
||||
|
||||
var isEditable = false
|
||||
|
||||
|
@ -129,12 +129,12 @@ class ConfigurationViewController: UIViewController, TableModelHost {
|
|||
log.warning("Could not parse original configuration: \(e)")
|
||||
return
|
||||
}
|
||||
initialConfiguration = originalConfiguration
|
||||
configuration = originalConfiguration.builder()
|
||||
initialConfiguration = originalConfiguration.sessionConfiguration
|
||||
configuration = initialConfiguration.builder()
|
||||
itemRefresh.isEnabled = true // allow for manual reconnection
|
||||
tableView.reloadData()
|
||||
|
||||
delegate?.configuration(didUpdate: originalConfiguration)
|
||||
delegate?.configuration(didUpdate: initialConfiguration)
|
||||
}
|
||||
|
||||
@IBAction private func refresh() {
|
||||
|
@ -270,8 +270,8 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
|
|||
case .keepAlive:
|
||||
cell.leftText = L10n.Configuration.Cells.KeepAlive.caption
|
||||
let V = L10n.Configuration.Cells.KeepAlive.Value.self
|
||||
if let keepAlive = configuration.keepAliveSeconds, keepAlive > 0 {
|
||||
cell.rightText = V.seconds(keepAlive)
|
||||
if let keepAlive = configuration.keepAliveInterval, keepAlive > 0 {
|
||||
cell.rightText = V.seconds(Int(keepAlive))
|
||||
} else {
|
||||
cell.rightText = V.never
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
|
|||
case .renegSeconds:
|
||||
cell.leftText = L10n.Configuration.Cells.RenegotiationSeconds.caption
|
||||
let V = L10n.Configuration.Cells.RenegotiationSeconds.Value.self
|
||||
if let reneg = configuration.renegotiatesAfterSeconds, reneg > 0 {
|
||||
if let reneg = configuration.renegotiatesAfter, reneg > 0 {
|
||||
cell.rightText = V.after(TimeInterval(reneg).localized)
|
||||
} else {
|
||||
cell.rightText = V.never
|
||||
|
|
|
@ -129,7 +129,7 @@ extension ProviderPresetViewController: UITableViewDataSource, UITableViewDelega
|
|||
case .techDetails:
|
||||
let vc = StoryboardScene.Main.configurationIdentifier.instantiate()
|
||||
vc.title = preset.name
|
||||
vc.initialConfiguration = preset.configuration
|
||||
vc.initialConfiguration = preset.configuration.sessionConfiguration
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ class ServiceViewController: UIViewController, TableModelHost {
|
|||
case .hostParametersSegueIdentifier:
|
||||
let vc = destination as? ConfigurationViewController
|
||||
vc?.title = L10n.Service.Cells.Host.Parameters.caption
|
||||
vc?.initialConfiguration = uncheckedHostProfile.parameters
|
||||
vc?.initialConfiguration = uncheckedHostProfile.parameters.sessionConfiguration
|
||||
vc?.isEditable = true
|
||||
vc?.originalConfigurationURL = ProfileConfigurationFactory.shared.configurationURL(for: uncheckedHostProfile)
|
||||
vc?.delegate = self
|
||||
|
@ -595,10 +595,10 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = L10n.Service.Cells.Host.Parameters.caption
|
||||
let V = L10n.Service.Cells.Host.Parameters.Value.self
|
||||
if !parameters.cipher.embedsDigest {
|
||||
cell.rightText = V.cipherDigest(parameters.cipher.genericName, parameters.digest.genericName)
|
||||
if !parameters.sessionConfiguration.cipher.embedsDigest {
|
||||
cell.rightText = V.cipherDigest(parameters.sessionConfiguration.cipher.genericName, parameters.sessionConfiguration.digest.genericName)
|
||||
} else {
|
||||
cell.rightText = V.cipher(parameters.cipher.genericName)
|
||||
cell.rightText = V.cipher(parameters.sessionConfiguration.cipher.genericName)
|
||||
}
|
||||
return cell
|
||||
|
||||
|
@ -973,9 +973,11 @@ extension ServiceViewController: TrustedNetworksModelDelegate {
|
|||
// MARK: -
|
||||
|
||||
extension ServiceViewController: ConfigurationModificationDelegate {
|
||||
func configuration(didUpdate newConfiguration: TunnelKitProvider.Configuration) {
|
||||
func configuration(didUpdate newConfiguration: SessionProxy.Configuration) {
|
||||
if let hostProfile = profile as? HostConnectionProfile {
|
||||
hostProfile.parameters = newConfiguration
|
||||
var builder = hostProfile.parameters.builder()
|
||||
builder.sessionConfiguration = newConfiguration
|
||||
hostProfile.parameters = builder.build()
|
||||
}
|
||||
reloadSelectedRow()
|
||||
}
|
||||
|
|
|
@ -41,13 +41,16 @@
|
|||
0E6BE13A20CFB76800A6DD36 /* ApplicationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */; };
|
||||
0E6BE13F20CFBAB300A6DD36 /* DebugLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */; };
|
||||
0E89DFC5213DF7AE00741BA1 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFC4213DF7AE00741BA1 /* Preferences.swift */; };
|
||||
0E89DFC8213E8FC500741BA1 /* TunnelKitProvider+Communication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFC7213E8FC500741BA1 /* TunnelKitProvider+Communication.swift */; };
|
||||
0E89DFC8213E8FC500741BA1 /* SessionProxy+Communication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */; };
|
||||
0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; };
|
||||
0E89DFD0213F223400741BA1 /* Wizard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCF213F223400741BA1 /* Wizard.swift */; };
|
||||
0E8D97E221388B52006FB4A0 /* InfrastructurePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */; };
|
||||
0E8D97E521389277006FB4A0 /* pia.json in Resources */ = {isa = PBXBuildFile; fileRef = 0E8D97E421389276006FB4A0 /* pia.json */; };
|
||||
0EAAD71920E6669A0088754A /* GroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE8DED20C93E4C004C739C /* GroupConstants.swift */; };
|
||||
0EB60FDA2111136E00AD27F3 /* UITextView+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */; };
|
||||
0EBBE8F221822B4D00106008 /* ConnectionServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */; };
|
||||
0EBBE8F321822B4D00106008 /* ConnectionService.json in Resources */ = {isa = PBXBuildFile; fileRef = 0EBBE8F121822B4D00106008 /* ConnectionService.json */; };
|
||||
0EBBE8F52182361800106008 /* ConnectionService+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBBE8F42182361700106008 /* ConnectionService+Migration.swift */; };
|
||||
0EBE3A79213C4E5500BFA2F5 /* OrganizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3A78213C4E5400BFA2F5 /* OrganizerViewController.swift */; };
|
||||
0EBE3A84213C6ADE00BFA2F5 /* InfrastructureFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */; };
|
||||
0EBE3A90213C6F4000BFA2F5 /* TrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3A8F213C6F4000BFA2F5 /* TrustPolicy.swift */; };
|
||||
|
@ -159,12 +162,15 @@
|
|||
0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationError.swift; sourceTree = "<group>"; };
|
||||
0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugLogViewController.swift; sourceTree = "<group>"; };
|
||||
0E89DFC4213DF7AE00741BA1 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||
0E89DFC7213E8FC500741BA1 /* TunnelKitProvider+Communication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+Communication.swift"; sourceTree = "<group>"; };
|
||||
0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+Communication.swift"; sourceTree = "<group>"; };
|
||||
0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardProviderViewController.swift; sourceTree = "<group>"; };
|
||||
0E89DFCF213F223400741BA1 /* Wizard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wizard.swift; sourceTree = "<group>"; };
|
||||
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructurePreset.swift; sourceTree = "<group>"; };
|
||||
0E8D97E421389276006FB4A0 /* pia.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = pia.json; sourceTree = "<group>"; };
|
||||
0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Search.swift"; sourceTree = "<group>"; };
|
||||
0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionServiceTests.swift; sourceTree = "<group>"; };
|
||||
0EBBE8F121822B4D00106008 /* ConnectionService.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ConnectionService.json; sourceTree = "<group>"; };
|
||||
0EBBE8F42182361700106008 /* ConnectionService+Migration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConnectionService+Migration.swift"; sourceTree = "<group>"; };
|
||||
0EBE3A78213C4E5400BFA2F5 /* OrganizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrganizerViewController.swift; sourceTree = "<group>"; };
|
||||
0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructureFactory.swift; sourceTree = "<group>"; };
|
||||
0EBE3A8F213C6F4000BFA2F5 /* TrustPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustPolicy.swift; sourceTree = "<group>"; };
|
||||
|
@ -324,10 +330,12 @@
|
|||
0E57F64F20C83FC7008323CF /* PassepartoutTests-iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0EBBE8F121822B4D00106008 /* ConnectionService.json */,
|
||||
0ED38AE2213F517D0004D387 /* pia-hungary.ovpn */,
|
||||
0E57F65220C83FC7008323CF /* Info.plist */,
|
||||
0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */,
|
||||
0ED38AE0213F51370004D387 /* FileConfigurationTests.swift */,
|
||||
0ED31C2620CF257C0027975F /* InfrastructureTests.swift */,
|
||||
0E57F65220C83FC7008323CF /* Info.plist */,
|
||||
);
|
||||
path = "PassepartoutTests-iOS";
|
||||
sourceTree = "<group>";
|
||||
|
@ -377,12 +385,13 @@
|
|||
0EBE3A9E213DC1A100BFA2F5 /* ConnectionProfile.swift */,
|
||||
0EBE3AAB213DEB8800BFA2F5 /* ConnectionProfileHolder.swift */,
|
||||
0EBE3A9F213DC1A100BFA2F5 /* ConnectionService.swift */,
|
||||
0EBBE8F42182361700106008 /* ConnectionService+Migration.swift */,
|
||||
0EDE8DE620C93945004C739C /* Credentials.swift */,
|
||||
0EC7F20420E24308004EA58E /* DebugLog.swift */,
|
||||
0ED38AE621404F100004D387 /* EndpointDataSource.swift */,
|
||||
0E89DFC4213DF7AE00741BA1 /* Preferences.swift */,
|
||||
0E2D11B9217DBEDE0096822C /* ProfileConfigurationFactory.swift */,
|
||||
0E89DFC7213E8FC500741BA1 /* TunnelKitProvider+Communication.swift */,
|
||||
0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */,
|
||||
0E2B494120FD16540094784C /* TransientStore.swift */,
|
||||
0E4C9CB820DB9BC600A0C59C /* TrustedNetworks.swift */,
|
||||
0EBE3A8F213C6F4000BFA2F5 /* TrustPolicy.swift */,
|
||||
|
@ -654,6 +663,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0ED38AE3213F517D0004D387 /* pia-hungary.ovpn in Resources */,
|
||||
0EBBE8F321822B4D00106008 /* ConnectionService.json in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -816,6 +826,7 @@
|
|||
0E1066C920E0F84A004F98B7 /* Cells.swift in Sources */,
|
||||
0EBE3AA6213DC1B000BFA2F5 /* ProviderConnectionProfile.swift in Sources */,
|
||||
0E3DA371215CB5BF00B40FC9 /* VersionViewController.swift in Sources */,
|
||||
0EBBE8F52182361800106008 /* ConnectionService+Migration.swift in Sources */,
|
||||
0E39BCF3214DA9310035E9DE /* AppConstants.swift in Sources */,
|
||||
0E05C5D620D1645F006EE732 /* SwiftGen+Storyboards.swift in Sources */,
|
||||
0E2B494220FD16540094784C /* TransientStore.swift in Sources */,
|
||||
|
@ -837,7 +848,7 @@
|
|||
0E2D11BA217DBEDE0096822C /* ProfileConfigurationFactory.swift in Sources */,
|
||||
0EBE3A90213C6F4000BFA2F5 /* TrustPolicy.swift in Sources */,
|
||||
0E6BE13F20CFBAB300A6DD36 /* DebugLogViewController.swift in Sources */,
|
||||
0E89DFC8213E8FC500741BA1 /* TunnelKitProvider+Communication.swift in Sources */,
|
||||
0E89DFC8213E8FC500741BA1 /* SessionProxy+Communication.swift in Sources */,
|
||||
0ED38AEA214054A50004D387 /* OptionViewController.swift in Sources */,
|
||||
0EFD943E215BE10800529B64 /* IssueReporter.swift in Sources */,
|
||||
0EBE3AAC213DEB8800BFA2F5 /* ConnectionProfileHolder.swift in Sources */,
|
||||
|
@ -866,6 +877,7 @@
|
|||
files = (
|
||||
0ED38AE1213F51370004D387 /* FileConfigurationTests.swift in Sources */,
|
||||
0ED31C2720CF257C0027975F /* InfrastructureTests.swift in Sources */,
|
||||
0EBBE8F221822B4D00106008 /* ConnectionServiceTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -41,15 +41,14 @@ class AppConstants {
|
|||
}
|
||||
|
||||
class VPN {
|
||||
static func tunnelConfiguration() -> TunnelKitProvider.Configuration {
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(ca: CryptoContainer(pem: ""))
|
||||
static func baseConfiguration() -> TunnelKitProvider.Configuration {
|
||||
let sessionBuilder = SessionProxy.ConfigurationBuilder(ca: CryptoContainer(pem: ""))
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||
builder.mtu = 1250
|
||||
builder.shouldDebug = true
|
||||
// builder.debugLogFormat = "$Dyyyy-MM-dd HH:mm:ss.SSS$d $L $N.$F:$l - $M"
|
||||
// builder.debugLogFormat = "$DHH:mm:ss$d $N.$F:$l - $M"
|
||||
builder.debugLogFormat = Log.debugFormat
|
||||
builder.debugLogKey = "LastVPNLog"
|
||||
builder.lastErrorKey = "LastVPNError"
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
|
|
|
@ -35,4 +35,6 @@ enum ApplicationError: Error {
|
|||
case emptyRemotes
|
||||
|
||||
case unsupportedConfiguration(option: String)
|
||||
|
||||
case migration
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// ConnectionService+Migration.swift
|
||||
// Passepartout
|
||||
//
|
||||
// Created by Davide De Rosa on 10/25/18.
|
||||
// Copyright (c) 2018 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/keeshux
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftyBeaver
|
||||
|
||||
private let log = SwiftyBeaver.self
|
||||
|
||||
extension ConnectionService {
|
||||
static func migrateJSON(at from: URL, to: URL) {
|
||||
do {
|
||||
let newData = try migrateJSON(at: from)
|
||||
// log.verbose(String(data: newData, encoding: .utf8)!)
|
||||
try newData.write(to: to)
|
||||
} catch let e {
|
||||
log.warning("Could not migrate service: \(e)")
|
||||
}
|
||||
}
|
||||
|
||||
static func migrateJSON(at from: URL) throws -> Data {
|
||||
let data = try Data(contentsOf: from)
|
||||
guard var json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
|
||||
throw ApplicationError.migration
|
||||
}
|
||||
|
||||
// replace migration logic here
|
||||
let build = json["build"] as? Int ?? 0
|
||||
if build <= 1084 {
|
||||
try migrateToWrappedSessionConfiguration(&json)
|
||||
try migrateToBaseConfiguration(&json)
|
||||
try migrateToBuildNumber(&json)
|
||||
}
|
||||
|
||||
return try JSONSerialization.data(withJSONObject: json, options: [])
|
||||
}
|
||||
|
||||
static func migrateToWrappedSessionConfiguration(_ json: inout [String: Any]) throws {
|
||||
guard let profiles = json["profiles"] as? [[String: Any]] else {
|
||||
throw ApplicationError.migration
|
||||
}
|
||||
var newProfiles: [[String: Any]] = []
|
||||
for var container in profiles {
|
||||
guard var hostProfile = container["host"] as? [String: Any] else {
|
||||
newProfiles.append(container)
|
||||
continue
|
||||
}
|
||||
guard var parameters = hostProfile["parameters"] as? [String: Any] else {
|
||||
throw ApplicationError.migration
|
||||
}
|
||||
guard parameters["sessionConfiguration"] == nil else {
|
||||
newProfiles.append(container)
|
||||
continue
|
||||
}
|
||||
migrateSessionConfiguration(in: ¶meters)
|
||||
hostProfile["parameters"] = parameters
|
||||
container["host"] = hostProfile
|
||||
newProfiles.append(container)
|
||||
}
|
||||
json["profiles"] = newProfiles
|
||||
}
|
||||
|
||||
static func migrateToBaseConfiguration(_ json: inout [String: Any]) throws {
|
||||
guard var baseConfiguration = json["tunnelConfiguration"] as? [String: Any] else {
|
||||
return
|
||||
}
|
||||
migrateSessionConfiguration(in: &baseConfiguration)
|
||||
json["baseConfiguration"] = baseConfiguration
|
||||
json.removeValue(forKey: "tunnelConfiguration")
|
||||
}
|
||||
|
||||
static func migrateToBuildNumber(_ json: inout [String: Any]) throws {
|
||||
json["build"] = GroupConstants.App.buildNumber
|
||||
}
|
||||
|
||||
// MARK: Helpers
|
||||
|
||||
private static func migrateSessionConfiguration(in map: inout [String: Any]) {
|
||||
let scKeys = [
|
||||
"cipher",
|
||||
"digest",
|
||||
"ca",
|
||||
"clientCertificate",
|
||||
"clientKey",
|
||||
"compressionFraming",
|
||||
"tlsWrap",
|
||||
// "keepAliveSeconds", // renamed
|
||||
// "renegotiatesAfterSeconds", // renamed
|
||||
"usesPIAPatches"
|
||||
]
|
||||
var sessionConfiguration: [String: Any] = [:]
|
||||
for key in scKeys {
|
||||
guard let value = map[key] else {
|
||||
continue
|
||||
}
|
||||
sessionConfiguration[key] = value
|
||||
map.removeValue(forKey: key)
|
||||
}
|
||||
if let value = map["keepAliveSeconds"] {
|
||||
sessionConfiguration["keepAliveInterval"] = value
|
||||
}
|
||||
if let value = map["renegotiatesAfterSeconds"] {
|
||||
sessionConfiguration["renegotiatesAfter"] = value
|
||||
}
|
||||
map["sessionConfiguration"] = sessionConfiguration
|
||||
}
|
||||
}
|
|
@ -38,9 +38,11 @@ protocol ConnectionServiceDelegate: class {
|
|||
|
||||
class ConnectionService: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case build
|
||||
|
||||
case appGroup
|
||||
|
||||
case tunnelConfiguration
|
||||
case baseConfiguration
|
||||
|
||||
case profiles
|
||||
|
||||
|
@ -49,13 +51,15 @@ class ConnectionService: Codable {
|
|||
case preferences
|
||||
}
|
||||
|
||||
private var build: Int
|
||||
|
||||
private let appGroup: String
|
||||
|
||||
private let defaults: UserDefaults
|
||||
|
||||
private let keychain: Keychain
|
||||
|
||||
var tunnelConfiguration: TunnelKitProvider.Configuration
|
||||
var baseConfiguration: TunnelKitProvider.Configuration
|
||||
|
||||
private var profiles: [String: ConnectionProfile]
|
||||
|
||||
|
@ -83,15 +87,16 @@ class ConnectionService: Codable {
|
|||
|
||||
weak var delegate: ConnectionServiceDelegate?
|
||||
|
||||
init(withAppGroup appGroup: String, tunnelConfiguration: TunnelKitProvider.Configuration) {
|
||||
init(withAppGroup appGroup: String, baseConfiguration: TunnelKitProvider.Configuration) {
|
||||
guard let defaults = UserDefaults(suiteName: appGroup) else {
|
||||
fatalError("No entitlements for group '\(appGroup)'")
|
||||
}
|
||||
build = GroupConstants.App.buildNumber
|
||||
self.appGroup = appGroup
|
||||
self.defaults = defaults
|
||||
keychain = Keychain(group: appGroup)
|
||||
|
||||
self.tunnelConfiguration = tunnelConfiguration
|
||||
self.baseConfiguration = baseConfiguration
|
||||
profiles = [:]
|
||||
activeProfileId = nil
|
||||
preferences = EditablePreferences()
|
||||
|
@ -105,11 +110,12 @@ class ConnectionService: Codable {
|
|||
guard let defaults = UserDefaults(suiteName: appGroup) else {
|
||||
fatalError("No entitlements for group '\(appGroup)'")
|
||||
}
|
||||
build = try container.decode(Int.self, forKey: .build)
|
||||
self.appGroup = appGroup
|
||||
self.defaults = defaults
|
||||
keychain = Keychain(group: appGroup)
|
||||
|
||||
tunnelConfiguration = try container.decode(TunnelKitProvider.Configuration.self, forKey: .tunnelConfiguration)
|
||||
baseConfiguration = try container.decode(TunnelKitProvider.Configuration.self, forKey: .baseConfiguration)
|
||||
let profilesArray = try container.decode([ConnectionProfileHolder].self, forKey: .profiles).map { $0.contained }
|
||||
var profiles: [String: ConnectionProfile] = [:]
|
||||
profilesArray.forEach {
|
||||
|
@ -124,9 +130,12 @@ class ConnectionService: Codable {
|
|||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
build = GroupConstants.App.buildNumber
|
||||
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(build, forKey: .build)
|
||||
try container.encode(appGroup, forKey: .appGroup)
|
||||
try container.encode(tunnelConfiguration, forKey: .tunnelConfiguration)
|
||||
try container.encode(baseConfiguration, forKey: .baseConfiguration)
|
||||
try container.encode(profiles.map { ConnectionProfileHolder($0.value) }, forKey: .profiles)
|
||||
try container.encodeIfPresent(activeProfileId, forKey: .activeProfileId)
|
||||
try container.encode(preferences, forKey: .preferences)
|
||||
|
@ -224,7 +233,7 @@ class ConnectionService: Codable {
|
|||
}
|
||||
}
|
||||
|
||||
let cfg = try profile.generate(from: tunnelConfiguration, preferences: preferences)
|
||||
let cfg = try profile.generate(from: baseConfiguration, preferences: preferences)
|
||||
let protocolConfiguration = try cfg.generatedTunnelProtocol(
|
||||
withBundleIdentifier: GroupConstants.App.tunnelIdentifier,
|
||||
appGroup: appGroup,
|
||||
|
@ -267,24 +276,15 @@ class ConnectionService: Codable {
|
|||
}
|
||||
|
||||
var vpnLog: String {
|
||||
return tunnelConfiguration.existingLog(in: appGroup) ?? ""
|
||||
return baseConfiguration.existingLog(in: appGroup) ?? ""
|
||||
}
|
||||
|
||||
var vpnLastError: TunnelKitProvider.ProviderError? {
|
||||
guard let key = tunnelConfiguration.lastErrorKey else {
|
||||
return nil
|
||||
}
|
||||
guard let rawValue = defaults.string(forKey: key) else {
|
||||
return nil
|
||||
}
|
||||
return TunnelKitProvider.ProviderError(rawValue: rawValue)
|
||||
return baseConfiguration.lastError(in: appGroup)
|
||||
}
|
||||
|
||||
func clearVpnLastError() {
|
||||
guard let key = tunnelConfiguration.lastErrorKey else {
|
||||
return
|
||||
}
|
||||
defaults.removeObject(forKey: key)
|
||||
baseConfiguration.clearLastError(in: appGroup)
|
||||
}
|
||||
|
||||
// func eraseVpnLog() {
|
||||
|
|
|
@ -34,7 +34,8 @@ class HostConnectionProfile: ConnectionProfile, Codable, Equatable {
|
|||
init(title: String, hostname: String) {
|
||||
self.title = title
|
||||
self.hostname = hostname
|
||||
parameters = TunnelKitProvider.ConfigurationBuilder(ca: CryptoContainer(pem: "")).build()
|
||||
let sessionConfiguration = SessionProxy.ConfigurationBuilder(ca: CryptoContainer(pem: "")).build()
|
||||
parameters = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration).build()
|
||||
}
|
||||
|
||||
// MARK: ConnectionProfile
|
||||
|
@ -59,8 +60,6 @@ class HostConnectionProfile: ConnectionProfile, Codable, Equatable {
|
|||
builder.mtu = configuration.mtu
|
||||
builder.shouldDebug = configuration.shouldDebug
|
||||
builder.debugLogFormat = configuration.debugLogFormat
|
||||
builder.debugLogKey = configuration.debugLogKey
|
||||
builder.lastErrorKey = configuration.lastErrorKey
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
|
|
@ -120,8 +120,6 @@ class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
|||
builder.mtu = configuration.mtu
|
||||
builder.shouldDebug = configuration.shouldDebug
|
||||
builder.debugLogFormat = configuration.debugLogFormat
|
||||
builder.debugLogKey = configuration.debugLogKey
|
||||
builder.lastErrorKey = configuration.lastErrorKey
|
||||
|
||||
if let address = manualAddress {
|
||||
builder.prefersResolvedAddresses = true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// TunnelKitProvider+Communication.swift
|
||||
// SessionProxy+Communication.swift
|
||||
// Passepartout
|
||||
//
|
||||
// Created by Davide De Rosa on 9/4/18.
|
||||
|
@ -26,15 +26,16 @@
|
|||
import Foundation
|
||||
import TunnelKit
|
||||
|
||||
extension TunnelKitProvider.ConfigurationBuilder {
|
||||
// mutating func copyCommunication(from other: TunnelKitProvider.ConfigurationBuilder) {
|
||||
extension SessionProxy.ConfigurationBuilder {
|
||||
// mutating func copyCommunication(from other: SessionProxy.ConfigurationBuilder) {
|
||||
// cipher = other.cipher
|
||||
// digest = other.digest
|
||||
// compressionFraming = other.compressionFraming
|
||||
// }
|
||||
|
||||
func canCommunicate(with other: TunnelKitProvider.Configuration) -> Bool {
|
||||
return (cipher == other.cipher) &&
|
||||
func canCommunicate(with other: SessionProxy.Configuration) -> Bool {
|
||||
return
|
||||
(cipher == other.cipher) &&
|
||||
((digest == other.digest) || cipher.embedsDigest) &&
|
||||
(compressionFraming == other.compressionFraming)
|
||||
}
|
|
@ -53,20 +53,22 @@ class TransientStore {
|
|||
for: .documentDirectory,
|
||||
appending: AppConstants.Store.serviceFilename
|
||||
)
|
||||
let cfg = AppConstants.VPN.tunnelConfiguration()
|
||||
let cfg = AppConstants.VPN.baseConfiguration()
|
||||
do {
|
||||
ConnectionService.migrateJSON(at: servicePath, to: servicePath)
|
||||
|
||||
let data = try Data(contentsOf: servicePath)
|
||||
if let content = String(data: data, encoding: .utf8) {
|
||||
log.verbose("Service JSON:")
|
||||
log.verbose(content)
|
||||
}
|
||||
service = try JSONDecoder().decode(ConnectionService.self, from: data)
|
||||
service.tunnelConfiguration = cfg
|
||||
service.baseConfiguration = cfg
|
||||
} catch let e {
|
||||
log.error("Could not decode service: \(e)")
|
||||
service = ConnectionService(
|
||||
withAppGroup: GroupConstants.App.appGroup,
|
||||
tunnelConfiguration: cfg
|
||||
baseConfiguration: cfg
|
||||
)
|
||||
|
||||
// // hardcoded loading
|
||||
|
|
|
@ -84,18 +84,21 @@ struct InfrastructurePreset: Codable {
|
|||
|
||||
let cfgContainer = try container.nestedContainer(keyedBy: ConfigurationKeys.self, forKey: .configuration)
|
||||
let ca = try cfgContainer.decode(CryptoContainer.self, forKey: .ca)
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(ca: ca)
|
||||
builder.endpointProtocols = try cfgContainer.decode([TunnelKitProvider.EndpointProtocol].self, forKey: .endpointProtocols)
|
||||
builder.cipher = try cfgContainer.decode(SessionProxy.Cipher.self, forKey: .cipher)
|
||||
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder(ca: ca)
|
||||
sessionBuilder.cipher = try cfgContainer.decode(SessionProxy.Cipher.self, forKey: .cipher)
|
||||
if let digest = try cfgContainer.decodeIfPresent(SessionProxy.Digest.self, forKey: .digest) {
|
||||
builder.digest = digest
|
||||
sessionBuilder.digest = digest
|
||||
}
|
||||
builder.clientCertificate = try cfgContainer.decodeIfPresent(CryptoContainer.self, forKey: .clientCertificate)
|
||||
builder.clientKey = try cfgContainer.decodeIfPresent(CryptoContainer.self, forKey: .clientKey)
|
||||
builder.compressionFraming = try cfgContainer.decode(SessionProxy.CompressionFraming.self, forKey: .compressionFraming)
|
||||
builder.keepAliveSeconds = try cfgContainer.decodeIfPresent(Int.self, forKey: .keepAliveSeconds)
|
||||
builder.renegotiatesAfterSeconds = try cfgContainer.decodeIfPresent(Int.self, forKey: .renegotiatesAfterSeconds)
|
||||
builder.usesPIAPatches = try cfgContainer.decodeIfPresent(Bool.self, forKey: .usesPIAPatches) ?? false
|
||||
sessionBuilder.clientCertificate = try cfgContainer.decodeIfPresent(CryptoContainer.self, forKey: .clientCertificate)
|
||||
sessionBuilder.clientKey = try cfgContainer.decodeIfPresent(CryptoContainer.self, forKey: .clientKey)
|
||||
sessionBuilder.compressionFraming = try cfgContainer.decode(SessionProxy.CompressionFraming.self, forKey: .compressionFraming)
|
||||
sessionBuilder.keepAliveInterval = try cfgContainer.decodeIfPresent(TimeInterval.self, forKey: .keepAliveSeconds)
|
||||
sessionBuilder.renegotiatesAfter = try cfgContainer.decodeIfPresent(TimeInterval.self, forKey: .renegotiatesAfterSeconds)
|
||||
sessionBuilder.usesPIAPatches = try cfgContainer.decodeIfPresent(Bool.self, forKey: .usesPIAPatches) ?? false
|
||||
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||
builder.endpointProtocols = try cfgContainer.decode([TunnelKitProvider.EndpointProtocol].self, forKey: .endpointProtocols)
|
||||
configuration = builder.build()
|
||||
}
|
||||
|
||||
|
@ -107,14 +110,15 @@ struct InfrastructurePreset: Codable {
|
|||
|
||||
var cfgContainer = container.nestedContainer(keyedBy: ConfigurationKeys.self, forKey: .configuration)
|
||||
try cfgContainer.encode(configuration.endpointProtocols, forKey: .endpointProtocols)
|
||||
try cfgContainer.encode(configuration.cipher, forKey: .cipher)
|
||||
try cfgContainer.encode(configuration.digest, forKey: .digest)
|
||||
try cfgContainer.encodeIfPresent(configuration.ca, forKey: .ca)
|
||||
try cfgContainer.encodeIfPresent(configuration.clientCertificate, forKey: .clientCertificate)
|
||||
try cfgContainer.encodeIfPresent(configuration.clientKey, forKey: .clientKey)
|
||||
try cfgContainer.encode(configuration.compressionFraming, forKey: .compressionFraming)
|
||||
try cfgContainer.encodeIfPresent(configuration.keepAliveSeconds, forKey: .keepAliveSeconds)
|
||||
try cfgContainer.encodeIfPresent(configuration.renegotiatesAfterSeconds, forKey: .renegotiatesAfterSeconds)
|
||||
try cfgContainer.encodeIfPresent(configuration.usesPIAPatches, forKey: .usesPIAPatches)
|
||||
|
||||
try cfgContainer.encode(configuration.sessionConfiguration.cipher, forKey: .cipher)
|
||||
try cfgContainer.encode(configuration.sessionConfiguration.digest, forKey: .digest)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.ca, forKey: .ca)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.clientCertificate, forKey: .clientCertificate)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.clientKey, forKey: .clientKey)
|
||||
try cfgContainer.encode(configuration.sessionConfiguration.compressionFraming, forKey: .compressionFraming)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.keepAliveInterval, forKey: .keepAliveSeconds)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.renegotiatesAfter, forKey: .renegotiatesAfterSeconds)
|
||||
try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.usesPIAPatches, forKey: .usesPIAPatches)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,8 @@ extension TunnelKitProvider.Configuration {
|
|||
var optCA: CryptoContainer?
|
||||
var clientCertificate: CryptoContainer?
|
||||
var clientKey: CryptoContainer?
|
||||
var keepAliveSeconds: Int?
|
||||
var renegotiateAfterSeconds: Int?
|
||||
var keepAliveSeconds: TimeInterval?
|
||||
var renegotiateAfterSeconds: TimeInterval?
|
||||
var keyDirection: StaticKey.Direction?
|
||||
var tlsStrategy: SessionProxy.TLSWrap.Strategy?
|
||||
var tlsKeyLines: [Substring]?
|
||||
|
@ -202,13 +202,13 @@ extension TunnelKitProvider.Configuration {
|
|||
guard let arg = $0.first else {
|
||||
return
|
||||
}
|
||||
keepAliveSeconds = Int(arg)
|
||||
keepAliveSeconds = TimeInterval(arg)
|
||||
}
|
||||
Regex.renegSec.enumerateArguments(in: line) {
|
||||
guard let arg = $0.first else {
|
||||
return
|
||||
}
|
||||
renegotiateAfterSeconds = Int(arg)
|
||||
renegotiateAfterSeconds = TimeInterval(arg)
|
||||
}
|
||||
Regex.fragment.enumerateArguments(in: line) { (_) in
|
||||
unsupportedError = ApplicationError.unsupportedConfiguration(option: "fragment")
|
||||
|
@ -270,16 +270,17 @@ extension TunnelKitProvider.Configuration {
|
|||
}
|
||||
}
|
||||
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(ca: ca)
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder(ca: ca)
|
||||
sessionBuilder.cipher = cipher ?? .aes128cbc
|
||||
sessionBuilder.digest = digest ?? .sha1
|
||||
sessionBuilder.compressionFraming = compressionFraming
|
||||
sessionBuilder.tlsWrap = tlsWrap
|
||||
sessionBuilder.clientCertificate = clientCertificate
|
||||
sessionBuilder.clientKey = clientKey
|
||||
sessionBuilder.keepAliveInterval = keepAliveSeconds
|
||||
sessionBuilder.renegotiatesAfter = renegotiateAfterSeconds
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||
builder.endpointProtocols = endpointProtocols
|
||||
builder.cipher = cipher ?? .aes128cbc
|
||||
builder.digest = digest ?? .sha1
|
||||
builder.compressionFraming = compressionFraming
|
||||
builder.tlsWrap = tlsWrap
|
||||
builder.clientCertificate = clientCertificate
|
||||
builder.clientKey = clientKey
|
||||
builder.keepAliveSeconds = keepAliveSeconds
|
||||
builder.renegotiatesAfterSeconds = renegotiateAfterSeconds
|
||||
|
||||
return (hostname, builder.build())
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"appGroup":"group.com.algoritmico.Passepartout","activeProfileId":"host.edu","tunnelConfiguration":{"endpointProtocols":["UDP:1194"],"compressionFraming":0,"digest":"SHA1","ca":"","lastErrorKey":"LastVPNError","debugLogFormat":"$DHH:mm:ss$d - $M","usesPIAPatches":false,"cipher":"AES-128-CBC","prefersResolvedAddresses":false,"shouldDebug":true,"mtu":1250,"debugLogKey":"LastVPNLog"},"preferences":{"trustPolicy":"ignore","trustsMobileNetwork":false,"disconnectsOnSleep":false,"trustedWifis":{},"resolvesHostname":true},"profiles":[{"provider":{"username":"p0000000","id":"provider.PIA","poolId":"ca-vancouver","name":"PIA","presetId":"recommended"}},{"host":{"username":"","title":"edu","hostname":"1.2.4.5","parameters":{"endpointProtocols":["UDP:1194","TCP:1194","TCP:443"],"compressionFraming":1,"digest":"SHA256","ca":"bogus+ca","clientCertificate":"bogus+client","usesPIAPatches":false,"tlsWrap":{"key":{"dir":1,"data":"bogus+static+key"},"strategy":"auth"},"cipher":"AES-256-CBC","prefersResolvedAddresses":false,"clientKey":"bogus+key","mtu":1500,"shouldDebug":false}}},{"host":{"username":"","title":"vps-udp-tc","hostname":"8.8.4.4","parameters":{"shouldDebug":false,"endpointProtocols":["UDP:1198"],"compressionFraming":1,"digest":"SHA512","ca":"bogus+ca","renegotiatesAfterSeconds":0,"usesPIAPatches":false,"tlsWrap":{"key":{"dir":1,"data":"bogus+static+key"},"strategy":"crypt"},"cipher":"AES-192-CBC","prefersResolvedAddresses":false,"clientKey":"bogus+key","mtu":1500,"keepAliveSeconds":25}}}]}
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// ConnectionServiceTests.swift
|
||||
// PassepartoutTests-iOS
|
||||
//
|
||||
// Created by Davide De Rosa on 10/25/18.
|
||||
// Copyright (c) 2018 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/keeshux
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import TunnelKit
|
||||
@testable import Passepartout_iOS
|
||||
|
||||
class ConnectionServiceTests: XCTestCase {
|
||||
let url = Bundle(for: ConnectionServiceTests.self).url(forResource: "ConnectionService", withExtension: "json")!
|
||||
|
||||
override func setUp() {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testParse() {
|
||||
let jsonData = try! Data(contentsOf: url)
|
||||
XCTAssertNoThrow(try JSONSerialization.jsonObject(with: jsonData, options: []))
|
||||
}
|
||||
|
||||
func testMigrate() {
|
||||
let migrated = try! ConnectionService.migrateJSON(at: url)
|
||||
let json = String(data: migrated, encoding: .utf8)!
|
||||
print(json)
|
||||
let service = try! JSONDecoder().decode(ConnectionService.self, from: migrated)
|
||||
|
||||
guard let activeProfile = service.activeProfile as? HostConnectionProfile else {
|
||||
XCTFail()
|
||||
return
|
||||
}
|
||||
XCTAssert(activeProfile.id == "host.edu")
|
||||
XCTAssert(activeProfile.hostname == "1.2.4.5")
|
||||
XCTAssert(activeProfile.parameters.sessionConfiguration.cipher == .aes256cbc)
|
||||
XCTAssert(activeProfile.parameters.sessionConfiguration.ca.pem == "bogus+ca")
|
||||
}
|
||||
}
|
|
@ -40,8 +40,8 @@ class FileConfigurationTests: XCTestCase {
|
|||
|
||||
func testPIA() throws {
|
||||
let cfg = try TunnelKitProvider.Configuration.parsed(from: url(withName: "pia-hungary")).1
|
||||
XCTAssertEqual(cfg.cipher, .aes128cbc)
|
||||
XCTAssertEqual(cfg.digest, .sha1)
|
||||
XCTAssertEqual(cfg.sessionConfiguration.cipher, .aes128cbc)
|
||||
XCTAssertEqual(cfg.sessionConfiguration.digest, .sha1)
|
||||
}
|
||||
|
||||
private func url(withName name: String) -> URL {
|
||||
|
|
2
Podfile
2
Podfile
|
@ -3,7 +3,7 @@ use_frameworks!
|
|||
|
||||
def shared_pods
|
||||
#pod 'TunnelKit', '~> 1.1.2'
|
||||
pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => '6995b88'
|
||||
pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => 'd94733f'
|
||||
#pod 'TunnelKit', :path => '../tunnelkit'
|
||||
end
|
||||
|
||||
|
|
20
Podfile.lock
20
Podfile.lock
|
@ -2,19 +2,19 @@ PODS:
|
|||
- MBProgressHUD (1.1.0)
|
||||
- OpenSSL-Apple (1.1.0i-v2)
|
||||
- SwiftyBeaver (1.6.1)
|
||||
- TunnelKit (1.2.2):
|
||||
- TunnelKit/AppExtension (= 1.2.2)
|
||||
- TunnelKit/Core (= 1.2.2)
|
||||
- TunnelKit/AppExtension (1.2.2):
|
||||
- TunnelKit (1.3.0):
|
||||
- TunnelKit/AppExtension (= 1.3.0)
|
||||
- TunnelKit/Core (= 1.3.0)
|
||||
- TunnelKit/AppExtension (1.3.0):
|
||||
- SwiftyBeaver
|
||||
- TunnelKit/Core
|
||||
- TunnelKit/Core (1.2.2):
|
||||
- TunnelKit/Core (1.3.0):
|
||||
- OpenSSL-Apple (~> 1.1.0h)
|
||||
- SwiftyBeaver
|
||||
|
||||
DEPENDENCIES:
|
||||
- MBProgressHUD
|
||||
- TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `6995b88`)
|
||||
- TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `d94733f`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
|
@ -24,20 +24,20 @@ SPEC REPOS:
|
|||
|
||||
EXTERNAL SOURCES:
|
||||
TunnelKit:
|
||||
:commit: 6995b88
|
||||
:commit: d94733f
|
||||
:git: https://github.com/keeshux/tunnelkit
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
TunnelKit:
|
||||
:commit: 6995b88
|
||||
:commit: d94733f
|
||||
:git: https://github.com/keeshux/tunnelkit
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
|
||||
OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c
|
||||
SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a
|
||||
TunnelKit: 15c88f0cef7b926883566a9455e912a1e55f4048
|
||||
TunnelKit: 8e747cac28959ebfdfa4eeab589c933f1856c0fb
|
||||
|
||||
PODFILE CHECKSUM: 159cfb999715d0ff9a22a7824f3b25dea9908ef0
|
||||
PODFILE CHECKSUM: 38237684ab2fdb5e262da936fd6932218abca0b4
|
||||
|
||||
COCOAPODS: 1.6.0.beta.2
|
||||
|
|
Loading…
Reference in New Issue