providerConfiguration is now a WgQuickConfig

Signed-off-by: Eric Kuck <eric@bluelinelabs.com>
This commit is contained in:
Eric Kuck
2018-12-21 16:32:08 -06:00
parent accf60b82f
commit 1fecd8eb6c
19 changed files with 109 additions and 315 deletions
+1 -4
View File
@@ -187,10 +187,7 @@ extension NETunnelProviderProtocol {
private func migrateFromConfigurationV1() { private func migrateFromConfigurationV1() {
guard let serializedTunnelConfiguration = providerConfiguration?["tunnelConfiguration"] as? Data else { return } guard let serializedTunnelConfiguration = providerConfiguration?["tunnelConfiguration"] as? Data else { return }
guard let configuration = try? JSONDecoder().decode(LegacyTunnelConfiguration.self, from: serializedTunnelConfiguration) else { return } guard let configuration = try? JSONDecoder().decode(LegacyTunnelConfiguration.self, from: serializedTunnelConfiguration) else { return }
guard let tunnelConfigData = try? JSONEncoder().encode(configuration.migrated) else { return } providerConfiguration = [Keys.wgQuickConfig.rawValue: configuration.migrated.asWgQuickConfig()]
guard let tunnelConfigDictionary = try? JSONSerialization.jsonObject(with: tunnelConfigData, options: .allowFragments) else { return }
providerConfiguration = [Keys.wgQuickConfig.rawValue: tunnelConfigDictionary]
} }
} }
-24
View File
@@ -12,30 +12,6 @@ struct DNSServer {
} }
} }
extension DNSServer: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(stringRepresentation)
}
public init(from decoder: Decoder) throws {
let values = try decoder.singleValueContainer()
let addressString = try values.decode(String.self)
if let address = IPv4Address(addressString) {
self.address = address
} else if let address = IPv6Address(addressString) {
self.address = address
} else {
throw DecodingError.invalidData
}
}
enum DecodingError: Error {
case invalidData
}
}
extension DNSServer { extension DNSServer {
var stringRepresentation: String { var stringRepresentation: String {
return "\(address)" return "\(address)"
-20
View File
@@ -14,26 +14,6 @@ struct Endpoint {
} }
} }
extension Endpoint: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let endpointString = try container.decode(String.self)
guard let endpoint = Endpoint(from: endpointString) else {
throw DecodingError.invalidData
}
self = endpoint
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(stringRepresentation)
}
enum DecodingError: Error {
case invalidData
}
}
extension Endpoint { extension Endpoint {
var stringRepresentation: String { var stringRepresentation: String {
switch host { switch host {
@@ -52,22 +52,3 @@ extension IPAddressRange {
return (address, networkPrefixLength) return (address, networkPrefixLength)
} }
} }
extension IPAddressRange: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(stringRepresentation)
}
public init(from decoder: Decoder) throws {
let values = try decoder.singleValueContainer()
let addressString = try values.decode(String.self)
guard let parsed = IPAddressRange.parseAddressString(addressString) else { throw DecodingError.invalidData }
address = parsed.0
networkPrefixLength = parsed.1
}
enum DecodingError: Error {
case invalidData
}
}
@@ -4,56 +4,18 @@
import Foundation import Foundation
struct InterfaceConfiguration { struct InterfaceConfiguration {
var name: String var name: String?
var privateKey: Data var privateKey: Data
var addresses = [IPAddressRange]() var addresses = [IPAddressRange]()
var listenPort: UInt16? var listenPort: UInt16?
var mtu: UInt16? var mtu: UInt16?
var dns = [DNSServer]() var dns = [DNSServer]()
init(name: String, privateKey: Data) { init(name: String?, privateKey: Data) {
self.name = name self.name = name
self.privateKey = privateKey self.privateKey = privateKey
if name.isEmpty {
fatalError("Empty name")
}
if privateKey.count != TunnelConfiguration.keyLength { if privateKey.count != TunnelConfiguration.keyLength {
fatalError("Invalid private key") fatalError("Invalid private key")
} }
} }
} }
extension InterfaceConfiguration: Codable {
enum CodingKeys: String, CodingKey {
case name = "Name"
case privateKey = "PrivateKey"
case addresses = "Address"
case listenPort = "ListenPort"
case mtu = "MTU"
case dns = "DNS"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
privateKey = try Data(base64Encoded: values.decode(String.self, forKey: .privateKey))!
addresses = try values.decode([IPAddressRange].self, forKey: .addresses)
listenPort = try? values.decode(UInt16.self, forKey: .listenPort)
mtu = try? values.decode(UInt16.self, forKey: .mtu)
dns = try values.decode([DNSServer].self, forKey: .dns)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(privateKey.base64EncodedString(), forKey: .privateKey)
try container.encode(addresses, forKey: .addresses)
if let listenPort = listenPort {
try container.encode(listenPort, forKey: .listenPort)
}
if let mtu = mtu {
try container.encode(mtu, forKey: .mtu)
}
try container.encode(dns, forKey: .dns)
}
}
@@ -25,42 +25,3 @@ struct PeerConfiguration {
} }
} }
} }
extension PeerConfiguration: Codable {
enum CodingKeys: String, CodingKey {
case publicKey = "PublicKey"
case preSharedKey = "PreSharedKey"
case allowedIPs = "AllowedIPs"
case endpoint = "Endpoint"
case persistentKeepAlive = "PersistentKeepAlive"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
publicKey = try Data(base64Encoded: values.decode(String.self, forKey: .publicKey))!
if let base64PreSharedKey = try? values.decode(Data.self, forKey: .preSharedKey) {
preSharedKey = Data(base64Encoded: base64PreSharedKey)
} else {
preSharedKey = nil
}
allowedIPs = try values.decode([IPAddressRange].self, forKey: .allowedIPs)
endpoint = try? values.decode(Endpoint.self, forKey: .endpoint)
persistentKeepAlive = try? values.decode(UInt16.self, forKey: .persistentKeepAlive)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(publicKey.base64EncodedString(), forKey: .publicKey)
if let preSharedKey = preSharedKey {
try container.encode(preSharedKey.base64EncodedString(), forKey: .preSharedKey)
}
try container.encode(allowedIPs, forKey: .allowedIPs)
if let endpoint = endpoint {
try container.encode(endpoint, forKey: .endpoint)
}
if let persistentKeepAlive = persistentKeepAlive {
try container.encode(persistentKeepAlive, forKey: .persistentKeepAlive)
}
}
}
@@ -20,23 +20,3 @@ final class TunnelConfiguration {
} }
} }
} }
extension TunnelConfiguration: Codable {
enum CodingKeys: String, CodingKey {
case interface = "Interface"
case peers = "Peer"
}
convenience init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let interface = try values.decode(InterfaceConfiguration.self, forKey: .interface)
let peers = try values.decode([PeerConfiguration].self, forKey: .peers)
self.init(interface: interface, peers: peers)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(interface, forKey: .interface)
try container.encode(peers, forKey: .peers)
}
}
@@ -3,37 +3,20 @@
import NetworkExtension import NetworkExtension
private var tunnelNameKey: Void?
extension NETunnelProviderProtocol { extension NETunnelProviderProtocol {
enum Keys: String { enum Keys: String {
case wgQuickConfig = "WgQuickConfigV1" case wgQuickConfig = "WgQuickConfig"
}
var tunnelConfiguration: TunnelConfiguration? {
migrateConfigurationIfNeeded()
let tunnelConfigurationData: Data?
if let configurationDictionary = providerConfiguration?[Keys.wgQuickConfig.rawValue] {
tunnelConfigurationData = try? JSONSerialization.data(withJSONObject: configurationDictionary, options: [])
} else {
tunnelConfigurationData = nil
}
guard tunnelConfigurationData != nil else { return nil }
return try? JSONDecoder().decode(TunnelConfiguration.self, from: tunnelConfigurationData!)
} }
convenience init?(tunnelConfiguration: TunnelConfiguration) { convenience init?(tunnelConfiguration: TunnelConfiguration) {
assert(!tunnelConfiguration.interface.name.isEmpty)
guard let tunnelConfigData = try? JSONEncoder().encode(tunnelConfiguration) else { return nil }
guard let tunnelConfigDictionary = try? JSONSerialization.jsonObject(with: tunnelConfigData, options: .allowFragments) else { return nil }
self.init() self.init()
let appId = Bundle.main.bundleIdentifier! let appId = Bundle.main.bundleIdentifier!
providerBundleIdentifier = "\(appId).network-extension" providerBundleIdentifier = "\(appId).network-extension"
providerConfiguration = [ Keys.wgQuickConfig.rawValue: tunnelConfigDictionary ] providerConfiguration = [Keys.wgQuickConfig.rawValue: tunnelConfiguration.asWgQuickConfig()]
let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint } let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
if endpoints.count == 1 { if endpoints.count == 1 {
@@ -43,13 +26,14 @@ extension NETunnelProviderProtocol {
} else { } else {
serverAddress = "Multiple endpoints" serverAddress = "Multiple endpoints"
} }
username = tunnelConfiguration.interface.name username = tunnelConfiguration.interface.name
} }
func hasTunnelConfiguration(tunnelConfiguration otherTunnelConfiguration: TunnelConfiguration) -> Bool { func tunnelConfiguration(name: String?) -> TunnelConfiguration? {
guard let serializedThisTunnelConfiguration = try? JSONEncoder().encode(tunnelConfiguration) else { return false } migrateConfigurationIfNeeded()
guard let serializedOtherTunnelConfiguration = try? JSONEncoder().encode(otherTunnelConfiguration) else { return false } guard let serializedConfig = providerConfiguration?[Keys.wgQuickConfig.rawValue] as? String else { return nil }
return serializedThisTunnelConfiguration == serializedOtherTunnelConfiguration return try? TunnelConfiguration(serializedConfig, name: name)
} }
} }
@@ -3,7 +3,7 @@
import Foundation import Foundation
class WgQuickConfigFileParser { extension TunnelConfiguration {
enum ParserState { enum ParserState {
case inInterfaceSection case inInterfaceSection
@@ -21,13 +21,11 @@ class WgQuickConfigFileParser {
} }
//swiftlint:disable:next cyclomatic_complexity function_body_length //swiftlint:disable:next cyclomatic_complexity function_body_length
static func parse(_ text: String, name: String) throws -> TunnelConfiguration { convenience init(_ wgQuickConfig: String, name: String?) throws {
assert(!name.isEmpty)
var interfaceConfiguration: InterfaceConfiguration? var interfaceConfiguration: InterfaceConfiguration?
var peerConfigurations = [PeerConfiguration]() var peerConfigurations = [PeerConfiguration]()
let lines = text.split(separator: "\n") let lines = wgQuickConfig.split(separator: "\n")
var parserState = ParserState.notInASection var parserState = ParserState.notInASection
var attributes = [String: String]() var attributes = [String: String]()
@@ -64,11 +62,11 @@ class WgQuickConfigFileParser {
if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" { if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" {
// Previous section has ended; process the attributes collected so far // Previous section has ended; process the attributes collected so far
if parserState == .inInterfaceSection { if parserState == .inInterfaceSection {
guard let interface = collate(interfaceAttributes: attributes, name: name) else { throw ParseError.invalidInterface } guard let interface = TunnelConfiguration.collate(interfaceAttributes: attributes, name: name) else { throw ParseError.invalidInterface }
guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces } guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces }
interfaceConfiguration = interface interfaceConfiguration = interface
} else if parserState == .inPeerSection { } else if parserState == .inPeerSection {
guard let peer = collate(peerAttributes: attributes) else { throw ParseError.invalidPeer } guard let peer = TunnelConfiguration.collate(peerAttributes: attributes) else { throw ParseError.invalidPeer }
peerConfigurations.append(peer) peerConfigurations.append(peer)
} }
} }
@@ -89,15 +87,53 @@ class WgQuickConfigFileParser {
} }
if let interfaceConfiguration = interfaceConfiguration { if let interfaceConfiguration = interfaceConfiguration {
let tunnelConfiguration = TunnelConfiguration(interface: interfaceConfiguration, peers: peerConfigurations) self.init(interface: interfaceConfiguration, peers: peerConfigurations)
return tunnelConfiguration
} else { } else {
throw ParseError.noInterface throw ParseError.noInterface
} }
} }
func asWgQuickConfig() -> String {
var output = "[Interface]\n"
output.append("PrivateKey = \(interface.privateKey.base64EncodedString())\n")
if let listenPort = interface.listenPort {
output.append("ListenPort = \(listenPort)\n")
}
if !interface.addresses.isEmpty {
let addressString = interface.addresses.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("Address = \(addressString)\n")
}
if !interface.dns.isEmpty {
let dnsString = interface.dns.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("DNS = \(dnsString)\n")
}
if let mtu = interface.mtu {
output.append("MTU = \(mtu)\n")
}
for peer in peers {
output.append("\n[Peer]\n")
output.append("PublicKey = \(peer.publicKey.base64EncodedString())\n")
if let preSharedKey = peer.preSharedKey {
output.append("PresharedKey = \(preSharedKey.base64EncodedString())\n")
}
if !peer.allowedIPs.isEmpty {
let allowedIPsString = peer.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("AllowedIPs = \(allowedIPsString)\n")
}
if let endpoint = peer.endpoint {
output.append("Endpoint = \(endpoint.stringRepresentation)\n")
}
if let persistentKeepAlive = peer.persistentKeepAlive {
output.append("PersistentKeepalive = \(persistentKeepAlive)\n")
}
}
return output
}
//swiftlint:disable:next cyclomatic_complexity //swiftlint:disable:next cyclomatic_complexity
private static func collate(interfaceAttributes attributes: [String: String], name: String) -> InterfaceConfiguration? { private static func collate(interfaceAttributes attributes: [String: String], name: String?) -> InterfaceConfiguration? {
// required wg fields // required wg fields
guard let privateKeyString = attributes["privatekey"] else { return nil } guard let privateKeyString = attributes["privatekey"] else { return nil }
guard let privateKey = Data(base64Encoded: privateKeyString), privateKey.count == TunnelConfiguration.keyLength else { return nil } guard let privateKey = Data(base64Encoded: privateKeyString), privateKey.count == TunnelConfiguration.keyLength else { return nil }
+9 -17
View File
@@ -20,6 +20,9 @@
5F4541B221CBFAEE00994C13 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */; }; 5F4541B221CBFAEE00994C13 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */; };
5F9696AA21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */; }; 5F9696AA21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */; };
5F9696AB21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */; }; 5F9696AB21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */; };
5F9696AE21CD6F72008063FE /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */; };
5F9696B021CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696AF21CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift */; };
5F9696B121CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F9696AF21CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift */; };
5FF7B96221CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */; }; 5FF7B96221CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */; };
5FF7B96321CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */; }; 5FF7B96321CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */; };
5FF7B96521CC95FA00A7DD74 /* PeerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96421CC95FA00A7DD74 /* PeerConfiguration.swift */; }; 5FF7B96521CC95FA00A7DD74 /* PeerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF7B96421CC95FA00A7DD74 /* PeerConfiguration.swift */; };
@@ -35,7 +38,6 @@
6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */; }; 6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */; };
6F6899A62180447E0012E523 /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A52180447E0012E523 /* x25519.c */; }; 6F6899A62180447E0012E523 /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A52180447E0012E523 /* x25519.c */; };
6F6899A8218044FC0012E523 /* Curve25519.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A7218044FC0012E523 /* Curve25519.swift */; }; 6F6899A8218044FC0012E523 /* Curve25519.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899A7218044FC0012E523 /* Curve25519.swift */; };
6F6899AC218099F00012E523 /* WgQuickConfigFileParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6899AB218099F00012E523 /* WgQuickConfigFileParser.swift */; };
6F693A562179E556008551C1 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F693A552179E556008551C1 /* Endpoint.swift */; }; 6F693A562179E556008551C1 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F693A552179E556008551C1 /* Endpoint.swift */; };
6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774DF217181B1006A79B3 /* MainViewController.swift */; }; 6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774DF217181B1006A79B3 /* MainViewController.swift */; };
6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E0217181B1006A79B3 /* AppDelegate.swift */; }; 6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E0217181B1006A79B3 /* AppDelegate.swift */; };
@@ -58,7 +60,6 @@
6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF7FF21863C0100D8FBF6 /* ioapi.c */; }; 6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF7FF21863C0100D8FBF6 /* ioapi.c */; };
6FDEF802218646BA00D8FBF6 /* ZipArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF801218646B900D8FBF6 /* ZipArchive.swift */; }; 6FDEF802218646BA00D8FBF6 /* ZipArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF801218646B900D8FBF6 /* ZipArchive.swift */; };
6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */; }; 6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */; };
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */; };
6FE1765621C90BBE002690EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6FE1765421C90BBE002690EA /* Localizable.strings */; }; 6FE1765621C90BBE002690EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6FE1765421C90BBE002690EA /* Localizable.strings */; };
6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE1765921C90E87002690EA /* LocalizationHelper.swift */; }; 6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE1765921C90E87002690EA /* LocalizationHelper.swift */; };
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; }; 6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
@@ -125,6 +126,7 @@
5F4541AD21C7704300994C13 /* NEVPNStatus+CustomStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NEVPNStatus+CustomStringConvertible.swift"; sourceTree = "<group>"; }; 5F4541AD21C7704300994C13 /* NEVPNStatus+CustomStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NEVPNStatus+CustomStringConvertible.swift"; sourceTree = "<group>"; };
5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ArrayConversion.swift"; sourceTree = "<group>"; }; 5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ArrayConversion.swift"; sourceTree = "<group>"; };
5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyConfigMigration.swift; sourceTree = "<group>"; }; 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyConfigMigration.swift; sourceTree = "<group>"; };
5F9696AF21CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelConfiguration+WgQuickConfig.swift"; sourceTree = "<group>"; };
5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceConfiguration.swift; sourceTree = "<group>"; }; 5FF7B96121CC95DE00A7DD74 /* InterfaceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceConfiguration.swift; sourceTree = "<group>"; };
5FF7B96421CC95FA00A7DD74 /* PeerConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerConfiguration.swift; sourceTree = "<group>"; }; 5FF7B96421CC95FA00A7DD74 /* PeerConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerConfiguration.swift; sourceTree = "<group>"; };
6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Extension.swift"; sourceTree = "<group>"; }; 6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Extension.swift"; sourceTree = "<group>"; };
@@ -144,7 +146,6 @@
6F6899A42180447E0012E523 /* x25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x25519.h; sourceTree = "<group>"; }; 6F6899A42180447E0012E523 /* x25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x25519.h; sourceTree = "<group>"; };
6F6899A52180447E0012E523 /* x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x25519.c; sourceTree = "<group>"; }; 6F6899A52180447E0012E523 /* x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x25519.c; sourceTree = "<group>"; };
6F6899A7218044FC0012E523 /* Curve25519.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Curve25519.swift; sourceTree = "<group>"; }; 6F6899A7218044FC0012E523 /* Curve25519.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Curve25519.swift; sourceTree = "<group>"; };
6F6899AB218099F00012E523 /* WgQuickConfigFileParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileParser.swift; sourceTree = "<group>"; };
6F693A552179E556008551C1 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; }; 6F693A552179E556008551C1 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
6F7774DF217181B1006A79B3 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; }; 6F7774DF217181B1006A79B3 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
6F7774E0217181B1006A79B3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 6F7774E0217181B1006A79B3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -170,7 +171,6 @@
6FDEF7FF21863C0100D8FBF6 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; }; 6FDEF7FF21863C0100D8FBF6 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; };
6FDEF801218646B900D8FBF6 /* ZipArchive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = "<group>"; }; 6FDEF801218646B900D8FBF6 /* ZipArchive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = "<group>"; };
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; }; 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileWriter.swift; sourceTree = "<group>"; };
6FE1765521C90BBE002690EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = WireGuard/Base.lproj/Localizable.strings; sourceTree = "<group>"; }; 6FE1765521C90BBE002690EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = WireGuard/Base.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; }; 6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; };
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; }; 6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
@@ -258,6 +258,8 @@
6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */, 6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */,
6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */, 6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */,
5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */, 5F9696A921CD6AE6008063FE /* LegacyConfigMigration.swift */,
5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */,
5F9696AF21CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift */,
); );
path = Shared; path = Shared;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -272,15 +274,6 @@
path = Crypto; path = Crypto;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6F6899AA218099D00012E523 /* ConfigFile */ = {
isa = PBXGroup;
children = (
6F6899AB218099F00012E523 /* WgQuickConfigFileParser.swift */,
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */,
);
path = ConfigFile;
sourceTree = "<group>";
};
6F7774DD217181B1006A79B3 /* UI */ = { 6F7774DD217181B1006A79B3 /* UI */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -298,7 +291,6 @@
6F7774E0217181B1006A79B3 /* AppDelegate.swift */, 6F7774E0217181B1006A79B3 /* AppDelegate.swift */,
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */, 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */,
5F45417C21C1B23600994C13 /* UITableViewCell+Reuse.swift */, 5F45417C21C1B23600994C13 /* UITableViewCell+Reuse.swift */,
5F4541B121CBFAEE00994C13 /* String+ArrayConversion.swift */,
); );
path = iOS; path = iOS;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -416,7 +408,6 @@
children = ( children = (
6F919ED3218C65C50023B400 /* Resources */, 6F919ED3218C65C50023B400 /* Resources */,
6F6899A32180445A0012E523 /* Crypto */, 6F6899A32180445A0012E523 /* Crypto */,
6F6899AA218099D00012E523 /* ConfigFile */,
6F7774DD217181B1006A79B3 /* UI */, 6F7774DD217181B1006A79B3 /* UI */,
6F7774ED21722D0C006A79B3 /* Tunnel */, 6F7774ED21722D0C006A79B3 /* Tunnel */,
6FDEF7E72186320E00D8FBF6 /* ZipArchive */, 6FDEF7E72186320E00D8FBF6 /* ZipArchive */,
@@ -664,9 +655,11 @@
6FF3527121C240160008484E /* Logger.swift in Sources */, 6FF3527121C240160008484E /* Logger.swift in Sources */,
6F5A2B4621AFDED40081EDD8 /* FileManager+Extension.swift in Sources */, 6F5A2B4621AFDED40081EDD8 /* FileManager+Extension.swift in Sources */,
6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */, 6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */,
5F9696B121CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift in Sources */,
6FFA5D96219446380001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */, 6FFA5D96219446380001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
6FFA5D8E2194370D0001E2F7 /* TunnelConfiguration.swift in Sources */, 6FFA5D8E2194370D0001E2F7 /* TunnelConfiguration.swift in Sources */,
5FF7B96621CC95FA00A7DD74 /* PeerConfiguration.swift in Sources */, 5FF7B96621CC95FA00A7DD74 /* PeerConfiguration.swift in Sources */,
5F9696AE21CD6F72008063FE /* String+ArrayConversion.swift in Sources */,
6FFA5D8F2194370D0001E2F7 /* IPAddressRange.swift in Sources */, 6FFA5D8F2194370D0001E2F7 /* IPAddressRange.swift in Sources */,
6FFA5D902194370D0001E2F7 /* Endpoint.swift in Sources */, 6FFA5D902194370D0001E2F7 /* Endpoint.swift in Sources */,
5FF7B96321CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */, 5FF7B96321CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */,
@@ -685,7 +678,6 @@
6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */, 6FE1765A21C90E87002690EA /* LocalizationHelper.swift in Sources */,
6FF3527221C2616C0008484E /* ringlogger.c in Sources */, 6FF3527221C2616C0008484E /* ringlogger.c in Sources */,
6FF3527321C2616C0008484E /* Logger.swift in Sources */, 6FF3527321C2616C0008484E /* Logger.swift in Sources */,
6F6899AC218099F00012E523 /* WgQuickConfigFileParser.swift in Sources */,
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */, 6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */, 6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
5F45417D21C1B23600994C13 /* UITableViewCell+Reuse.swift in Sources */, 5F45417D21C1B23600994C13 /* UITableViewCell+Reuse.swift in Sources */,
@@ -710,7 +702,6 @@
5F9696AA21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */, 5F9696AA21CD6AE6008063FE /* LegacyConfigMigration.swift in Sources */,
6F5A2B4821AFF49A0081EDD8 /* FileManager+Extension.swift in Sources */, 6F5A2B4821AFF49A0081EDD8 /* FileManager+Extension.swift in Sources */,
5F45418C21C2D48200994C13 /* TunnelEditKeyValueCell.swift in Sources */, 5F45418C21C2D48200994C13 /* TunnelEditKeyValueCell.swift in Sources */,
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */,
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */, 6FE254FB219C10800028284D /* ZipImporter.swift in Sources */,
6F7774EA217229DB006A79B3 /* IPAddressRange.swift in Sources */, 6F7774EA217229DB006A79B3 /* IPAddressRange.swift in Sources */,
5F4541AE21C7704300994C13 /* NEVPNStatus+CustomStringConvertible.swift in Sources */, 5F4541AE21C7704300994C13 /* NEVPNStatus+CustomStringConvertible.swift in Sources */,
@@ -718,6 +709,7 @@
6FDEF7FB21863B6100D8FBF6 /* unzip.c in Sources */, 6FDEF7FB21863B6100D8FBF6 /* unzip.c in Sources */,
6F6899A8218044FC0012E523 /* Curve25519.swift in Sources */, 6F6899A8218044FC0012E523 /* Curve25519.swift in Sources */,
5F4541A021C2D6B700994C13 /* TunnelListCell.swift in Sources */, 5F4541A021C2D6B700994C13 /* TunnelListCell.swift in Sources */,
5F9696B021CD7128008063FE /* TunnelConfiguration+WgQuickConfig.swift in Sources */,
6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */, 6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */,
6F61F1EB21B937EF00483816 /* WireGuardResult.swift in Sources */, 6F61F1EB21B937EF00483816 /* WireGuardResult.swift in Sources */,
6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */, 6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */,
@@ -1,46 +0,0 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018 WireGuard LLC. All Rights Reserved.
import UIKit
class WgQuickConfigFileWriter {
static func writeConfigFile(from configuration: TunnelConfiguration) -> Data? {
let interface = configuration.interface
var output = "[Interface]\n"
output.append("PrivateKey = \(interface.privateKey.base64EncodedString())\n")
if let listenPort = interface.listenPort {
output.append("ListenPort = \(listenPort)\n")
}
if !interface.addresses.isEmpty {
let addressString = interface.addresses.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("Address = \(addressString)\n")
}
if !interface.dns.isEmpty {
let dnsString = interface.dns.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("DNS = \(dnsString)\n")
}
if let mtu = interface.mtu {
output.append("MTU = \(mtu)\n")
}
for peer in configuration.peers {
output.append("\n[Peer]\n")
output.append("PublicKey = \(peer.publicKey.base64EncodedString())\n")
if let preSharedKey = peer.preSharedKey {
output.append("PresharedKey = \(preSharedKey.base64EncodedString())\n")
}
if !peer.allowedIPs.isEmpty {
let allowedIPsString = peer.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("AllowedIPs = \(allowedIPsString)\n")
}
if let endpoint = peer.endpoint {
output.append("Endpoint = \(endpoint.stringRepresentation)\n")
}
if let persistentKeepAlive = peer.persistentKeepAlive {
output.append("PersistentKeepalive = \(persistentKeepAlive)\n")
}
}
return output.data(using: .utf8)
}
}
+1 -1
View File
@@ -38,7 +38,7 @@ class MockTunnels {
let tunnelProviderManager = NETunnelProviderManager() let tunnelProviderManager = NETunnelProviderManager()
tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration) tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration)
tunnelProviderManager.localizedDescription = tunnelName tunnelProviderManager.localizedDescription = (tunnelConfiguration).interface.name
tunnelProviderManager.isEnabled = true tunnelProviderManager.isEnabled = true
return tunnelProviderManager return tunnelProviderManager
+12 -16
View File
@@ -43,9 +43,9 @@ class TunnelsManager {
} }
let tunnelManagers = managers ?? [] let tunnelManagers = managers ?? []
tunnelManagers.forEach { tunnelManagers.forEach { tunnelManager in
if ($0.protocolConfiguration as? NETunnelProviderProtocol)?.migrateConfigurationIfNeeded() == true { if (tunnelManager.protocolConfiguration as? NETunnelProviderProtocol)?.migrateConfigurationIfNeeded() == true {
$0.saveToPreferences { _ in } tunnelManager.saveToPreferences { _ in }
} }
} }
completionHandler(.success(TunnelsManager(tunnelProviders: tunnelManagers))) completionHandler(.success(TunnelsManager(tunnelProviders: tunnelManagers)))
@@ -54,7 +54,7 @@ class TunnelsManager {
} }
func add(tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting = ActivateOnDemandSetting.defaultSetting, completionHandler: @escaping (WireGuardResult<TunnelContainer>) -> Void) { func add(tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting = ActivateOnDemandSetting.defaultSetting, completionHandler: @escaping (WireGuardResult<TunnelContainer>) -> Void) {
let tunnelName = tunnelConfiguration.interface.name let tunnelName = tunnelConfiguration.interface.name ?? ""
if tunnelName.isEmpty { if tunnelName.isEmpty {
completionHandler(.failure(TunnelsManagerError.tunnelNameEmpty)) completionHandler(.failure(TunnelsManagerError.tunnelNameEmpty))
return return
@@ -67,7 +67,7 @@ class TunnelsManager {
let tunnelProviderManager = NETunnelProviderManager() let tunnelProviderManager = NETunnelProviderManager()
tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration) tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration)
tunnelProviderManager.localizedDescription = tunnelName tunnelProviderManager.localizedDescription = (tunnelConfiguration).interface.name
tunnelProviderManager.isEnabled = true tunnelProviderManager.isEnabled = true
activateOnDemandSetting.apply(on: tunnelProviderManager) activateOnDemandSetting.apply(on: tunnelProviderManager)
@@ -107,7 +107,7 @@ class TunnelsManager {
} }
func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting, completionHandler: @escaping (TunnelsManagerError?) -> Void) { func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration, activateOnDemandSetting: ActivateOnDemandSetting, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
let tunnelName = tunnelConfiguration.interface.name let tunnelName = tunnelConfiguration.interface.name ?? ""
if tunnelName.isEmpty { if tunnelName.isEmpty {
completionHandler(TunnelsManagerError.tunnelNameEmpty) completionHandler(TunnelsManagerError.tunnelNameEmpty)
return return
@@ -123,10 +123,8 @@ class TunnelsManager {
tunnel.name = tunnelName tunnel.name = tunnelName
} }
let shouldRestartIfActive = !((tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.hasTunnelConfiguration(tunnelConfiguration: tunnelConfiguration) ?? false)
tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration) tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration)
tunnelProviderManager.localizedDescription = tunnelName tunnelProviderManager.localizedDescription = (tunnelConfiguration).interface.name
tunnelProviderManager.isEnabled = true tunnelProviderManager.isEnabled = true
let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && activateOnDemandSetting.isActivateOnDemandEnabled let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && activateOnDemandSetting.isActivateOnDemandEnabled
@@ -148,12 +146,10 @@ class TunnelsManager {
} }
self.tunnelsListDelegate?.tunnelModified(at: self.tunnels.firstIndex(of: tunnel)!) self.tunnelsListDelegate?.tunnelModified(at: self.tunnels.firstIndex(of: tunnel)!)
if shouldRestartIfActive { if tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting {
if tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting { // Turn off the tunnel, and then turn it back on, so the changes are made effective
// Turn off the tunnel, and then turn it back on, so the changes are made effective tunnel.status = .restarting
tunnel.status = .restarting (tunnel.tunnelProvider.connection as? NETunnelProviderSession)?.stopTunnel()
(tunnel.tunnelProvider.connection as? NETunnelProviderSession)?.stopTunnel()
}
} }
if isActivatingOnDemand { if isActivatingOnDemand {
@@ -353,7 +349,7 @@ class TunnelContainer: NSObject {
private var lastTunnelConnectionStatus: NEVPNStatus? private var lastTunnelConnectionStatus: NEVPNStatus?
var tunnelConfiguration: TunnelConfiguration? { var tunnelConfiguration: TunnelConfiguration? {
return (tunnelProvider.protocolConfiguration as? NETunnelProviderProtocol)?.tunnelConfiguration return (tunnelProvider.protocolConfiguration as? NETunnelProviderProtocol)?.tunnelConfiguration(name: tunnelProvider.localizedDescription)
} }
var activateOnDemandSetting: ActivateOnDemandSetting { var activateOnDemandSetting: ActivateOnDemandSetting {
@@ -101,7 +101,7 @@ class QRScanViewController: UIViewController {
} }
func scanDidComplete(withCode code: String) { func scanDidComplete(withCode code: String) {
let scannedTunnelConfiguration = try? WgQuickConfigFileParser.parse(code, name: "Scanned") let scannedTunnelConfiguration = try? TunnelConfiguration(code, name: "Scanned")
guard let tunnelConfiguration = scannedTunnelConfiguration else { guard let tunnelConfiguration = scannedTunnelConfiguration else {
scanDidEncounterError(title: tr("alertScanQRCodeInvalidQRCodeTitle"), message: tr("alertScanQRCodeInvalidQRCodeMessage")) scanDidEncounterError(title: tr("alertScanQRCodeInvalidQRCodeTitle"), message: tr("alertScanQRCodeInvalidQRCodeMessage"))
return return
@@ -180,7 +180,7 @@ class TunnelsListTableViewController: UIViewController {
} else /* if (url.pathExtension == "conf") -- we assume everything else is a conf */ { } else /* if (url.pathExtension == "conf") -- we assume everything else is a conf */ {
let fileBaseName = url.deletingPathExtension().lastPathComponent.trimmingCharacters(in: .whitespacesAndNewlines) let fileBaseName = url.deletingPathExtension().lastPathComponent.trimmingCharacters(in: .whitespacesAndNewlines)
if let fileContents = try? String(contentsOf: url), if let fileContents = try? String(contentsOf: url),
let tunnelConfiguration = try? WgQuickConfigFileParser.parse(fileContents, name: fileBaseName) { let tunnelConfiguration = try? TunnelConfiguration(fileContents, name: fileBaseName) {
tunnelsManager.add(tunnelConfiguration: tunnelConfiguration) { [weak self] result in tunnelsManager.add(tunnelConfiguration: tunnelConfiguration) { [weak self] result in
if let error = result.error { if let error = result.error {
ErrorPresenter.showErrorAlert(error: error, from: self, onPresented: completionHandler) ErrorPresenter.showErrorAlert(error: error, from: self, onPresented: completionHandler)
@@ -22,8 +22,8 @@ class ZipExporter {
var inputsToArchiver: [(fileName: String, contents: Data)] = [] var inputsToArchiver: [(fileName: String, contents: Data)] = []
var lastTunnelName: String = "" var lastTunnelName: String = ""
for tunnelConfiguration in tunnelConfigurations { for tunnelConfiguration in tunnelConfigurations {
if let contents = WgQuickConfigFileWriter.writeConfigFile(from: tunnelConfiguration) { if let contents = tunnelConfiguration.asWgQuickConfig().data(using: .utf8) {
let name = tunnelConfiguration.interface.name let name = tunnelConfiguration.interface.name ?? ""
if name.isEmpty || name == lastTunnelName { continue } if name.isEmpty || name == lastTunnelName { continue }
inputsToArchiver.append((fileName: "\(name).conf", contents: contents)) inputsToArchiver.append((fileName: "\(name).conf", contents: contents))
lastTunnelName = name lastTunnelName = name
@@ -43,12 +43,8 @@ class ZipImporter {
if index > 0 && file == unarchivedFiles[index - 1] { if index > 0 && file == unarchivedFiles[index - 1] {
continue continue
} }
guard let fileContents = String(data: file.contents, encoding: .utf8) else { guard let fileContents = String(data: file.contents, encoding: .utf8) else { continue }
continue guard let tunnelConfig = try? TunnelConfiguration(fileContents, name: file.fileBaseName) else { continue }
}
guard let tunnelConfig = try? WgQuickConfigFileParser.parse(fileContents, name: file.fileBaseName) else {
continue
}
configs[index] = tunnelConfig configs[index] = tunnelConfig
} }
DispatchQueue.main.async { completion(.success(configs)) } DispatchQueue.main.async { completion(.success(configs)) }
@@ -29,7 +29,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId, tunnelProvider: self) let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId, tunnelProvider: self)
guard let tunnelProviderProtocol = protocolConfiguration as? NETunnelProviderProtocol, guard let tunnelProviderProtocol = protocolConfiguration as? NETunnelProviderProtocol,
let tunnelConfiguration = tunnelProviderProtocol.tunnelConfiguration else { let tunnelConfiguration = tunnelProviderProtocol.tunnelConfiguration(name: nil) else {
errorNotifier.notify(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid) errorNotifier.notify(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)
startTunnelCompletionHandler(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid) startTunnelCompletionHandler(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)
return return
@@ -132,7 +132,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
if err == -EADDRINUSE && listenPort != nil { if err == -EADDRINUSE && listenPort != nil {
let endpointString = packetTunnelSettingsGenerator.endpointUapiConfiguration(currentListenPort: 0) let endpointString = packetTunnelSettingsGenerator.endpointUapiConfiguration(currentListenPort: 0)
_ = endpointString.withGoString { return wgSetConfig(handle, $0) } _ = endpointString.withGoString { return wgSetConfig(handle, $0) }
} }
} }
} }