Nuke trailing spaces
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -7,17 +7,17 @@ import NetworkExtension
|
||||
|
||||
protocol LegacyModel: Decodable {
|
||||
associatedtype Model
|
||||
|
||||
|
||||
var migrated: Model { get }
|
||||
}
|
||||
|
||||
struct LegacyDNSServer: LegacyModel {
|
||||
let address: IPAddress
|
||||
|
||||
|
||||
var migrated: DNSServer {
|
||||
return DNSServer(address: address)
|
||||
}
|
||||
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
var data = try container.decode(Data.self)
|
||||
@@ -33,7 +33,7 @@ struct LegacyDNSServer: LegacyModel {
|
||||
}
|
||||
address = ipAddress
|
||||
}
|
||||
|
||||
|
||||
enum DecodingError: Error {
|
||||
case invalidData
|
||||
}
|
||||
@@ -48,11 +48,11 @@ extension Array where Element == LegacyDNSServer {
|
||||
struct LegacyEndpoint: LegacyModel {
|
||||
let host: Network.NWEndpoint.Host
|
||||
let port: Network.NWEndpoint.Port
|
||||
|
||||
|
||||
var migrated: Endpoint {
|
||||
return Endpoint(host: host, port: port)
|
||||
}
|
||||
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
let endpointString = try container.decode(String.self)
|
||||
@@ -81,7 +81,7 @@ struct LegacyEndpoint: LegacyModel {
|
||||
host = NWEndpoint.Host(hostString)
|
||||
port = endpointPort
|
||||
}
|
||||
|
||||
|
||||
enum DecodingError: Error {
|
||||
case invalidData
|
||||
}
|
||||
@@ -94,7 +94,7 @@ struct LegacyInterfaceConfiguration: LegacyModel {
|
||||
let listenPort: UInt16?
|
||||
let mtu: UInt16?
|
||||
let dns: [LegacyDNSServer]
|
||||
|
||||
|
||||
var migrated: InterfaceConfiguration {
|
||||
var interface = InterfaceConfiguration(name: name, privateKey: privateKey)
|
||||
interface.addresses = addresses.migrated
|
||||
@@ -108,11 +108,11 @@ struct LegacyInterfaceConfiguration: LegacyModel {
|
||||
struct LegacyIPAddressRange: LegacyModel {
|
||||
let address: IPAddress
|
||||
let networkPrefixLength: UInt8
|
||||
|
||||
|
||||
var migrated: IPAddressRange {
|
||||
return IPAddressRange(address: address, networkPrefixLength: networkPrefixLength)
|
||||
}
|
||||
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
var data = try container.decode(Data.self)
|
||||
@@ -127,7 +127,7 @@ struct LegacyIPAddressRange: LegacyModel {
|
||||
guard let ipAddress = ipAddressFromData else { throw DecodingError.invalidData }
|
||||
address = ipAddress
|
||||
}
|
||||
|
||||
|
||||
enum DecodingError: Error {
|
||||
case invalidData
|
||||
}
|
||||
@@ -145,7 +145,7 @@ struct LegacyPeerConfiguration: LegacyModel {
|
||||
let allowedIPs: [LegacyIPAddressRange]
|
||||
let endpoint: LegacyEndpoint?
|
||||
let persistentKeepAlive: UInt16?
|
||||
|
||||
|
||||
var migrated: PeerConfiguration {
|
||||
var configuration = PeerConfiguration(publicKey: publicKey)
|
||||
configuration.preSharedKey = preSharedKey
|
||||
@@ -165,14 +165,14 @@ extension Array where Element == LegacyPeerConfiguration {
|
||||
final class LegacyTunnelConfiguration: LegacyModel {
|
||||
let interface: LegacyInterfaceConfiguration
|
||||
let peers: [LegacyPeerConfiguration]
|
||||
|
||||
|
||||
var migrated: TunnelConfiguration {
|
||||
return TunnelConfiguration(interface: interface.migrated, peers: peers.migrated)
|
||||
}
|
||||
}
|
||||
|
||||
extension NETunnelProviderProtocol {
|
||||
|
||||
|
||||
@discardableResult
|
||||
func migrateConfigurationIfNeeded() -> Bool {
|
||||
guard let configurationVersion = providerConfiguration?["tunnelConfigurationVersion"] as? Int else { return false }
|
||||
@@ -183,11 +183,11 @@ extension NETunnelProviderProtocol {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
private func migrateFromConfigurationV1() {
|
||||
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 }
|
||||
providerConfiguration = [Keys.wgQuickConfig.rawValue: configuration.migrated.asWgQuickConfig()]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ public class Logger {
|
||||
enum LoggerError: Error {
|
||||
case openFailure
|
||||
}
|
||||
|
||||
|
||||
static var global: Logger?
|
||||
|
||||
var log: OpaquePointer
|
||||
|
||||
@@ -6,7 +6,7 @@ import Network
|
||||
|
||||
struct DNSServer {
|
||||
let address: IPAddress
|
||||
|
||||
|
||||
init(address: IPAddress) {
|
||||
self.address = address
|
||||
}
|
||||
@@ -16,7 +16,7 @@ extension DNSServer {
|
||||
var stringRepresentation: String {
|
||||
return "\(address)"
|
||||
}
|
||||
|
||||
|
||||
init?(from addressString: String) {
|
||||
if let addr = IPv4Address(addressString) {
|
||||
address = addr
|
||||
|
||||
@@ -7,7 +7,7 @@ import Network
|
||||
struct Endpoint {
|
||||
let host: NWEndpoint.Host
|
||||
let port: NWEndpoint.Port
|
||||
|
||||
|
||||
init(host: NWEndpoint.Host, port: NWEndpoint.Port) {
|
||||
self.host = host
|
||||
self.port = port
|
||||
@@ -25,7 +25,7 @@ extension Endpoint {
|
||||
return "[\(address)]:\(port)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init?(from string: String) {
|
||||
// Separation of host and port is based on 'parse_endpoint' function in
|
||||
// https://git.zx2c4.com/WireGuard/tree/src/tools/config.c
|
||||
|
||||
@@ -7,7 +7,7 @@ import Network
|
||||
struct IPAddressRange {
|
||||
let address: IPAddress
|
||||
var networkPrefixLength: UInt8
|
||||
|
||||
|
||||
init(address: IPAddress, networkPrefixLength: UInt8) {
|
||||
self.address = address
|
||||
self.networkPrefixLength = networkPrefixLength
|
||||
@@ -18,13 +18,13 @@ extension IPAddressRange {
|
||||
var stringRepresentation: String {
|
||||
return "\(address)/\(networkPrefixLength)"
|
||||
}
|
||||
|
||||
|
||||
init?(from string: String) {
|
||||
guard let parsed = IPAddressRange.parseAddressString(string) else { return nil }
|
||||
address = parsed.0
|
||||
networkPrefixLength = parsed.1
|
||||
}
|
||||
|
||||
|
||||
private static func parseAddressString(_ string: String) -> (IPAddress, UInt8)? {
|
||||
let endOfIPAddress = string.lastIndex(of: "/") ?? string.endIndex
|
||||
let addressString = String(string[string.startIndex ..< endOfIPAddress])
|
||||
@@ -36,7 +36,7 @@ extension IPAddressRange {
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
let maxNetworkPrefixLength: UInt8 = address is IPv4Address ? 32 : 128
|
||||
var networkPrefixLength: UInt8
|
||||
if endOfIPAddress < string.endIndex { // "/" was located
|
||||
@@ -48,7 +48,7 @@ extension IPAddressRange {
|
||||
} else {
|
||||
networkPrefixLength = maxNetworkPrefixLength
|
||||
}
|
||||
|
||||
|
||||
return (address, networkPrefixLength)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ struct InterfaceConfiguration {
|
||||
var listenPort: UInt16?
|
||||
var mtu: UInt16?
|
||||
var dns = [DNSServer]()
|
||||
|
||||
|
||||
init(name: String?, privateKey: Data) {
|
||||
self.name = name
|
||||
self.privateKey = privateKey
|
||||
|
||||
@@ -17,7 +17,7 @@ struct PeerConfiguration {
|
||||
var allowedIPs = [IPAddressRange]()
|
||||
var endpoint: Endpoint?
|
||||
var persistentKeepAlive: UInt16?
|
||||
|
||||
|
||||
init(publicKey: Data) {
|
||||
self.publicKey = publicKey
|
||||
if publicKey.count != TunnelConfiguration.keyLength {
|
||||
|
||||
@@ -6,18 +6,18 @@ import NetworkExtension
|
||||
private var tunnelNameKey: Void?
|
||||
|
||||
extension NETunnelProviderProtocol {
|
||||
|
||||
|
||||
enum Keys: String {
|
||||
case wgQuickConfig = "WgQuickConfig"
|
||||
}
|
||||
|
||||
|
||||
convenience init?(tunnelConfiguration: TunnelConfiguration) {
|
||||
self.init()
|
||||
|
||||
|
||||
let appId = Bundle.main.bundleIdentifier!
|
||||
providerBundleIdentifier = "\(appId).network-extension"
|
||||
providerConfiguration = [Keys.wgQuickConfig.rawValue: tunnelConfiguration.asWgQuickConfig()]
|
||||
|
||||
|
||||
let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
|
||||
if endpoints.count == 1 {
|
||||
serverAddress = endpoints[0].stringRepresentation
|
||||
@@ -26,14 +26,14 @@ extension NETunnelProviderProtocol {
|
||||
} else {
|
||||
serverAddress = "Multiple endpoints"
|
||||
}
|
||||
|
||||
|
||||
username = tunnelConfiguration.interface.name
|
||||
}
|
||||
|
||||
|
||||
func tunnelConfiguration(name: String?) -> TunnelConfiguration? {
|
||||
migrateConfigurationIfNeeded()
|
||||
guard let serializedConfig = providerConfiguration?[Keys.wgQuickConfig.rawValue] as? String else { return nil }
|
||||
return try? TunnelConfiguration(serializedConfig, name: name)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import Foundation
|
||||
|
||||
extension String {
|
||||
|
||||
|
||||
func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
|
||||
return split(separator: separator)
|
||||
.map {
|
||||
@@ -15,11 +15,11 @@ extension String {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension Optional where Wrapped == String {
|
||||
|
||||
|
||||
func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
|
||||
switch self {
|
||||
case .none:
|
||||
@@ -28,5 +28,5 @@ extension Optional where Wrapped == String {
|
||||
return wrapped.splitToArray(separator: separator, trimmingCharacters: trimmingCharacters)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import Foundation
|
||||
|
||||
extension TunnelConfiguration {
|
||||
|
||||
|
||||
enum ParserState {
|
||||
case inInterfaceSection
|
||||
case inPeerSection
|
||||
case notInASection
|
||||
}
|
||||
|
||||
|
||||
enum ParseError: Error {
|
||||
case invalidLine(_ line: String.SubSequence)
|
||||
case noInterface
|
||||
@@ -19,17 +19,17 @@ extension TunnelConfiguration {
|
||||
case multiplePeersWithSamePublicKey
|
||||
case invalidPeer
|
||||
}
|
||||
|
||||
|
||||
//swiftlint:disable:next cyclomatic_complexity function_body_length
|
||||
convenience init(_ wgQuickConfig: String, name: String?) throws {
|
||||
var interfaceConfiguration: InterfaceConfiguration?
|
||||
var peerConfigurations = [PeerConfiguration]()
|
||||
|
||||
|
||||
let lines = wgQuickConfig.split(separator: "\n")
|
||||
|
||||
|
||||
var parserState = ParserState.notInASection
|
||||
var attributes = [String: String]()
|
||||
|
||||
|
||||
for (lineIndex, line) in lines.enumerated() {
|
||||
var trimmedLine: String
|
||||
if let commentRange = line.range(of: "#") {
|
||||
@@ -37,12 +37,12 @@ extension TunnelConfiguration {
|
||||
} else {
|
||||
trimmedLine = String(line)
|
||||
}
|
||||
|
||||
|
||||
trimmedLine = trimmedLine.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
|
||||
guard !trimmedLine.isEmpty else { continue }
|
||||
let lowercasedLine = line.lowercased()
|
||||
|
||||
|
||||
if let equalsIndex = line.firstIndex(of: "=") {
|
||||
// Line contains an attribute
|
||||
let key = line[..<equalsIndex].trimmingCharacters(in: .whitespaces).lowercased()
|
||||
@@ -56,9 +56,9 @@ extension TunnelConfiguration {
|
||||
} else if lowercasedLine != "[interface]" && lowercasedLine != "[peer]" {
|
||||
throw ParseError.invalidLine(line)
|
||||
}
|
||||
|
||||
|
||||
let isLastLine = lineIndex == lines.count - 1
|
||||
|
||||
|
||||
if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" {
|
||||
// Previous section has ended; process the attributes collected so far
|
||||
if parserState == .inInterfaceSection {
|
||||
@@ -70,7 +70,7 @@ extension TunnelConfiguration {
|
||||
peerConfigurations.append(peer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if lowercasedLine == "[interface]" {
|
||||
parserState = .inInterfaceSection
|
||||
attributes.removeAll()
|
||||
@@ -79,20 +79,20 @@ extension TunnelConfiguration {
|
||||
attributes.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let peerPublicKeysArray = peerConfigurations.map { $0.publicKey }
|
||||
let peerPublicKeysSet = Set<Data>(peerPublicKeysArray)
|
||||
if peerPublicKeysArray.count != peerPublicKeysSet.count {
|
||||
throw ParseError.multiplePeersWithSamePublicKey
|
||||
}
|
||||
|
||||
|
||||
if let interfaceConfiguration = interfaceConfiguration {
|
||||
self.init(interface: interfaceConfiguration, peers: peerConfigurations)
|
||||
} else {
|
||||
throw ParseError.noInterface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func asWgQuickConfig() -> String {
|
||||
var output = "[Interface]\n"
|
||||
output.append("PrivateKey = \(interface.privateKey.base64EncodedString())\n")
|
||||
@@ -110,7 +110,7 @@ extension TunnelConfiguration {
|
||||
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")
|
||||
@@ -128,10 +128,10 @@ extension TunnelConfiguration {
|
||||
output.append("PersistentKeepalive = \(persistentKeepAlive)\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
|
||||
//swiftlint:disable:next cyclomatic_complexity
|
||||
private static func collate(interfaceAttributes attributes: [String: String], name: String?) -> InterfaceConfiguration? {
|
||||
// required wg fields
|
||||
@@ -166,7 +166,7 @@ extension TunnelConfiguration {
|
||||
}
|
||||
return interface
|
||||
}
|
||||
|
||||
|
||||
//swiftlint:disable:next cyclomatic_complexity
|
||||
private static func collate(peerAttributes attributes: [String: String]) -> PeerConfiguration? {
|
||||
// required wg fields
|
||||
@@ -196,5 +196,5 @@ extension TunnelConfiguration {
|
||||
}
|
||||
return peer
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user