Migrate host configurations
This commit is contained in:
parent
542a3e3721
commit
d087acd512
|
@ -48,6 +48,9 @@
|
|||
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 */; };
|
||||
|
@ -165,6 +168,9 @@
|
|||
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,6 +385,7 @@
|
|||
0EBE3A9E213DC1A100BFA2F5 /* ConnectionProfile.swift */,
|
||||
0EBE3AAB213DEB8800BFA2F5 /* ConnectionProfileHolder.swift */,
|
||||
0EBE3A9F213DC1A100BFA2F5 /* ConnectionService.swift */,
|
||||
0EBBE8F42182361700106008 /* ConnectionService+Migration.swift */,
|
||||
0EDE8DE620C93945004C739C /* Credentials.swift */,
|
||||
0EC7F20420E24308004EA58E /* DebugLog.swift */,
|
||||
0ED38AE621404F100004D387 /* EndpointDataSource.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 */,
|
||||
|
@ -866,6 +877,7 @@
|
|||
files = (
|
||||
0ED38AE1213F51370004D387 /* FileConfigurationTests.swift in Sources */,
|
||||
0ED31C2720CF257C0027975F /* InfrastructureTests.swift in Sources */,
|
||||
0EBBE8F221822B4D00106008 /* ConnectionServiceTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -35,4 +35,6 @@ enum ApplicationError: Error {
|
|||
case emptyRemotes
|
||||
|
||||
case unsupportedConfiguration(option: String)
|
||||
|
||||
case migration
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// 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)
|
||||
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
|
||||
try migrateToWrappedSessionConfiguration(&json)
|
||||
|
||||
return try JSONSerialization.data(withJSONObject: json, options: [])
|
||||
}
|
||||
|
||||
private 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue