From 3d5c2bb8f56b4fb6d3125ed98d0c2893b6197ec1 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sat, 10 Nov 2018 10:29:51 +0100 Subject: [PATCH 1/2] Move .ovpn parser to TunnelKit --- Passepartout-iOS/AppDelegate.swift | 19 +- Passepartout-iOS/Global/IssueReporter.swift | 2 +- ...lerts.swift => ParsingResult+Alerts.swift} | 24 +- .../Scenes/ConfigurationViewController.swift | 8 +- .../Scenes/EndpointViewController.swift | 8 +- .../ImportedHostsViewController.swift | 18 +- .../Organizer/WizardHostViewController.swift | 18 +- .../Scenes/ServiceViewController.swift | 2 +- Passepartout.xcodeproj/project.pbxproj | 20 +- Passepartout/Sources/ApplicationError.swift | 6 +- .../Sources/Model/EndpointDataSource.swift | 4 +- .../Profiles/HostConnectionProfile.swift | 4 +- .../PlaceholderConnectionProfile.swift | 4 +- .../Profiles/ProviderConnectionProfile.swift | 10 +- .../Services/InfrastructurePreset.swift | 4 +- Passepartout/Sources/Utils.swift | 10 - .../TunnelKitProvider+FileConfiguration.swift | 402 ------------------ .../FileConfigurationTests.swift | 73 ---- .../InfrastructureTests.swift | 28 +- PassepartoutTests-iOS/pia-hungary.ovpn | 72 ---- Podfile | 4 +- Podfile.lock | 20 +- README.md | 24 +- 23 files changed, 96 insertions(+), 688 deletions(-) rename Passepartout-iOS/Global/{ParsedFile+Alerts.swift => ParsingResult+Alerts.swift} (84%) delete mode 100644 Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift delete mode 100644 PassepartoutTests-iOS/FileConfigurationTests.swift delete mode 100644 PassepartoutTests-iOS/pia-hungary.ovpn diff --git a/Passepartout-iOS/AppDelegate.swift b/Passepartout-iOS/AppDelegate.swift index 81f28494..714c60d4 100644 --- a/Passepartout-iOS/AppDelegate.swift +++ b/Passepartout-iOS/AppDelegate.swift @@ -24,6 +24,7 @@ // import UIKit +import TunnelKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate { @@ -93,32 +94,32 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele let topmost = root.presentedViewController ?? root let fm = FileManager.default - guard let parsedFile = ParsedFile.from(url, withErrorAlertIn: topmost) else { + guard let parsingResult = ConfigurationParser.ParsingResult.from(url, withErrorAlertIn: topmost) else { try? fm.removeItem(at: url) return true } - if let warning = parsedFile.warning { - ParsedFile.alertImportWarning(url: url, in: topmost, withWarning: warning) { + if let warning = parsingResult.warning { + ConfigurationParser.ParsingResult.alertImportWarning(url: url, in: topmost, withWarning: warning) { if $0 { - self.handleParsedFile(parsedFile, in: topmost) + self.handleParsingResult(parsingResult, in: topmost) } else { try? fm.removeItem(at: url) } } return true } - handleParsedFile(parsedFile, in: topmost) + handleParsingResult(parsingResult, in: topmost) return true } - private func handleParsedFile(_ parsedFile: ParsedFile, in target: UIViewController) { + private func handleParsingResult(_ parsingResult: ConfigurationParser.ParsingResult, in target: UIViewController) { // already presented: update parsed configuration if let nav = target as? UINavigationController, let wizard = nav.topViewController as? WizardHostViewController { - if let oldURL = wizard.parsedFile?.url { + if let oldURL = wizard.parsingResult?.url { try? FileManager.default.removeItem(at: oldURL) } - wizard.parsedFile = parsedFile + wizard.parsingResult = parsingResult wizard.removesConfigurationOnCancel = true return } @@ -128,7 +129,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele guard let wizard = wizardNav.topViewController as? WizardHostViewController else { fatalError("Expected WizardHostViewController from storyboard") } - wizard.parsedFile = parsedFile + wizard.parsingResult = parsingResult wizard.removesConfigurationOnCancel = true wizardNav.modalPresentationStyle = .formSheet diff --git a/Passepartout-iOS/Global/IssueReporter.swift b/Passepartout-iOS/Global/IssueReporter.swift index 069081df..27b09b86 100644 --- a/Passepartout-iOS/Global/IssueReporter.swift +++ b/Passepartout-iOS/Global/IssueReporter.swift @@ -91,7 +91,7 @@ class IssueReporter: NSObject { } if let url = configurationURL { do { - let parsedFile = try TunnelKitProvider.Configuration.parsed(fromURL: url, returnsStripped: true) + let parsedFile = try ConfigurationParser.parsed(fromURL: url, returnsStripped: true) if let attachment = parsedFile.strippedLines?.joined(separator: "\n").data(using: .utf8) { vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration) } diff --git a/Passepartout-iOS/Global/ParsedFile+Alerts.swift b/Passepartout-iOS/Global/ParsingResult+Alerts.swift similarity index 84% rename from Passepartout-iOS/Global/ParsedFile+Alerts.swift rename to Passepartout-iOS/Global/ParsingResult+Alerts.swift index cc7ab6e0..3cddeb03 100644 --- a/Passepartout-iOS/Global/ParsedFile+Alerts.swift +++ b/Passepartout-iOS/Global/ParsingResult+Alerts.swift @@ -1,5 +1,5 @@ // -// ParsedFile+Alerts.swift +// ParsingResult+Alerts.swift // Passepartout-iOS // // Created by Davide De Rosa on 10/27/18. @@ -30,18 +30,18 @@ import SwiftyBeaver private let log = SwiftyBeaver.self -extension ParsedFile { - static func from(_ url: URL, withErrorAlertIn viewController: UIViewController) -> ParsedFile? { - let file: ParsedFile +extension ConfigurationParser.ParsingResult { + static func from(_ url: URL, withErrorAlertIn viewController: UIViewController) -> ConfigurationParser.ParsingResult? { + let result: ConfigurationParser.ParsingResult log.debug("Parsing configuration URL: \(url)") do { - file = try TunnelKitProvider.Configuration.parsed(fromURL: url) + result = try ConfigurationParser.parsed(fromURL: url) } catch let e { let message = localizedMessage(forError: e) alertImportError(url: url, in: viewController, withMessage: message) return nil } - return file + return result } private static func alertImportError(url: URL, in vc: UIViewController, withMessage message: String) { @@ -55,7 +55,7 @@ extension ParsedFile { vc.present(alert, animated: true, completion: nil) } - static func alertImportWarning(url: URL, in vc: UIViewController, withWarning warning: ApplicationError, completionHandler: @escaping (Bool) -> Void) { + static func alertImportWarning(url: URL, in vc: UIViewController, withWarning warning: ConfigurationParser.ParsingError, completionHandler: @escaping (Bool) -> Void) { let message = details(forWarning: warning) let alert = Macros.alert(url.normalizedFilename, L10n.ParsedFile.Alerts.PotentiallyUnsupported.message(message)) alert.addDefaultAction(L10n.Global.ok) { @@ -68,7 +68,7 @@ extension ParsedFile { } private static func localizedMessage(forError error: Error) -> String { - if let appError = error as? ApplicationError { + if let appError = error as? ConfigurationParser.ParsingError { switch appError { case .missingConfiguration(let option): log.error("Could not parse configuration URL: missing configuration, \(option)") @@ -77,25 +77,19 @@ extension ParsedFile { case .unsupportedConfiguration(let option): log.error("Could not parse configuration URL: unsupported configuration, \(option)") return L10n.ParsedFile.Alerts.Unsupported.message(option) - - default: - break } } log.error("Could not parse configuration URL: \(error)") return L10n.ParsedFile.Alerts.Parsing.message(error.localizedDescription) } - private static func details(forWarning warning: ApplicationError) -> String { + private static func details(forWarning warning: ConfigurationParser.ParsingError) -> String { switch warning { case .missingConfiguration(let option): return option case .unsupportedConfiguration(let option): return option - - default: - fatalError("Only use .missingConfiguration or .unsupportedConfiguration for warnings") } } } diff --git a/Passepartout-iOS/Scenes/ConfigurationViewController.swift b/Passepartout-iOS/Scenes/ConfigurationViewController.swift index 18633817..af9f4506 100644 --- a/Passepartout-iOS/Scenes/ConfigurationViewController.swift +++ b/Passepartout-iOS/Scenes/ConfigurationViewController.swift @@ -121,16 +121,16 @@ class ConfigurationViewController: UIViewController, TableModelHost { log.warning("Resetting with no original configuration set? Bad table model?") return } - let parsedFile: ParsedFile + let parsingResult: ConfigurationParser.ParsingResult do { - parsedFile = try TunnelKitProvider.Configuration.parsed(fromURL: originalURL) + parsingResult = try ConfigurationParser.parsed(fromURL: originalURL) } catch let e { log.error("Could not parse original configuration: \(e)") return } - configuration = parsedFile.configuration.sessionConfiguration.builder() + configuration = parsingResult.configuration.builder() itemRefresh.isEnabled = !configuration.canCommunicate(with: initialConfiguration) - initialConfiguration = parsedFile.configuration.sessionConfiguration + initialConfiguration = parsingResult.configuration tableView.reloadData() delegate?.configuration(didUpdate: initialConfiguration) diff --git a/Passepartout-iOS/Scenes/EndpointViewController.swift b/Passepartout-iOS/Scenes/EndpointViewController.swift index ae05a9fe..5946f513 100644 --- a/Passepartout-iOS/Scenes/EndpointViewController.swift +++ b/Passepartout-iOS/Scenes/EndpointViewController.swift @@ -27,7 +27,7 @@ import UIKit import TunnelKit protocol EndpointViewControllerDelegate: class { - func endpointController(_: EndpointViewController, didUpdateWithNewAddress newAddress: String?, newProtocol: TunnelKitProvider.EndpointProtocol?) + func endpointController(_: EndpointViewController, didUpdateWithNewAddress newAddress: String?, newProtocol: EndpointProtocol?) } class EndpointViewController: UIViewController, TableModelHost { @@ -37,15 +37,15 @@ class EndpointViewController: UIViewController, TableModelHost { private var endpointAddresses: [String] = [] - private var endpointProtocols: [TunnelKitProvider.EndpointProtocol] = [] + private var endpointProtocols: [EndpointProtocol] = [] private var initialAddress: String? - private var initialProtocol: TunnelKitProvider.EndpointProtocol? + private var initialProtocol: EndpointProtocol? private var currentAddress: String? - private var currentProtocol: TunnelKitProvider.EndpointProtocol? + private var currentProtocol: EndpointProtocol? private var currentAddressIndexPath: IndexPath? diff --git a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift index 7750810b..bf32a2bd 100644 --- a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift +++ b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift @@ -32,7 +32,7 @@ private let log = SwiftyBeaver.self class ImportedHostsViewController: UITableViewController { private lazy var pendingConfigurationURLs = TransientStore.shared.service.pendingConfigurationURLs().sortedCaseInsensitive() - private var parsedFile: ParsedFile? + private var parsingResult: ConfigurationParser.ParsingResult? override func viewDidLoad() { super.viewDidLoad() @@ -43,7 +43,7 @@ class ImportedHostsViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - parsedFile = nil + parsingResult = nil } override func viewDidAppear(_ animated: Bool) { @@ -70,25 +70,25 @@ class ImportedHostsViewController: UITableViewController { override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { // segue parses configuration file if not yet - if parsedFile == nil { + if parsingResult == nil { guard let cell = sender as? UITableViewCell, let indexPath = tableView.indexPath(for: cell) else { return false } let url = pendingConfigurationURLs[indexPath.row] - guard let parsedFile = ParsedFile.from(url, withErrorAlertIn: self) else { + guard let parsingResult = ConfigurationParser.ParsingResult.from(url, withErrorAlertIn: self) else { deselectSelectedRow() return false } - self.parsedFile = parsedFile + self.parsingResult = parsingResult // postpone segue until alert dismissal - if let warning = parsedFile.warning { - ParsedFile.alertImportWarning(url: url, in: self, withWarning: warning) { + if let warning = parsingResult.warning { + ConfigurationParser.ParsingResult.alertImportWarning(url: url, in: self, withWarning: warning) { self.deselectSelectedRow() if $0 { self.perform(segue: StoryboardSegue.Organizer.importHostSegueIdentifier) } else { - self.parsedFile = nil + self.parsingResult = nil } } return false @@ -101,7 +101,7 @@ class ImportedHostsViewController: UITableViewController { guard let wizard = segue.destination as? WizardHostViewController else { return } - wizard.parsedFile = parsedFile + wizard.parsingResult = parsingResult // retain back button wizard.navigationItem.leftBarButtonItem = nil diff --git a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift index b268eaa7..72a4154f 100644 --- a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift +++ b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift @@ -36,7 +36,7 @@ class WizardHostViewController: UITableViewController, TableModelHost { return TransientStore.shared.service.ids(forContext: .host).sortedCaseInsensitive() }() - var parsedFile: ParsedFile? { + var parsingResult: ConfigurationParser.ParsingResult? { didSet { useSuggestedTitle() } @@ -88,19 +88,21 @@ class WizardHostViewController: UITableViewController, TableModelHost { // MARK: Actions private func useSuggestedTitle() { - cellTitle?.field.text = parsedFile?.url?.normalizedFilename + cellTitle?.field.text = parsingResult?.url?.normalizedFilename } @IBAction private func next() { guard let enteredTitle = cellTitle?.field.text?.trimmingCharacters(in: .whitespaces), !enteredTitle.isEmpty else { return } - guard let file = parsedFile else { + guard let result = parsingResult else { return } - - let profile = HostConnectionProfile(title: enteredTitle, hostname: file.hostname) - profile.parameters = file.configuration + + let profile = HostConnectionProfile(title: enteredTitle, hostname: result.hostname) + var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: result.configuration) + builder.endpointProtocols = result.protocols + profile.parameters = builder.build() let service = TransientStore.shared.service guard !service.containsProfile(profile) else { @@ -132,7 +134,7 @@ class WizardHostViewController: UITableViewController, TableModelHost { fatalError("No profile created?") } let service = TransientStore.shared.service - if let url = parsedFile?.url { + if let url = parsingResult?.url { do { let savedURL = try service.save(configurationURL: url, for: profile) log.debug("Associated .ovpn configuration file to profile '\(profile.id)': \(savedURL)") @@ -149,7 +151,7 @@ class WizardHostViewController: UITableViewController, TableModelHost { } @IBAction private func close() { - if removesConfigurationOnCancel, let url = parsedFile?.url { + if removesConfigurationOnCancel, let url = parsingResult?.url { try? FileManager.default.removeItem(at: url) } dismiss(animated: true, completion: nil) diff --git a/Passepartout-iOS/Scenes/ServiceViewController.swift b/Passepartout-iOS/Scenes/ServiceViewController.swift index 25b3cd77..a225c1c5 100644 --- a/Passepartout-iOS/Scenes/ServiceViewController.swift +++ b/Passepartout-iOS/Scenes/ServiceViewController.swift @@ -1050,7 +1050,7 @@ extension ServiceViewController: AccountViewControllerDelegate { } extension ServiceViewController: EndpointViewControllerDelegate { - func endpointController(_: EndpointViewController, didUpdateWithNewAddress newAddress: String?, newProtocol: TunnelKitProvider.EndpointProtocol?) { + func endpointController(_: EndpointViewController, didUpdateWithNewAddress newAddress: String?, newProtocol: EndpointProtocol?) { if let providerProfile = profile as? ProviderConnectionProfile { providerProfile.manualAddress = newAddress providerProfile.manualProtocol = newProtocol diff --git a/Passepartout.xcodeproj/project.pbxproj b/Passepartout.xcodeproj/project.pbxproj index 8b5a4404..c58abb03 100644 --- a/Passepartout.xcodeproj/project.pbxproj +++ b/Passepartout.xcodeproj/project.pbxproj @@ -47,7 +47,7 @@ 0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; }; 0E8D97E221388B52006FB4A0 /* InfrastructurePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */; }; 0E8D97E521389277006FB4A0 /* pia.json in Resources */ = {isa = PBXBuildFile; fileRef = 0E8D97E421389276006FB4A0 /* pia.json */; }; - 0EA068F4218475F800C320AD /* ParsedFile+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA068F3218475F800C320AD /* ParsedFile+Alerts.swift */; }; + 0EA068F4218475F800C320AD /* ParsingResult+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */; }; 0EAAD71920E6669A0088754A /* GroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE8DED20C93E4C004C739C /* GroupConstants.swift */; }; 0EB60FDA2111136E00AD27F3 /* UITextView+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */; }; 0EB67D6B2184581E00BA6200 /* ImportedHostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */; }; @@ -74,9 +74,6 @@ 0ED31C3D20CF396E0027975F /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ED31C3920CF39510027975F /* NetworkExtension.framework */; }; 0ED38AD9213F33150004D387 /* WizardHostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AD8213F33150004D387 /* WizardHostViewController.swift */; }; 0ED38ADA213F44D00004D387 /* Organizer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0ED38ADC213F44D00004D387 /* Organizer.storyboard */; }; - 0ED38ADE213F4E980004D387 /* TunnelKitProvider+FileConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38ADD213F4E980004D387 /* TunnelKitProvider+FileConfiguration.swift */; }; - 0ED38AE1213F51370004D387 /* FileConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AE0213F51370004D387 /* FileConfigurationTests.swift */; }; - 0ED38AE3213F517D0004D387 /* pia-hungary.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0ED38AE2213F517D0004D387 /* pia-hungary.ovpn */; }; 0ED38AE721404F100004D387 /* EndpointDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AE621404F100004D387 /* EndpointDataSource.swift */; }; 0ED38AEA214054A50004D387 /* OptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AE9214054A50004D387 /* OptionViewController.swift */; }; 0ED38AEC2141260D0004D387 /* ConfigurationModificationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AEB2141260D0004D387 /* ConfigurationModificationDelegate.swift */; }; @@ -171,7 +168,7 @@ 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardProviderViewController.swift; sourceTree = ""; }; 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructurePreset.swift; sourceTree = ""; }; 0E8D97E421389276006FB4A0 /* pia.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = pia.json; sourceTree = ""; }; - 0EA068F3218475F800C320AD /* ParsedFile+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParsedFile+Alerts.swift"; sourceTree = ""; }; + 0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParsingResult+Alerts.swift"; sourceTree = ""; }; 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Search.swift"; sourceTree = ""; }; 0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportedHostsViewController.swift; sourceTree = ""; }; 0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionServiceTests.swift; sourceTree = ""; }; @@ -197,9 +194,6 @@ 0ED31C3B20CF39510027975F /* Tunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Tunnel.entitlements; sourceTree = ""; }; 0ED38AD8213F33150004D387 /* WizardHostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardHostViewController.swift; sourceTree = ""; }; 0ED38ADB213F44D00004D387 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/Organizer.storyboard; sourceTree = ""; }; - 0ED38ADD213F4E980004D387 /* TunnelKitProvider+FileConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+FileConfiguration.swift"; sourceTree = ""; }; - 0ED38AE0213F51370004D387 /* FileConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileConfigurationTests.swift; sourceTree = ""; }; - 0ED38AE2213F517D0004D387 /* pia-hungary.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "pia-hungary.ovpn"; sourceTree = ""; }; 0ED38AE621404F100004D387 /* EndpointDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndpointDataSource.swift; sourceTree = ""; }; 0ED38AE9214054A50004D387 /* OptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionViewController.swift; sourceTree = ""; }; 0ED38AEB2141260D0004D387 /* ConfigurationModificationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationModificationDelegate.swift; sourceTree = ""; }; @@ -283,7 +277,6 @@ 0E5E5DE421511C5F00E318A3 /* GracefulVPN.swift */, 0E4FD7E020D3E4C5002221FF /* MockVPNProvider.swift */, 0E4FD7DD20D3E49A002221FF /* StandardVPNProvider.swift */, - 0ED38ADD213F4E980004D387 /* TunnelKitProvider+FileConfiguration.swift */, 0ED31C3620CF38D10027975F /* VPN.swift */, 0E5E5DE1215119DD00E318A3 /* VPNConfiguration.swift */, 0ED38AF1214177920004D387 /* VPNProvider.swift */, @@ -337,10 +330,8 @@ isa = PBXGroup; children = ( 0EBBE8F121822B4D00106008 /* ConnectionService.json */, - 0ED38AE2213F517D0004D387 /* pia-hungary.ovpn */, 0E57F65220C83FC7008323CF /* Info.plist */, 0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */, - 0ED38AE0213F51370004D387 /* FileConfigurationTests.swift */, 0ED31C2620CF257C0027975F /* InfrastructureTests.swift */, ); path = "PassepartoutTests-iOS"; @@ -445,7 +436,7 @@ 0EFD943D215BE10800529B64 /* IssueReporter.swift */, 0E4FD7F020D58618002221FF /* Macros.swift */, 0ED38AE9214054A50004D387 /* OptionViewController.swift */, - 0EA068F3218475F800C320AD /* ParsedFile+Alerts.swift */, + 0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */, 0EDE8DE320C89028004C739C /* SwiftGen+Scenes.swift */, 0EF56BBA2185AC8500B0C8AB /* SwiftGen+Segues.swift */, 0E05C61C20D27C82006EE732 /* Theme.swift */, @@ -671,7 +662,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0ED38AE3213F517D0004D387 /* pia-hungary.ovpn in Resources */, 0EBBE8F321822B4D00106008 /* ConnectionService.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -826,7 +816,6 @@ 0EBE3AA5213DC1B000BFA2F5 /* HostConnectionProfile.swift in Sources */, 0E05C5D420D1645F006EE732 /* FieldTableViewCell.swift in Sources */, 0E05C61D20D27C82006EE732 /* Theme.swift in Sources */, - 0ED38ADE213F4E980004D387 /* TunnelKitProvider+FileConfiguration.swift in Sources */, 0EDE8DEE20C93E4C004C739C /* GroupConstants.swift in Sources */, 0ED38AEC2141260D0004D387 /* ConfigurationModificationDelegate.swift in Sources */, 0ECEE45020E1182E00A6BB43 /* Theme+Cells.swift in Sources */, @@ -866,7 +855,7 @@ 0E57F63E20C83FC5008323CF /* ServiceViewController.swift in Sources */, 0E39BCF0214B9EF10035E9DE /* WebServices.swift in Sources */, 0EDE8DE720C93945004C739C /* Credentials.swift in Sources */, - 0EA068F4218475F800C320AD /* ParsedFile+Alerts.swift in Sources */, + 0EA068F4218475F800C320AD /* ParsingResult+Alerts.swift in Sources */, 0ED38AF2214177920004D387 /* VPNProvider.swift in Sources */, 0E4C9CB920DB9BC600A0C59C /* TrustedNetworks.swift in Sources */, 0E57F63C20C83FC5008323CF /* AppDelegate.swift in Sources */, @@ -887,7 +876,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0ED38AE1213F51370004D387 /* FileConfigurationTests.swift in Sources */, 0ED31C2720CF257C0027975F /* InfrastructureTests.swift in Sources */, 0EBBE8F221822B4D00106008 /* ConnectionServiceTests.swift in Sources */, ); diff --git a/Passepartout/Sources/ApplicationError.swift b/Passepartout/Sources/ApplicationError.swift index 874fbc10..10aeadf5 100644 --- a/Passepartout/Sources/ApplicationError.swift +++ b/Passepartout/Sources/ApplicationError.swift @@ -25,14 +25,10 @@ import Foundation -enum ApplicationError: Error { +enum ApplicationError: String, Error { case missingProfile case missingCredentials - - case missingConfiguration(option: String) - - case unsupportedConfiguration(option: String) case migration } diff --git a/Passepartout/Sources/Model/EndpointDataSource.swift b/Passepartout/Sources/Model/EndpointDataSource.swift index 1a9c8588..7d58b7d7 100644 --- a/Passepartout/Sources/Model/EndpointDataSource.swift +++ b/Passepartout/Sources/Model/EndpointDataSource.swift @@ -31,11 +31,11 @@ protocol EndpointDataSource { var addresses: [String] { get } - var protocols: [TunnelKitProvider.EndpointProtocol] { get } + var protocols: [EndpointProtocol] { get } var canCustomizeEndpoint: Bool { get } var customAddress: String? { get } - var customProtocol: TunnelKitProvider.EndpointProtocol? { get } + var customProtocol: EndpointProtocol? { get } } diff --git a/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift index d109b07f..9f1c28a0 100644 --- a/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift +++ b/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift @@ -89,7 +89,7 @@ extension HostConnectionProfile { return [hostname] } - var protocols: [TunnelKitProvider.EndpointProtocol] { + var protocols: [EndpointProtocol] { return parameters.endpointProtocols } @@ -101,7 +101,7 @@ extension HostConnectionProfile { return nil } - var customProtocol: TunnelKitProvider.EndpointProtocol? { + var customProtocol: EndpointProtocol? { return nil } } diff --git a/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift index f2db7645..aa4191a0 100644 --- a/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift +++ b/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift @@ -47,13 +47,13 @@ class PlaceholderConnectionProfile: ConnectionProfile { var addresses: [String] = [] - var protocols: [TunnelKitProvider.EndpointProtocol] = [] + var protocols: [EndpointProtocol] = [] var canCustomizeEndpoint: Bool = false var customAddress: String? - var customProtocol: TunnelKitProvider.EndpointProtocol? + var customProtocol: EndpointProtocol? init(_ context: Context, _ id: String) { self.context = context diff --git a/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift index e20d4ee4..40eb7937 100644 --- a/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift +++ b/Passepartout/Sources/Model/Profiles/ProviderConnectionProfile.swift @@ -55,7 +55,7 @@ class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable { var manualAddress: String? - var manualProtocol: TunnelKitProvider.EndpointProtocol? + var manualProtocol: EndpointProtocol? var usesProviderEndpoint: Bool { return (manualAddress != nil) || (manualProtocol != nil) @@ -133,8 +133,8 @@ class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable { } else { builder.endpointProtocols = preset.configuration.endpointProtocols // builder.endpointProtocols = [ -// TunnelKitProvider.EndpointProtocol(.udp, 8080), -// TunnelKitProvider.EndpointProtocol(.tcp, 443) +// EndpointProtocol(.udp, 8080), +// EndpointProtocol(.tcp, 443) // ] } return builder.build() @@ -161,7 +161,7 @@ extension ProviderConnectionProfile { return pool?.addresses(sorted: true) ?? [] } - var protocols: [TunnelKitProvider.EndpointProtocol] { + var protocols: [EndpointProtocol] { return preset?.configuration.endpointProtocols ?? [] } @@ -173,7 +173,7 @@ extension ProviderConnectionProfile { return manualAddress } - var customProtocol: TunnelKitProvider.EndpointProtocol? { + var customProtocol: EndpointProtocol? { return manualProtocol } } diff --git a/Passepartout/Sources/Services/InfrastructurePreset.swift b/Passepartout/Sources/Services/InfrastructurePreset.swift index cd4a5788..2ab9fcc2 100644 --- a/Passepartout/Sources/Services/InfrastructurePreset.swift +++ b/Passepartout/Sources/Services/InfrastructurePreset.swift @@ -70,7 +70,7 @@ struct InfrastructurePreset: Codable { let configuration: TunnelKitProvider.Configuration - func hasProtocol(_ proto: TunnelKitProvider.EndpointProtocol) -> Bool { + func hasProtocol(_ proto: EndpointProtocol) -> Bool { return configuration.endpointProtocols.index(of: proto) != nil } @@ -98,7 +98,7 @@ struct InfrastructurePreset: Codable { 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) + builder.endpointProtocols = try cfgContainer.decode([EndpointProtocol].self, forKey: .endpointProtocols) configuration = builder.build() } diff --git a/Passepartout/Sources/Utils.swift b/Passepartout/Sources/Utils.swift index 1c9df6b3..b79eaade 100644 --- a/Passepartout/Sources/Utils.swift +++ b/Passepartout/Sources/Utils.swift @@ -192,16 +192,6 @@ extension StringProtocol where Index == String.Index { } } -extension String { - func trimmedLines() -> [String] { - return components(separatedBy: .newlines).map { - $0.trimmingCharacters(in: .whitespacesAndNewlines) - }.filter { - !$0.isEmpty - } - } -} - extension CharacterSet { static let filename: CharacterSet = { var chars: CharacterSet = .decimalDigits diff --git a/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift b/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift deleted file mode 100644 index f991bca9..00000000 --- a/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift +++ /dev/null @@ -1,402 +0,0 @@ -// -// TunnelKitProvider+FileConfiguration.swift -// Passepartout -// -// Created by Davide De Rosa on 9/5/18. -// Copyright (c) 2018 Davide De Rosa. All rights reserved. -// -// https://github.com/passepartoutvpn -// -// 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 . -// - -import Foundation -import TunnelKit -import SwiftyBeaver - -private let log = SwiftyBeaver.self - -struct ParsedFile { - let url: URL? - - let hostname: String - - let configuration: TunnelKitProvider.Configuration - - let strippedLines: [String]? - - let warning: ApplicationError? -} - -extension TunnelKitProvider.Configuration { - private struct Regex { - static let proto = Utils.regex("^proto +(udp6?|tcp6?)") - - static let port = Utils.regex("^port +\\d+") - - static let remote = Utils.regex("^remote +[^ ]+( +\\d+)?( +(udp6?|tcp6?))?") - - static let cipher = Utils.regex("^cipher +[\\w\\-]+") - - static let auth = Utils.regex("^auth +[\\w\\-]+") - - static let compLZO = Utils.regex("^comp-lzo.*") - - static let compress = Utils.regex("^compress.*") - - static let ping = Utils.regex("^ping +\\d+") - - static let renegSec = Utils.regex("^reneg-sec +\\d+") - - static let keyDirection = Utils.regex("^key-direction +\\d") - - static let blockBegin = Utils.regex("^<[\\w\\-]+>") - - static let blockEnd = Utils.regex("^<\\/[\\w\\-]+>") - - // unsupported - -// static let fragment = Utils.regex("^fragment +\\d+") - static let fragment = Utils.regex("^fragment") - - static let proxy = Utils.regex("^\\w+-proxy") - - static let externalFiles = Utils.regex("^(ca|cert|key|tls-auth|tls-crypt) ") - } - - static func parsed(fromURL url: URL, returnsStripped: Bool = false) throws -> ParsedFile { - let lines = try String(contentsOf: url).trimmedLines() - return try parsed(fromLines: lines, originalURL: url, returnsStripped: returnsStripped) - } - - static func parsed(fromLines lines: [String], originalURL: URL? = nil, returnsStripped: Bool = false) throws -> ParsedFile { - var strippedLines: [String]? = returnsStripped ? [] : nil - var warning: ApplicationError? = nil - - var defaultProto: TunnelKitProvider.SocketType? - var defaultPort: UInt16? - var remotes: [(String, UInt16?, TunnelKitProvider.SocketType?)] = [] - - var cipher: SessionProxy.Cipher? - var digest: SessionProxy.Digest? - var compressionFraming: SessionProxy.CompressionFraming = .disabled - var optCA: CryptoContainer? - var clientCertificate: CryptoContainer? - var clientKey: CryptoContainer? - var keepAliveSeconds: TimeInterval? - var renegotiateAfterSeconds: TimeInterval? - var keyDirection: StaticKey.Direction? - var tlsStrategy: SessionProxy.TLSWrap.Strategy? - var tlsKeyLines: [Substring]? - var tlsWrap: SessionProxy.TLSWrap? - - var currentBlockName: String? - var currentBlock: [String] = [] - var unsupportedError: ApplicationError? = nil - - log.verbose("Configuration file:") - for line in lines { - log.verbose(line) - - var isHandled = false - var strippedLine = line - defer { - if isHandled { - strippedLines?.append(strippedLine) - } - } - - Regex.blockBegin.enumerateComponents(in: line) { - isHandled = true - let tag = $0.first! - let from = tag.index(after: tag.startIndex) - let to = tag.index(before: tag.endIndex) - - currentBlockName = String(tag[from.."] - if $0.count > 1 { - port = UInt16($0[1]) - strippedComponents.append($0[1]) - } - if $0.count > 2 { - proto = TunnelKitProvider.SocketType(protoString: $0[2]) - strippedComponents.append($0[2]) - } - remotes.append((hostname, port, proto)) - - // replace private data - strippedLine = strippedComponents.joined(separator: " ") - } - Regex.cipher.enumerateArguments(in: line) { - isHandled = true - guard let rawValue = $0.first else { - return - } - cipher = SessionProxy.Cipher(rawValue: rawValue.uppercased()) - if cipher == nil { - unsupportedError = ApplicationError.unsupportedConfiguration(option: "cipher \(rawValue)") - } - } - Regex.auth.enumerateArguments(in: line) { - isHandled = true - guard let rawValue = $0.first else { - return - } - digest = SessionProxy.Digest(rawValue: rawValue.uppercased()) - if digest == nil { - unsupportedError = ApplicationError.unsupportedConfiguration(option: "auth \(rawValue)") - } - } - Regex.compLZO.enumerateArguments(in: line) { - isHandled = true - compressionFraming = .compLZO - - guard let arg = $0.first else { - warning = warning ?? .unsupportedConfiguration(option: line) - return - } - guard arg == "no" else { - unsupportedError = .unsupportedConfiguration(option: line) - return - } - } - Regex.compress.enumerateArguments(in: line) { - isHandled = true - compressionFraming = .compress - - guard $0.isEmpty else { - unsupportedError = .unsupportedConfiguration(option: line) - return - } - } - Regex.keyDirection.enumerateArguments(in: line) { - isHandled = true - guard let arg = $0.first, let value = Int(arg) else { - return - } - keyDirection = StaticKey.Direction(rawValue: value) - } - Regex.ping.enumerateArguments(in: line) { - isHandled = true - guard let arg = $0.first else { - return - } - keepAliveSeconds = TimeInterval(arg) - } - Regex.renegSec.enumerateArguments(in: line) { - isHandled = true - guard let arg = $0.first else { - return - } - renegotiateAfterSeconds = TimeInterval(arg) - } - Regex.fragment.enumerateArguments(in: line) { (_) in - unsupportedError = ApplicationError.unsupportedConfiguration(option: "fragment") - } - Regex.proxy.enumerateArguments(in: line) { (_) in - unsupportedError = ApplicationError.unsupportedConfiguration(option: "proxy: \"\(line)\"") - } - Regex.externalFiles.enumerateArguments(in: line) { (_) in - unsupportedError = ApplicationError.unsupportedConfiguration(option: "external file: \"\(line)\"") - } - if line.contains("mtu") || line.contains("mssfix") { - isHandled = true - } - - if let error = unsupportedError { - throw error - } - } - - guard let ca = optCA else { - throw ApplicationError.missingConfiguration(option: "ca") - } - - // XXX: only reads first remote -// hostnames = remotes.map { $0.0 } - guard !remotes.isEmpty else { - throw ApplicationError.missingConfiguration(option: "remote") - } - let hostname = remotes[0].0 - - defaultProto = defaultProto ?? .udp - defaultPort = defaultPort ?? 1194 - - // XXX: reads endpoints from remotes with matching hostname - var endpointProtocols: [TunnelKitProvider.EndpointProtocol] = [] - remotes.forEach { - guard $0.0 == hostname else { - return - } - guard let port = $0.1 ?? defaultPort else { - return - } - guard let socketType = $0.2 ?? defaultProto else { - return - } - endpointProtocols.append(TunnelKitProvider.EndpointProtocol(socketType, port)) - } - - assert(!endpointProtocols.isEmpty, "Must define an endpoint protocol") - - if let keyLines = tlsKeyLines, let strategy = tlsStrategy { - let optKey: StaticKey? - switch strategy { - case .auth: - optKey = StaticKey(lines: keyLines, direction: keyDirection) - - case .crypt: - optKey = StaticKey(lines: keyLines, direction: .client) - } - if let key = optKey { - tlsWrap = SessionProxy.TLSWrap(strategy: strategy, key: key) - } - } - - 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 - - return ParsedFile( - url: originalURL, - hostname: hostname, - configuration: builder.build(), - strippedLines: strippedLines, - warning: warning - ) - } -} - -private extension TunnelKitProvider.SocketType { - init?(protoString: String) { - var str = protoString - if str.hasSuffix("6") { - str.removeLast() - } - self.init(rawValue: str.uppercased()) - } -} - -private extension NSRegularExpression { - func enumerateComponents(in string: String, using block: ([String]) -> Void) { - enumerateMatches(in: string, options: [], range: NSMakeRange(0, string.count)) { (result, flags, stop) in - guard let range = result?.range else { - return - } - let match = (string as NSString).substring(with: range) - let tokens = match.components(separatedBy: " ").filter { !$0.isEmpty } - block(tokens) - } - } - - func enumerateArguments(in string: String, using block: ([String]) -> Void) { - enumerateMatches(in: string, options: [], range: NSMakeRange(0, string.count)) { (result, flags, stop) in - guard let range = result?.range else { - return - } - let match = (string as NSString).substring(with: range) - var tokens = match.components(separatedBy: " ").filter { !$0.isEmpty } - tokens.removeFirst() - block(tokens) - } - } -} - -extension CryptoContainer { - var isEncrypted: Bool { - return pem.contains("ENCRYPTED") - } -} diff --git a/PassepartoutTests-iOS/FileConfigurationTests.swift b/PassepartoutTests-iOS/FileConfigurationTests.swift deleted file mode 100644 index 3b25f300..00000000 --- a/PassepartoutTests-iOS/FileConfigurationTests.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// FileConfigurationTests.swift -// PassepartoutTests-iOS -// -// Created by Davide De Rosa on 9/5/18. -// Copyright (c) 2018 Davide De Rosa. All rights reserved. -// -// https://github.com/passepartoutvpn -// -// 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 . -// - -import XCTest -import TunnelKit -@testable import Passepartout - -class FileConfigurationTests: XCTestCase { - override func setUp() { - super.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. - super.tearDown() - } - - func testPIA() throws { - let file = try TunnelKitProvider.Configuration.parsed(fromURL: url(withName: "pia-hungary")) - XCTAssertEqual(file.hostname, "hungary.privateinternetaccess.com") - XCTAssertEqual(file.configuration.sessionConfiguration.cipher, .aes128cbc) - XCTAssertEqual(file.configuration.sessionConfiguration.digest, .sha1) - XCTAssertEqual(file.configuration.endpointProtocols, [ - TunnelKitProvider.EndpointProtocol(.udp, 1198), - TunnelKitProvider.EndpointProtocol(.tcp, 502) - ]) - } - - func testStripped() throws { - let lines = try TunnelKitProvider.Configuration.parsed(fromURL: url(withName: "pia-hungary"), returnsStripped: true).strippedLines! - let stripped = lines.joined(separator: "\n") - print(stripped) - } - - func testCompression() throws { - let base: [String] = ["", "", "remote 1.2.3.4"] - - XCTAssertNotNil(try TunnelKitProvider.Configuration.parsed(fromLines: base + ["comp-lzo"]).warning) - XCTAssertNoThrow(try TunnelKitProvider.Configuration.parsed(fromLines: base + ["comp-lzo no"])) - XCTAssertThrowsError(try TunnelKitProvider.Configuration.parsed(fromLines: base + ["comp-lzo yes"])) - - XCTAssertNoThrow(try TunnelKitProvider.Configuration.parsed(fromLines: base + ["compress"])) - XCTAssertThrowsError(try TunnelKitProvider.Configuration.parsed(fromLines: base + ["compress lzo"])) - } - - private func url(withName name: String) -> URL { - return Bundle(for: FileConfigurationTests.self).url(forResource: name, withExtension: "ovpn")! - } - -} diff --git a/PassepartoutTests-iOS/InfrastructureTests.swift b/PassepartoutTests-iOS/InfrastructureTests.swift index 5bf652e9..2e128381 100644 --- a/PassepartoutTests-iOS/InfrastructureTests.swift +++ b/PassepartoutTests-iOS/InfrastructureTests.swift @@ -53,21 +53,21 @@ class InfrastructureTests: XCTestCase { } func testStableSort() { - let original: [TunnelKitProvider.EndpointProtocol] = [ - TunnelKitProvider.EndpointProtocol(.udp, 1194), - TunnelKitProvider.EndpointProtocol(.udp, 8080), - TunnelKitProvider.EndpointProtocol(.udp, 9201), - TunnelKitProvider.EndpointProtocol(.udp, 53), - TunnelKitProvider.EndpointProtocol(.udp, 1197), - TunnelKitProvider.EndpointProtocol(.udp, 198), - TunnelKitProvider.EndpointProtocol(.tcp, 443), - TunnelKitProvider.EndpointProtocol(.tcp, 110), - TunnelKitProvider.EndpointProtocol(.tcp, 80), - TunnelKitProvider.EndpointProtocol(.tcp, 500), - TunnelKitProvider.EndpointProtocol(.tcp, 501), - TunnelKitProvider.EndpointProtocol(.tcp, 502) + let original: [EndpointProtocol] = [ + EndpointProtocol(.udp, 1194), + EndpointProtocol(.udp, 8080), + EndpointProtocol(.udp, 9201), + EndpointProtocol(.udp, 53), + EndpointProtocol(.udp, 1197), + EndpointProtocol(.udp, 198), + EndpointProtocol(.tcp, 443), + EndpointProtocol(.tcp, 110), + EndpointProtocol(.tcp, 80), + EndpointProtocol(.tcp, 500), + EndpointProtocol(.tcp, 501), + EndpointProtocol(.tcp, 502) ] - var preferredType: TunnelKitProvider.SocketType + var preferredType: SocketType preferredType = .udp let sorted1 = original.stableSorted { diff --git a/PassepartoutTests-iOS/pia-hungary.ovpn b/PassepartoutTests-iOS/pia-hungary.ovpn deleted file mode 100644 index 24e2a592..00000000 --- a/PassepartoutTests-iOS/pia-hungary.ovpn +++ /dev/null @@ -1,72 +0,0 @@ -client -dev tun -remote hungary.privateinternetaccess.com 1198 udp -remote hungary.privateinternetaccess.com 502 tcp -resolv-retry infinite -nobind -persist-key -persist-tun -setenv CLIENT_CERT 0 - - ------BEGIN CERTIFICATE----- -MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV -BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu -dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx -IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB -FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1 -MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex -EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg -QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE -AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 -ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy -bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD -L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX -lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp -cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/ -8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB -/5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC -OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL -y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO -sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM -b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G -A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg -SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz -czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j -b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn -a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU -ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3 -7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC -GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz -1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt -YDQ8z9v+DMO6iwyIDRiU ------END CERTIFICATE----- - - -cipher aes-128-cbc -auth sha1 -tls-client -remote-cert-tls server -auth-user-pass -comp-lzo no -verb 1 -reneg-sec 0 - - ------BEGIN X509 CRL----- -MIICWDCCAUAwDQYJKoZIhvcNAQENBQAwgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI -EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl -cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw -HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 -ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl -aW50ZXJuZXRhY2Nlc3MuY29tFw0xNjA3MDgxOTAwNDZaFw0zNjA3MDMxOTAwNDZa -MCYwEQIBARcMMTYwNzA4MTkwMDQ2MBECAQYXDDE2MDcwODE5MDA0NjANBgkqhkiG -9w0BAQ0FAAOCAQEAQZo9X97ci8EcPYu/uK2HB152OZbeZCINmYyluLDOdcSvg6B5 -jI+ffKN3laDvczsG6CxmY3jNyc79XVpEYUnq4rT3FfveW1+Ralf+Vf38HdpwB8EW -B4hZlQ205+21CALLvZvR8HcPxC9KEnev1mU46wkTiov0EKc+EdRxkj5yMgv0V2Re -ze7AP+NQ9ykvDScH4eYCsmufNpIjBLhpLE2cuZZXBLcPhuRzVoU3l7A9lvzG9mjA -5YijHJGHNjlWFqyrn1CfYS6koa4TGEPngBoAziWRbDGdhEgJABHrpoaFYaL61zqy -MR6jC0K2ps9qyZAN74LEBedEfK7tBOzWMwr58A== ------END X509 CRL----- - diff --git a/Podfile b/Podfile index 592d5316..b5f57624 100644 --- a/Podfile +++ b/Podfile @@ -2,8 +2,8 @@ source 'https://github.com/cocoapods/specs.git' use_frameworks! def shared_pods - #pod 'TunnelKit', '~> 1.3.0' - pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => 'caea662' + #pod 'TunnelKit', '~> 1.3.1' + pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => 'ac9ce0d' #pod 'TunnelKit', :path => '../../personal/tunnelkit' end diff --git a/Podfile.lock b/Podfile.lock index a7669522..aa5a1b64 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,19 +2,19 @@ PODS: - MBProgressHUD (1.1.0) - OpenSSL-Apple (1.1.0i-v2) - SwiftyBeaver (1.6.1) - - TunnelKit (1.3.1): - - TunnelKit/AppExtension (= 1.3.1) - - TunnelKit/Core (= 1.3.1) - - TunnelKit/AppExtension (1.3.1): + - TunnelKit (1.4.0): + - TunnelKit/AppExtension (= 1.4.0) + - TunnelKit/Core (= 1.4.0) + - TunnelKit/AppExtension (1.4.0): - SwiftyBeaver - TunnelKit/Core - - TunnelKit/Core (1.3.1): + - TunnelKit/Core (1.4.0): - OpenSSL-Apple (~> 1.1.0h) - SwiftyBeaver DEPENDENCIES: - MBProgressHUD - - TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `caea662`) + - TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `ac9ce0d`) SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -24,20 +24,20 @@ SPEC REPOS: EXTERNAL SOURCES: TunnelKit: - :commit: caea662 + :commit: ac9ce0d :git: https://github.com/keeshux/tunnelkit CHECKOUT OPTIONS: TunnelKit: - :commit: caea662 + :commit: ac9ce0d :git: https://github.com/keeshux/tunnelkit SPEC CHECKSUMS: MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9 OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a - TunnelKit: f98fb7d88642eda94c42007dbc501903c469a891 + TunnelKit: 8ac6ca743020b62e63bea66b3d169c53666fb737 -PODFILE CHECKSUM: a86923e57746e09e04296a49bdc0ad3520fd700f +PODFILE CHECKSUM: 07c9d064a6f7b053986d305449fa44258029bb35 COCOAPODS: 1.6.0.beta.2 diff --git a/README.md b/README.md index 7c4118fd..aa5debde 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # [Passepartout][about-website] ![iOS 11+](https://img.shields.io/badge/ios-11+-green.svg) -[![TunnelKit 1.3.x](https://img.shields.io/badge/tunnelkit-1.3-d69c68.svg)][dep-tunnelkit] +[![TunnelKit 1.4.x](https://img.shields.io/badge/tunnelkit-1.3-d69c68.svg)][dep-tunnelkit] [![License GPLv3](https://img.shields.io/badge/license-GPLv3-lightgray.svg)](LICENSE) [![Join TestFlight](https://img.shields.io/badge/beta-TestFlight-5ecdf6.svg)][about-testflight] [![Join Reddit](https://img.shields.io/badge/discuss-Reddit-orange.svg)][about-reddit] @@ -63,26 +63,9 @@ In preset mode, you can pick pre-resolved IPv4 endpoints when DNS is problematic ### Import .ovpn profiles -Passepartout can import .ovpn configuration files. This way you can fine-tune encryption without tweaking and reimporting a new configuration. Below are a few limitations worth mentioning. +Passepartout can import .ovpn configuration files. This way you can fine-tune encryption without tweaking and reimporting a new configuration. -Unsupported: - -- UDP fragmentation, i.e. `--fragment` -- Compression - - `--comp-lzo` other than `no` - - `--compress` other than empty -- Proxy -- External file references (inline `` only) -- Encrypted client certificate keys - -Ignored: - -- MTU overrides - - `--*-mtu` and variants - - `--mssfix` -- Multiple `--remote` with different `host` values (first wins) - -Many other flags are ignored too but it's normally not an issue. +You can find details on what may or may not work in the related section of the [TunnelKit README][dep-tunnelkit-ovpn]. ## Installation @@ -152,6 +135,7 @@ Website: [passepartoutvpn.app][about-website] [dep-jazzy]: https://github.com/realm/jazzy [dep-brew]: https://brew.sh/ [dep-tunnelkit]: https://github.com/keeshux/tunnelkit +[dep-tunnelkit-ovpn]: https://github.com/keeshux/tunnelkit#support-for-ovpn-configuration [dep-openssl]: https://www.openssl.org/ [license-content]: LICENSE From 9b91c7acd3458ad5c93656bb712b946a95ac836f Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Mon, 12 Nov 2018 10:45:47 +0100 Subject: [PATCH 2/2] Use versioned pod --- Podfile | 4 ++-- Podfile.lock | 15 +++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Podfile b/Podfile index b5f57624..69ba936f 100644 --- a/Podfile +++ b/Podfile @@ -2,8 +2,8 @@ source 'https://github.com/cocoapods/specs.git' use_frameworks! def shared_pods - #pod 'TunnelKit', '~> 1.3.1' - pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => 'ac9ce0d' + pod 'TunnelKit', '~> 1.4.0' + #pod 'TunnelKit', :git => 'https://github.com/keeshux/tunnelkit', :commit => 'ac9ce0d' #pod 'TunnelKit', :path => '../../personal/tunnelkit' end diff --git a/Podfile.lock b/Podfile.lock index aa5a1b64..5080a966 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -14,23 +14,14 @@ PODS: DEPENDENCIES: - MBProgressHUD - - TunnelKit (from `https://github.com/keeshux/tunnelkit`, commit `ac9ce0d`) + - TunnelKit (~> 1.4.0) SPEC REPOS: https://github.com/cocoapods/specs.git: - MBProgressHUD - OpenSSL-Apple - SwiftyBeaver - -EXTERNAL SOURCES: - TunnelKit: - :commit: ac9ce0d - :git: https://github.com/keeshux/tunnelkit - -CHECKOUT OPTIONS: - TunnelKit: - :commit: ac9ce0d - :git: https://github.com/keeshux/tunnelkit + - TunnelKit SPEC CHECKSUMS: MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9 @@ -38,6 +29,6 @@ SPEC CHECKSUMS: SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a TunnelKit: 8ac6ca743020b62e63bea66b3d169c53666fb737 -PODFILE CHECKSUM: 07c9d064a6f7b053986d305449fa44258029bb35 +PODFILE CHECKSUM: 286e244242c593f64bdb564cfa8a8048df3c956b COCOAPODS: 1.6.0.beta.2