diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81120b4..23ee1bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## Unreleased
+
+### Added
+
+- WireGuard support. [#236](https://github.com/passepartoutvpn/tunnelkit/pull/236)
+
## 4.0.3 (2021-11-27)
### Fixed
diff --git a/Demo/Demo/Configuration.swift b/Demo/Demo/Configuration.swift
index 76acc76..261fea6 100644
--- a/Demo/Demo/Configuration.swift
+++ b/Demo/Demo/Configuration.swift
@@ -26,9 +26,11 @@
import Foundation
import TunnelKitCore
import TunnelKitOpenVPN
+import TunnelKitWireGuard
-struct Configuration {
- static let ca = OpenVPN.CryptoContainer(pem: """
+extension OpenVPN {
+ struct DemoConfiguration {
+ static let ca = OpenVPN.CryptoContainer(pem: """
-----BEGIN CERTIFICATE-----
MIIG6zCCBNOgAwIBAgIJAJhm2PWFkE8NMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzAR
@@ -70,7 +72,7 @@ HiT8esMeX+/orMetzuTPgZInMhznvVdNdfwAfibwlXOKvm154UgDVgnKV405oNM=
-----END CERTIFICATE-----
""")
- static let clientCertificate = OpenVPN.CryptoContainer(pem: """
+ static let clientCertificate = OpenVPN.CryptoContainer(pem: """
-----BEGIN CERTIFICATE-----
MIIHPTCCBSWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBqTELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpH
@@ -114,7 +116,7 @@ kiJ6Ts2iqIvR7T7Eme2vBYH/UJ1DXrdCJx6IDGxxgoXk
-----END CERTIFICATE-----
""")
- static let clientKey = OpenVPN.CryptoContainer(pem: """
+ static let clientKey = OpenVPN.CryptoContainer(pem: """
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDvgpUJoqgvHmbF
2y7Uvt1BfglAXWmzzhaSjr4ZqYLMQncpcwC1iuVgDseGp/rl4C/C64RebIx0hLU1
@@ -169,21 +171,47 @@ M69t86apMrAxkUxVJAWLRBd9fbYyzJgTW61tFqXWTZpiz6bhuWApSEzaHcL3/f5l
-----END PRIVATE KEY-----
""")
- static func make(hostname: String, port: UInt16, socketType: SocketType) -> OpenVPNProvider.Configuration {
- var sessionBuilder = OpenVPN.ConfigurationBuilder()
- sessionBuilder.ca = ca
- sessionBuilder.cipher = .aes128cbc
- sessionBuilder.digest = .sha1
- sessionBuilder.compressionFraming = .compLZO
- sessionBuilder.renegotiatesAfter = nil
- sessionBuilder.hostname = hostname
- sessionBuilder.endpointProtocols = [EndpointProtocol(socketType, port)]
- sessionBuilder.clientCertificate = clientCertificate
- sessionBuilder.clientKey = clientKey
- sessionBuilder.mtu = 1350
- var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
- builder.shouldDebug = true
- builder.masksPrivateData = false
- return builder.build()
+ static func make(hostname: String, port: UInt16, socketType: SocketType) -> OpenVPNProvider.Configuration {
+ var sessionBuilder = OpenVPN.ConfigurationBuilder()
+ sessionBuilder.ca = ca
+ sessionBuilder.cipher = .aes128cbc
+ sessionBuilder.digest = .sha1
+ sessionBuilder.compressionFraming = .compLZO
+ sessionBuilder.renegotiatesAfter = nil
+ sessionBuilder.hostname = hostname
+ sessionBuilder.endpointProtocols = [EndpointProtocol(socketType, port)]
+ sessionBuilder.clientCertificate = clientCertificate
+ sessionBuilder.clientKey = clientKey
+ sessionBuilder.mtu = 1350
+ var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
+ builder.shouldDebug = true
+ builder.masksPrivateData = false
+ return builder.build()
+ }
+ }
+}
+
+extension WireGuard {
+ struct DemoConfiguration {
+ static func make(
+ clientPrivateKey: String,
+ clientAddress: String,
+ serverPublicKey: String,
+ serverAddress: String,
+ serverPort: String
+ ) -> WireGuardProvider.Configuration? {
+ var builder = WireGuard.ConfigurationBuilder()
+ builder.privateKey = clientPrivateKey
+ builder.addresses = [clientAddress]
+ builder.peerPublicKey = serverPublicKey
+ builder.peerAddress = serverAddress
+ builder.peerPort = UInt16(serverPort)
+ builder.allowedIPs = ["0.0.0.0/0"]
+ builder.dns = ["1.1.1.1", "1.0.0.1"]
+ guard let cfg = builder.build() else {
+ return nil
+ }
+ return WireGuardProvider.Configuration(innerConfiguration: cfg)
+ }
}
}
diff --git a/Demo/Demo/DemoTunnel.plist b/Demo/Demo/DemoTunnel.plist
index e36f178..c146255 100644
--- a/Demo/Demo/DemoTunnel.plist
+++ b/Demo/Demo/DemoTunnel.plist
@@ -5,7 +5,7 @@
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
- BasicTunnelExtension
+ TunnelKitDemoTunnel
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
diff --git a/Demo/Demo/PacketTunnelProvider.swift b/Demo/Demo/OpenVPNPacketTunnelProvider.swift
similarity index 96%
rename from Demo/Demo/PacketTunnelProvider.swift
rename to Demo/Demo/OpenVPNPacketTunnelProvider.swift
index b832279..eec46e5 100644
--- a/Demo/Demo/PacketTunnelProvider.swift
+++ b/Demo/Demo/OpenVPNPacketTunnelProvider.swift
@@ -1,5 +1,5 @@
//
-// PacketTunnelProvider.swift
+// OpenVPNPacketTunnelProvider.swift
// Demo
//
// Created by Davide De Rosa on 9/15/17.
diff --git a/Demo/Demo/WireGuardPacketTunnelProvider.swift b/Demo/Demo/WireGuardPacketTunnelProvider.swift
new file mode 100644
index 0000000..770e784
--- /dev/null
+++ b/Demo/Demo/WireGuardPacketTunnelProvider.swift
@@ -0,0 +1,29 @@
+//
+// WireGuardPacketTunnelProvider.swift
+// Demo
+//
+// Created by Davide De Rosa on 11/22/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/keeshux
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import TunnelKitWireGuardAppExtension
+
+class PacketTunnelProvider: WireGuardTunnelProvider {
+}
diff --git a/Demo/Demo/iOS/Base.lproj/Main.storyboard b/Demo/Demo/iOS/Base.lproj/Main.storyboard
index 4fec762..d5b2052 100644
--- a/Demo/Demo/iOS/Base.lproj/Main.storyboard
+++ b/Demo/Demo/iOS/Base.lproj/Main.storyboard
@@ -1,16 +1,196 @@
-
+
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -20,35 +200,35 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
@@ -114,6 +294,7 @@
+
@@ -130,4 +311,12 @@
+
+
+
+
+
+
+
+
diff --git a/Demo/Demo/iOS/ViewController.swift b/Demo/Demo/iOS/OpenVPNViewController.swift
similarity index 93%
rename from Demo/Demo/iOS/ViewController.swift
rename to Demo/Demo/iOS/OpenVPNViewController.swift
index 56a29cb..2813ae7 100644
--- a/Demo/Demo/iOS/ViewController.swift
+++ b/Demo/Demo/iOS/OpenVPNViewController.swift
@@ -1,5 +1,5 @@
//
-// ViewController.swift
+// OpenVPNViewController.swift
// Demo
//
// Created by Davide De Rosa on 2/11/17.
@@ -25,15 +25,14 @@
import UIKit
import TunnelKitCore
-import TunnelKitAppExtension
import TunnelKitManager
import TunnelKitOpenVPN
private let appGroup = "group.com.algoritmico.TunnelKit.Demo"
-private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.Tunnel"
+private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel"
-class ViewController: UIViewController, URLSessionDataDelegate {
+class OpenVPNViewController: UIViewController {
@IBOutlet var textUsername: UITextField!
@IBOutlet var textPassword: UITextField!
@@ -97,14 +96,14 @@ class ViewController: UIViewController, URLSessionDataDelegate {
let socketType: SocketType = switchTCP.isOn ? .tcp : .udp
let credentials = OpenVPN.Credentials(textUsername.text!, textPassword.text!)
- let cfg = Configuration.make(hostname: hostname, port: port, socketType: socketType)
+ let cfg = OpenVPN.DemoConfiguration.make(hostname: hostname, port: port, socketType: socketType)
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier,
credentials: credentials
)
- let neCfg = NetworkExtensionVPNConfiguration(title: "BasicTunnel", protocolConfiguration: proto, onDemandRules: [])
+ let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.OpenVPN", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")
diff --git a/Demo/Demo/iOS/WireGuardViewController.swift b/Demo/Demo/iOS/WireGuardViewController.swift
new file mode 100644
index 0000000..d471717
--- /dev/null
+++ b/Demo/Demo/iOS/WireGuardViewController.swift
@@ -0,0 +1,134 @@
+//
+// WireGuardViewController.swift
+// Demo
+//
+// Created by Davide De Rosa on 11/22/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/keeshux
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import UIKit
+import TunnelKitManager
+import TunnelKitWireGuard
+import NetworkExtension
+
+private let appGroup = "group.com.algoritmico.TunnelKit.Demo"
+
+private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel"
+
+class WireGuardViewController: UIViewController {
+ @IBOutlet var textClientPrivateKey: UITextField!
+
+ @IBOutlet var textAddress: UITextField!
+
+ @IBOutlet var textServerPublicKey: UITextField!
+
+ @IBOutlet var textServerAddress: UITextField!
+
+ @IBOutlet var textServerPort: UITextField!
+
+ @IBOutlet var buttonConnection: UIButton!
+
+ private let vpn = WireGuardProvider(bundleIdentifier: tunnelIdentifier)
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ textClientPrivateKey.placeholder = "client private key"
+ textAddress.placeholder = "client address"
+ textServerPublicKey.placeholder = "server public key"
+ textServerAddress.placeholder = "server address"
+ textServerPort.placeholder = "server port"
+
+ textAddress.text = "192.168.30.2/32"
+
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(VPNStatusDidChange(notification:)),
+ name: VPN.didChangeStatus,
+ object: nil
+ )
+
+ vpn.prepare(completionHandler: nil)
+ }
+
+ @IBAction func connectionClicked(_ sender: Any) {
+ switch vpn.status {
+ case .disconnected:
+ connect()
+
+ case .connected, .connecting, .disconnecting:
+ disconnect()
+ }
+ }
+
+ func connect() {
+ let clientPrivateKey = textClientPrivateKey.text!
+ let clientAddress = textAddress.text!
+ let serverPublicKey = textServerPublicKey.text!
+ let serverAddress = textServerAddress.text!
+ let serverPort = textServerPort.text!
+
+ guard let cfg = WireGuard.DemoConfiguration.make(
+ clientPrivateKey: clientPrivateKey,
+ clientAddress: clientAddress,
+ serverPublicKey: serverPublicKey,
+ serverAddress: serverAddress,
+ serverPort: serverPort
+ ) else {
+ print("Configuration incomplete")
+ return
+ }
+ let proto = try! cfg.generatedTunnelProtocol(
+ withBundleIdentifier: tunnelIdentifier,
+ appGroup: appGroup,
+ context: tunnelIdentifier
+ )
+
+ let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.WireGuard", protocolConfiguration: proto, onDemandRules: [])
+ vpn.reconnect(configuration: neCfg) { (error) in
+ if let error = error {
+ print("configure error: \(error)")
+ return
+ }
+ }
+ }
+
+ func disconnect() {
+ vpn.disconnect(completionHandler: nil)
+ }
+
+ func updateButton() {
+ switch vpn.status {
+ case .connected, .connecting:
+ buttonConnection.setTitle("Disconnect", for: .normal)
+
+ case .disconnected:
+ buttonConnection.setTitle("Connect", for: .normal)
+
+ case .disconnecting:
+ buttonConnection.setTitle("Disconnecting", for: .normal)
+ }
+ }
+
+ @objc private func VPNStatusDidChange(notification: NSNotification) {
+ print("VPNStatusDidChange: \(vpn.status)")
+ updateButton()
+ }
+}
diff --git a/Demo/Demo/macOS/Base.lproj/Main.storyboard b/Demo/Demo/macOS/Base.lproj/Main.storyboard
index 1822950..6d45cc8 100644
--- a/Demo/Demo/macOS/Base.lproj/Main.storyboard
+++ b/Demo/Demo/macOS/Base.lproj/Main.storyboard
@@ -1,8 +1,8 @@
-
+
-
+
@@ -12,11 +12,11 @@
-
+
-
+
-
+
@@ -695,17 +695,150 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -798,7 +931,7 @@
-
+
diff --git a/Demo/Demo/macOS/DemoTunnel.entitlements b/Demo/Demo/macOS/DemoTunnel.entitlements
index 7336b16..f2940f3 100644
--- a/Demo/Demo/macOS/DemoTunnel.entitlements
+++ b/Demo/Demo/macOS/DemoTunnel.entitlements
@@ -14,6 +14,8 @@
com.apple.security.network.client
+ com.apple.security.network.server
+
keychain-access-groups
$(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo
diff --git a/Demo/Demo/macOS/ViewController.swift b/Demo/Demo/macOS/OpenVPNViewController.swift
similarity index 92%
rename from Demo/Demo/macOS/ViewController.swift
rename to Demo/Demo/macOS/OpenVPNViewController.swift
index 859d6b7..72d6322 100644
--- a/Demo/Demo/macOS/ViewController.swift
+++ b/Demo/Demo/macOS/OpenVPNViewController.swift
@@ -1,5 +1,5 @@
//
-// ViewController.swift
+// OpenVPNViewController.swift
// Demo
//
// Created by Davide De Rosa on 10/15/17.
@@ -25,15 +25,14 @@
import Cocoa
import TunnelKitCore
-import TunnelKitAppExtension
import TunnelKitManager
import TunnelKitOpenVPN
private let appGroup = "DTDYD63ZX9.group.com.algoritmico.TunnelKit.Demo"
-private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.Tunnel"
+private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel"
-class ViewController: NSViewController {
+class OpenVPNViewController: NSViewController {
@IBOutlet var textUsername: NSTextField!
@IBOutlet var textPassword: NSTextField!
@@ -88,14 +87,14 @@ class ViewController: NSViewController {
let port = UInt16(textPort.stringValue)!
let credentials = OpenVPN.Credentials(textUsername.stringValue, textPassword.stringValue)
- let cfg = Configuration.make(hostname: hostname, port: port, socketType: .udp)
+ let cfg = OpenVPN.DemoConfiguration.make(hostname: hostname, port: port, socketType: .udp)
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier,
credentials: credentials
)
- let neCfg = NetworkExtensionVPNConfiguration(title: "BasicTunnel", protocolConfiguration: proto, onDemandRules: [])
+ let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.OpenVPN", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")
diff --git a/Demo/Demo/macOS/WireGuardViewController.swift b/Demo/Demo/macOS/WireGuardViewController.swift
new file mode 100644
index 0000000..9564793
--- /dev/null
+++ b/Demo/Demo/macOS/WireGuardViewController.swift
@@ -0,0 +1,134 @@
+//
+// WireGuardViewController.swift
+// Demo
+//
+// Created by Davide De Rosa on 11/22/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/keeshux
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Cocoa
+import TunnelKitManager
+import TunnelKitWireGuard
+import NetworkExtension
+
+private let appGroup = "DTDYD63ZX9.group.com.algoritmico.TunnelKit.Demo"
+
+private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel"
+
+class WireGuardViewController: NSViewController {
+ @IBOutlet var textClientPrivateKey: NSTextField!
+
+ @IBOutlet var textAddress: NSTextField!
+
+ @IBOutlet var textServerPublicKey: NSTextField!
+
+ @IBOutlet var textServerAddress: NSTextField!
+
+ @IBOutlet var textServerPort: NSTextField!
+
+ @IBOutlet var buttonConnection: NSButton!
+
+ private let vpn = WireGuardProvider(bundleIdentifier: tunnelIdentifier)
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ textClientPrivateKey.placeholderString = "client private key"
+ textAddress.placeholderString = "client address"
+ textServerPublicKey.placeholderString = "server public key"
+ textServerAddress.placeholderString = "server address"
+ textServerPort.placeholderString = "server port"
+
+ textAddress.stringValue = "192.168.30.2/32"
+
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(VPNStatusDidChange(notification:)),
+ name: VPN.didChangeStatus,
+ object: nil
+ )
+
+ vpn.prepare(completionHandler: nil)
+ }
+
+ @IBAction func connectionClicked(_ sender: Any) {
+ switch vpn.status {
+ case .disconnected:
+ connect()
+
+ case .connected, .connecting, .disconnecting:
+ disconnect()
+ }
+ }
+
+ func connect() {
+ let clientPrivateKey = textClientPrivateKey.stringValue
+ let clientAddress = textAddress.stringValue
+ let serverPublicKey = textServerPublicKey.stringValue
+ let serverAddress = textServerAddress.stringValue
+ let serverPort = textServerPort.stringValue
+
+ guard let cfg = WireGuard.DemoConfiguration.make(
+ clientPrivateKey: clientPrivateKey,
+ clientAddress: clientAddress,
+ serverPublicKey: serverPublicKey,
+ serverAddress: serverAddress,
+ serverPort: serverPort
+ ) else {
+ print("Configuration incomplete")
+ return
+ }
+ let proto = try! cfg.generatedTunnelProtocol(
+ withBundleIdentifier: tunnelIdentifier,
+ appGroup: appGroup,
+ context: tunnelIdentifier
+ )
+
+ let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.WireGuard", protocolConfiguration: proto, onDemandRules: [])
+ vpn.reconnect(configuration: neCfg) { (error) in
+ if let error = error {
+ print("configure error: \(error)")
+ return
+ }
+ }
+ }
+
+ func disconnect() {
+ vpn.disconnect(completionHandler: nil)
+ }
+
+ func updateButton() {
+ switch vpn.status {
+ case .connected, .connecting:
+ buttonConnection.title = "Disconnect"
+
+ case .disconnected:
+ buttonConnection.title = "Connect"
+
+ case .disconnecting:
+ buttonConnection.title = "Disconnecting"
+ }
+ }
+
+ @objc private func VPNStatusDidChange(notification: NSNotification) {
+ print("VPNStatusDidChange: \(vpn.status)")
+ updateButton()
+ }
+}
diff --git a/Demo/TunnelKit.xcodeproj/project.pbxproj b/Demo/TunnelKit.xcodeproj/project.pbxproj
index a51f439..64766fc 100644
--- a/Demo/TunnelKit.xcodeproj/project.pbxproj
+++ b/Demo/TunnelKit.xcodeproj/project.pbxproj
@@ -8,22 +8,22 @@
/* Begin PBXBuildFile section */
0E05418725A2334500EFC5FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414B25A231D500EFC5FF /* AppDelegate.swift */; };
- 0E05418825A2334500EFC5FF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414425A231D500EFC5FF /* ViewController.swift */; };
+ 0E05418825A2334500EFC5FF /* OpenVPNViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */; };
0E05418925A2334500EFC5FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414525A231D500EFC5FF /* Assets.xcassets */; };
0E05418A25A2334900EFC5FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414825A231D500EFC5FF /* Main.storyboard */; };
0E05418B25A2334900EFC5FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414625A231D500EFC5FF /* LaunchScreen.storyboard */; };
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
- 0E0541A925A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
- 0E0541D125A2354500EFC5FF /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */; };
+ 0E0541A925A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 0E0541D125A2354500EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */; };
0E0541D825A2355000EFC5FF /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413425A231D500EFC5FF /* Configuration.swift */; };
0E05425825A2392E00EFC5FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414125A231D500EFC5FF /* AppDelegate.swift */; };
- 0E05425925A2392E00EFC5FF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413C25A231D500EFC5FF /* ViewController.swift */; };
+ 0E05425925A2392E00EFC5FF /* OpenVPNViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */; };
0E05426125A2393300EFC5FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E05413D25A231D500EFC5FF /* Assets.xcassets */; };
0E05426925A2393B00EFC5FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05413E25A231D500EFC5FF /* Main.storyboard */; };
0E05427825A239C600EFC5FF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
- 0E05428025A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 0E05428025A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E0542B925A23A8100EFC5FF /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413425A231D500EFC5FF /* Configuration.swift */; };
- 0E0542C225A23A8400EFC5FF /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */; };
+ 0E0542C225A23A8400EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */; };
0E1108AC1F77B9F900A92462 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AB1F77B9F900A92462 /* AppDelegate.swift */; };
0E1108AE1F77B9F900A92462 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AD1F77B9F900A92462 /* ViewController.swift */; };
0E1108B11F77B9F900A92462 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108AF1F77B9F900A92462 /* Main.storyboard */; };
@@ -31,6 +31,18 @@
0E1108B61F77B9F900A92462 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B41F77B9F900A92462 /* LaunchScreen.storyboard */; };
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */; };
0E80FA5327396F66000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */; };
+ 0E81EB4C274BACF200E5F2D3 /* WireGuardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */; };
+ 0E81EB4F274BAE0A00E5F2D3 /* WireGuardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */; };
+ 0E81EB51274BB02100E5F2D3 /* TunnelKitWireGuard in Frameworks */ = {isa = PBXBuildFile; productRef = 0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */; };
+ 0E81EB53274BB02600E5F2D3 /* TunnelKitWireGuard in Frameworks */ = {isa = PBXBuildFile; productRef = 0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */; };
+ 0E833A85274BC39C008EA397 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
+ 0E833A96274BC3B1008EA397 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
+ 0E833AA3274BC480008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */; };
+ 0E833AA5274BC484008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */; };
+ 0E833AAA274BC5BA008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 0E833AAB274BC5C2008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 0E833AAD274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */; };
+ 0E833AAE274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */; };
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */; };
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */; };
/* End PBXBuildFile section */
@@ -50,6 +62,34 @@
remoteGlobalIDString = 0E05427625A239C600EFC5FF;
remoteInfo = Tunnel;
};
+ 0E833A8B274BC39C008EA397 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 0E833A83274BC39C008EA397;
+ remoteInfo = "TunnelKitDemoWireGuardTunnel-iOS";
+ };
+ 0E833A9C274BC3B1008EA397 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 0E833A94274BC3B1008EA397;
+ remoteInfo = "TunnelKitDemoWireGuardTunnel-macOS";
+ };
+ 0E833AA6274BC496008EA397 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 0E81EB54274BB0D000E5F2D3;
+ remoteInfo = "TunnelKitDemoWireGuardKitGo-macOS";
+ };
+ 0E833AA8274BC49B008EA397 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 0EDD211D274BB4CF006833D1;
+ remoteInfo = "TunnelKitDemoWireGuardKitGo-iOS";
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -59,7 +99,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
- 0E0541A925A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex in Embed App Extensions */,
+ 0E833AAB274BC5C2008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex in Embed App Extensions */,
+ 0E0541A925A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
@@ -70,7 +111,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
- 0E05428025A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex in Embed App Extensions */,
+ 0E833AAA274BC5BA008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex in Embed App Extensions */,
+ 0E05428025A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
@@ -111,15 +153,15 @@
0E05413025A231D500EFC5FF /* DemoTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DemoTunnel.entitlements; sourceTree = ""; };
0E05413225A231D500EFC5FF /* DemoTunnel.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = DemoTunnel.plist; sourceTree = ""; };
0E05413425A231D500EFC5FF /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; };
- 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; };
+ 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNPacketTunnelProvider.swift; sourceTree = ""; };
0E05413925A231D500EFC5FF /* DemoTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DemoTunnel.entitlements; sourceTree = ""; };
- 0E05413C25A231D500EFC5FF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ 0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNViewController.swift; sourceTree = ""; };
0E05413D25A231D500EFC5FF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
0E05413F25A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
0E05414025A231D500EFC5FF /* Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Demo.entitlements; sourceTree = ""; };
0E05414125A231D500EFC5FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
0E05414225A231D500EFC5FF /* Demo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Demo.plist; sourceTree = ""; };
- 0E05414425A231D500EFC5FF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ 0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNViewController.swift; sourceTree = ""; };
0E05414525A231D500EFC5FF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
0E05414725A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
0E05414925A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
@@ -127,10 +169,10 @@
0E05414B25A231D500EFC5FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
0E05414C25A231D500EFC5FF /* Demo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Demo.plist; sourceTree = ""; };
0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TunnelKitDemo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoOpenVPNTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E0541A025A2343500EFC5FF /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TunnelKitDemo-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoOpenVPNTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E1108A91F77B9F900A92462 /* TunnelKitHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TunnelKitHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
0E1108AB1F77B9F900A92462 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
0E1108AD1F77B9F900A92462 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
@@ -141,6 +183,11 @@
0E26B05627272767008FB1E7 /* tunnelkit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = tunnelkit; path = ..; sourceTree = ""; };
0E411B9F2271FA3300E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; };
0E411BA12271FA3C00E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
+ 0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardViewController.swift; sourceTree = ""; };
+ 0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardViewController.swift; sourceTree = ""; };
+ 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoWireGuardTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoWireGuardTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardPacketTunnelProvider.swift; sourceTree = ""; };
0E85A25B202CCA3D0059E9F9 /* Host.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Host.entitlements; sourceTree = ""; };
44612F27B9EF890AF8B926DB /* Pods_ios_TunnelKit_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_TunnelKit_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
488FA71CA2DC38D2FDF7D1D8 /* Pods_ios_TunnelKitDemoTunnel_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_TunnelKitDemoTunnel_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -158,6 +205,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0E81EB53274BB02600E5F2D3 /* TunnelKitWireGuard in Frameworks */,
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -166,8 +214,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */,
+ 0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -175,6 +223,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0E81EB51274BB02100E5F2D3 /* TunnelKitWireGuard in Frameworks */,
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -195,6 +244,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 0E833A81274BC39C008EA397 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0E833AA3274BC480008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */,
+ 0E833A85274BC39C008EA397 /* NetworkExtension.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0E833A92274BC3B1008EA397 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0E833AA5274BC484008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */,
+ 0E833A96274BC3B1008EA397 /* NetworkExtension.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -205,7 +272,8 @@
0E05413B25A231D500EFC5FF /* macOS */,
0E05413225A231D500EFC5FF /* DemoTunnel.plist */,
0E05413425A231D500EFC5FF /* Configuration.swift */,
- 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */,
+ 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */,
+ 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */,
);
path = Demo;
sourceTree = "";
@@ -217,7 +285,8 @@
0E05413025A231D500EFC5FF /* DemoTunnel.entitlements */,
0E05414225A231D500EFC5FF /* Demo.plist */,
0E05414125A231D500EFC5FF /* AppDelegate.swift */,
- 0E05413C25A231D500EFC5FF /* ViewController.swift */,
+ 0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */,
+ 0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */,
0E05413D25A231D500EFC5FF /* Assets.xcassets */,
0E05413E25A231D500EFC5FF /* Main.storyboard */,
);
@@ -231,7 +300,8 @@
0E05413925A231D500EFC5FF /* DemoTunnel.entitlements */,
0E05414C25A231D500EFC5FF /* Demo.plist */,
0E05414B25A231D500EFC5FF /* AppDelegate.swift */,
- 0E05414425A231D500EFC5FF /* ViewController.swift */,
+ 0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */,
+ 0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */,
0E05414525A231D500EFC5FF /* Assets.xcassets */,
0E05414625A231D500EFC5FF /* LaunchScreen.storyboard */,
0E05414825A231D500EFC5FF /* Main.storyboard */,
@@ -269,9 +339,11 @@
children = (
0E1108A91F77B9F900A92462 /* TunnelKitHost.app */,
0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */,
- 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */,
+ 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */,
0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */,
- 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */,
+ 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */,
+ 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */,
+ 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */,
);
name = Products;
sourceTree = "";
@@ -305,6 +377,37 @@
};
/* End PBXGroup section */
+/* Begin PBXLegacyTarget section */
+ 0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "$(ACTION)";
+ buildConfigurationList = 0E81EB55274BB0D000E5F2D3 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-macOS" */;
+ buildPhases = (
+ );
+ buildToolPath = "$(PROJECT_DIR)/../Scripts/build_wireguard_go_bridge.sh";
+ buildWorkingDirectory = "";
+ dependencies = (
+ );
+ name = "TunnelKitDemoWireGuardKitGo-macOS";
+ passBuildSettingsInEnvironment = 1;
+ productName = "TunnelKitDemoWireGuardKitGo-macOS";
+ };
+ 0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "$(ACTION)";
+ buildConfigurationList = 0EDD211E274BB4CF006833D1 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-iOS" */;
+ buildPhases = (
+ );
+ buildToolPath = "$(PROJECT_DIR)/../Scripts/build_wireguard_go_bridge.sh";
+ buildWorkingDirectory = "";
+ dependencies = (
+ );
+ name = "TunnelKitDemoWireGuardKitGo-iOS";
+ passBuildSettingsInEnvironment = 1;
+ productName = "TunnelKitDemoWireGuardKitGo-iOS";
+ };
+/* End PBXLegacyTarget section */
+
/* Begin PBXNativeTarget section */
0E05416825A232FD00EFC5FF /* TunnelKitDemo-iOS */ = {
isa = PBXNativeTarget;
@@ -320,18 +423,20 @@
);
dependencies = (
0E0541A825A2343500EFC5FF /* PBXTargetDependency */,
+ 0E833A8C274BC39C008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemo-iOS";
packageProductDependencies = (
0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */,
+ 0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */,
);
productName = Demo;
productReference = 0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */;
productType = "com.apple.product-type.application";
};
- 0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */ = {
+ 0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-iOS" */;
+ buildConfigurationList = 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-iOS" */;
buildPhases = (
0E05419B25A2343500EFC5FF /* Sources */,
0E05419C25A2343500EFC5FF /* Frameworks */,
@@ -341,12 +446,12 @@
);
dependencies = (
);
- name = "TunnelKitDemoTunnel-iOS";
+ name = "TunnelKitDemoOpenVPNTunnel-iOS";
packageProductDependencies = (
0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */,
);
productName = Tunnel;
- productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */;
+ productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */;
productType = "com.apple.product-type.app-extension";
};
0E05422B25A236EB00EFC5FF /* TunnelKitDemo-macOS */ = {
@@ -363,18 +468,20 @@
);
dependencies = (
0E05427F25A239C600EFC5FF /* PBXTargetDependency */,
+ 0E833A9D274BC3B1008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemo-macOS";
packageProductDependencies = (
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */,
+ 0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */,
);
productName = Demo;
productReference = 0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */;
productType = "com.apple.product-type.application";
};
- 0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */ = {
+ 0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-macOS" */;
+ buildConfigurationList = 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-macOS" */;
buildPhases = (
0E05427325A239C600EFC5FF /* Sources */,
0E05427425A239C600EFC5FF /* Frameworks */,
@@ -384,12 +491,12 @@
);
dependencies = (
);
- name = "TunnelKitDemoTunnel-macOS";
+ name = "TunnelKitDemoOpenVPNTunnel-macOS";
packageProductDependencies = (
0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */,
);
productName = Tunnel;
- productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */;
+ productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */;
productType = "com.apple.product-type.app-extension";
};
0E1108A81F77B9F900A92462 /* TunnelKitHost */ = {
@@ -410,13 +517,55 @@
productReference = 0E1108A91F77B9F900A92462 /* TunnelKitHost.app */;
productType = "com.apple.product-type.application";
};
+ 0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 0E833A8E274BC39C008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-iOS" */;
+ buildPhases = (
+ 0E833A80274BC39C008EA397 /* Sources */,
+ 0E833A81274BC39C008EA397 /* Frameworks */,
+ 0E833A82274BC39C008EA397 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 0E833AA9274BC49B008EA397 /* PBXTargetDependency */,
+ );
+ name = "TunnelKitDemoWireGuardTunnel-iOS";
+ packageProductDependencies = (
+ 0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */,
+ );
+ productName = "TunnelKitDemoWireGuardTunnel-iOS";
+ productReference = 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
+ 0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 0E833A9F274BC3B2008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-macOS" */;
+ buildPhases = (
+ 0E833A91274BC3B1008EA397 /* Sources */,
+ 0E833A92274BC3B1008EA397 /* Frameworks */,
+ 0E833A93274BC3B1008EA397 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 0E833AA7274BC496008EA397 /* PBXTargetDependency */,
+ );
+ name = "TunnelKitDemoWireGuardTunnel-macOS";
+ packageProductDependencies = (
+ 0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */,
+ );
+ productName = "TunnelKitDemoWireGuardTunnel-macOS";
+ productReference = 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0E17D7F01F730D9F009EE129 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastSwiftUpdateCheck = 1230;
+ LastSwiftUpdateCheck = 1310;
LastUpgradeCheck = 1230;
ORGANIZATIONNAME = "Davide De Rosa";
TargetAttributes = {
@@ -449,6 +598,20 @@
};
};
};
+ 0E81EB54274BB0D000E5F2D3 = {
+ CreatedOnToolsVersion = 13.1;
+ };
+ 0E833A83274BC39C008EA397 = {
+ CreatedOnToolsVersion = 13.1;
+ LastSwiftMigration = 1310;
+ };
+ 0E833A94274BC3B1008EA397 = {
+ CreatedOnToolsVersion = 13.1;
+ LastSwiftMigration = 1310;
+ };
+ 0EDD211D274BB4CF006833D1 = {
+ CreatedOnToolsVersion = 13.1;
+ };
};
};
buildConfigurationList = 0E17D7F31F730D9F009EE129 /* Build configuration list for PBXProject "TunnelKit" */;
@@ -467,8 +630,12 @@
0E1108A81F77B9F900A92462 /* TunnelKitHost */,
0E05416825A232FD00EFC5FF /* TunnelKitDemo-iOS */,
0E05422B25A236EB00EFC5FF /* TunnelKitDemo-macOS */,
- 0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */,
- 0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */,
+ 0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */,
+ 0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */,
+ 0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */,
+ 0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */,
+ 0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */,
+ 0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */,
);
};
/* End PBXProject section */
@@ -517,6 +684,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 0E833A82274BC39C008EA397 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0E833A93274BC3B1008EA397 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -525,7 +706,8 @@
buildActionMask = 2147483647;
files = (
0E0541D825A2355000EFC5FF /* Configuration.swift in Sources */,
- 0E05418825A2334500EFC5FF /* ViewController.swift in Sources */,
+ 0E81EB4C274BACF200E5F2D3 /* WireGuardViewController.swift in Sources */,
+ 0E05418825A2334500EFC5FF /* OpenVPNViewController.swift in Sources */,
0E05418725A2334500EFC5FF /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -534,7 +716,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E0541D125A2354500EFC5FF /* PacketTunnelProvider.swift in Sources */,
+ 0E0541D125A2354500EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -543,8 +725,9 @@
buildActionMask = 2147483647;
files = (
0E0542B925A23A8100EFC5FF /* Configuration.swift in Sources */,
+ 0E81EB4F274BAE0A00E5F2D3 /* WireGuardViewController.swift in Sources */,
0E05425825A2392E00EFC5FF /* AppDelegate.swift in Sources */,
- 0E05425925A2392E00EFC5FF /* ViewController.swift in Sources */,
+ 0E05425925A2392E00EFC5FF /* OpenVPNViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -552,7 +735,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E0542C225A23A8400EFC5FF /* PacketTunnelProvider.swift in Sources */,
+ 0E0542C225A23A8400EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -565,19 +748,55 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 0E833A80274BC39C008EA397 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0E833AAD274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 0E833A91274BC3B1008EA397 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 0E833AAE274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0E0541A825A2343500EFC5FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */;
+ target = 0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */;
targetProxy = 0E0541A725A2343500EFC5FF /* PBXContainerItemProxy */;
};
0E05427F25A239C600EFC5FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */;
+ target = 0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */;
targetProxy = 0E05427E25A239C600EFC5FF /* PBXContainerItemProxy */;
};
+ 0E833A8C274BC39C008EA397 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */;
+ targetProxy = 0E833A8B274BC39C008EA397 /* PBXContainerItemProxy */;
+ };
+ 0E833A9D274BC3B1008EA397 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */;
+ targetProxy = 0E833A9C274BC3B1008EA397 /* PBXContainerItemProxy */;
+ };
+ 0E833AA7274BC496008EA397 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */;
+ targetProxy = 0E833AA6274BC496008EA397 /* PBXContainerItemProxy */;
+ };
+ 0E833AA9274BC49B008EA397 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */;
+ targetProxy = 0E833AA8274BC49B008EA397 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -627,6 +846,7 @@
0E05417B25A2330100EFC5FF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/Demo.entitlements;
@@ -641,7 +861,6 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -649,6 +868,7 @@
0E05417C25A2330100EFC5FF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/Demo.entitlements;
@@ -662,7 +882,6 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@@ -674,7 +893,7 @@
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
- INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -682,10 +901,9 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.Tunnel;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
- SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -697,17 +915,16 @@
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
- INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.Tunnel;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
- SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@@ -715,6 +932,7 @@
0E05423925A236EE00EFC5FF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/Demo.entitlements;
@@ -733,13 +951,13 @@
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
- SWIFT_VERSION = 5.0;
};
name = Debug;
};
0E05423A25A236EE00EFC5FF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/Demo.entitlements;
@@ -757,7 +975,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
- SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -770,7 +987,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
- INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
@@ -778,11 +995,10 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.Tunnel;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
- SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -795,18 +1011,17 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
- INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.Tunnel;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
- SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -905,10 +1120,11 @@
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
+ PATH = "${PATH}:/opt/homebrew/bin";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 4.2;
+ SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@@ -964,16 +1180,173 @@
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = NO;
+ PATH = "${PATH}:/opt/homebrew/bin";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
- SWIFT_VERSION = 4.2;
+ SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
+ 0E81EB56274BB0D000E5F2D3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 0E81EB57274BB0D000E5F2D3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 0E833A8F274BC39C008EA397 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = DTDYD63ZX9;
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 0E833A90274BC39C008EA397 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = DTDYD63ZX9;
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 0E833AA0274BC3B2008EA397 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_ENTITLEMENTS = Demo/macOS/DemoTunnel.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = DTDYD63ZX9;
+ ENABLE_HARDENED_RUNTIME = YES;
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "TunnelKitDemoWireGuardTunnel-macOS";
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Davide De Rosa. All rights reserved.";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 12.0;
+ MARKETING_VERSION = 1.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 0E833AA1274BC3B2008EA397 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_ENTITLEMENTS = Demo/macOS/DemoTunnel.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = DTDYD63ZX9;
+ ENABLE_HARDENED_RUNTIME = YES;
+ INFOPLIST_FILE = Demo/DemoTunnel.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "TunnelKitDemoWireGuardTunnel-macOS";
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Davide De Rosa. All rights reserved.";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 12.0;
+ MARKETING_VERSION = 1.0;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 0EDD211F274BB4CF006833D1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 0EDD2120274BB4CF006833D1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -986,7 +1359,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-iOS" */ = {
+ 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E0541AB25A2343500EFC5FF /* Debug */,
@@ -1004,7 +1377,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-macOS" */ = {
+ 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E05428225A239C600EFC5FF /* Debug */,
@@ -1031,6 +1404,42 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 0E81EB55274BB0D000E5F2D3 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-macOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0E81EB56274BB0D000E5F2D3 /* Debug */,
+ 0E81EB57274BB0D000E5F2D3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 0E833A8E274BC39C008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0E833A8F274BC39C008EA397 /* Debug */,
+ 0E833A90274BC39C008EA397 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 0E833A9F274BC3B2008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-macOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0E833AA0274BC3B2008EA397 /* Debug */,
+ 0E833AA1274BC3B2008EA397 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 0EDD211E274BB4CF006833D1 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 0EDD211F274BB4CF006833D1 /* Debug */,
+ 0EDD2120274BB4CF006833D1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
@@ -1042,6 +1451,22 @@
isa = XCSwiftPackageProductDependency;
productName = TunnelKitOpenVPNAppExtension;
};
+ 0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = TunnelKitWireGuard;
+ };
+ 0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = TunnelKitWireGuard;
+ };
+ 0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = TunnelKitWireGuardAppExtension;
+ };
+ 0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = TunnelKitWireGuardAppExtension;
+ };
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitOpenVPN;
diff --git a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-iOS.xcscheme b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-iOS.xcscheme
similarity index 77%
rename from Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-iOS.xcscheme
rename to Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-iOS.xcscheme
index d709fb6..b102911 100644
--- a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-iOS.xcscheme
+++ b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-iOS.xcscheme
@@ -16,8 +16,8 @@
@@ -57,16 +57,6 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
-
-
-
-
-
+
-
+
diff --git a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-macOS.xcscheme b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-macOS.xcscheme
similarity index 77%
rename from Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-macOS.xcscheme
rename to Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-macOS.xcscheme
index a2b3b2a..a593f03 100644
--- a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoTunnel-macOS.xcscheme
+++ b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoOpenVPNTunnel-macOS.xcscheme
@@ -16,8 +16,8 @@
@@ -57,16 +57,6 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
-
-
-
-
-
+
-
+
diff --git a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-iOS.xcscheme b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-iOS.xcscheme
new file mode 100644
index 0000000..d5801ea
--- /dev/null
+++ b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-iOS.xcscheme
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-macOS.xcscheme b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-macOS.xcscheme
new file mode 100644
index 0000000..8712027
--- /dev/null
+++ b/Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemoWireGuardTunnel-macOS.xcscheme
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Package.resolved b/Package.resolved
index b4b65f0..34adf8e 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -18,6 +18,15 @@
"revision": "2c039501d6eeb4d4cd4aec4a8d884ad28862e044",
"version": "1.9.5"
}
+ },
+ {
+ "package": "WireGuardKit",
+ "repositoryURL": "https://git.zx2c4.com/wireguard-apple",
+ "state": {
+ "branch": null,
+ "revision": "10da5cfdef362889b438cfbeff867a74e6d717fd",
+ "version": "1.0.15-26"
+ }
}
]
},
diff --git a/Package.swift b/Package.swift
index 3e35f92..8bd26a3 100644
--- a/Package.swift
+++ b/Package.swift
@@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "TunnelKit",
platforms: [
- .iOS(.v11), .macOS(.v10_15)
+ .iOS(.v12), .macOS(.v10_15)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
@@ -26,6 +26,14 @@ let package = Package(
name: "TunnelKitOpenVPNAppExtension",
targets: ["TunnelKitOpenVPNAppExtension"]
),
+ .library(
+ name: "TunnelKitWireGuard",
+ targets: ["TunnelKitWireGuard"]
+ ),
+ .library(
+ name: "TunnelKitWireGuardAppExtension",
+ targets: ["TunnelKitWireGuardAppExtension"]
+ ),
.library(
name: "TunnelKitLZO",
targets: ["TunnelKitLZO"]
@@ -35,7 +43,8 @@ let package = Package(
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0"),
- .package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "1.1.11200")
+ .package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "1.1.11200"),
+ .package(name: "WireGuardKit", url: "https://git.zx2c4.com/wireguard-apple", .exact("1.0.15-26"))
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -103,6 +112,30 @@ let package = Package(
"TunnelKitOpenVPNManager",
"TunnelKitOpenVPNProtocol"
]),
+ //
+ .target(
+ name: "TunnelKitWireGuard",
+ dependencies: [
+ "TunnelKitWireGuardCore",
+ "TunnelKitWireGuardManager"
+ ]),
+ .target(
+ name: "TunnelKitWireGuardCore",
+ dependencies: [
+ "WireGuardKit"
+ ]),
+ .target(
+ name: "TunnelKitWireGuardManager",
+ dependencies: [
+ "TunnelKitManager",
+ "TunnelKitWireGuardCore"
+ ]),
+ .target(
+ name: "TunnelKitWireGuardAppExtension",
+ dependencies: [
+ "TunnelKitWireGuardCore",
+ "TunnelKitWireGuardManager"
+ ]),
.target(
name: "TunnelKitLZO",
dependencies: [],
diff --git a/README.md b/README.md
index 10fbb80..faa11fe 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,19 @@
-![iOS 11+](https://img.shields.io/badge/iOS-11+-green.svg)
-![macOS 10.15+](https://img.shields.io/badge/macOS-10.15+-green.svg)
-[![License GPLv3](https://img.shields.io/badge/License-GPLv3-lightgray.svg)](LICENSE)
-[![GitHub Actions](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml)
+![iOS 12+](https://img.shields.io/badge/ios-12+-green.svg)
+![macOS 10.15+](https://img.shields.io/badge/macos-10.15+-green.svg)
+[![License GPLv3](https://img.shields.io/badge/license-GPLv3-lightgray.svg)](LICENSE)
+
+[![Unit Tests](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml)
+[![Release](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml)
# TunnelKit
-This library provides a generic framework for VPN development and a simplified Swift/Obj-C implementation of the OpenVPN® protocol for the Apple platforms. The crypto layer is built on top of [OpenSSL 1.1.1][dep-openssl], which in turn enables support for a certain range of encryption and digest algorithms.
+This library provides a generic framework for VPN development on Apple platforms.
-## Getting started
+## OpenVPN
-The client is known to work with [OpenVPN®][openvpn] 2.3+ servers.
+TunnelKit comes with a simplified Swift/Obj-C implementation of the [OpenVPN®][dep-openvpn] protocol, whose crypto layer is built on top of [OpenSSL 1.1.1][dep-openssl].
+
+The client is known to work with OpenVPN® 2.3+ servers.
- [x] Handshake and tunneling over UDP or TCP
- [x] Ciphers
@@ -67,11 +71,36 @@ TunnelKit can parse .ovpn configuration files. Below are a few details worth men
Many other flags are ignored too but it's normally not an issue.
+## WireGuard
+
+TunnelKit offers a user-friendly API to the modern [WireGuard®][dep-wireguard] protocol.
+
+### Manual Xcode steps
+
+If you add any `TunnelKitWireGuard*` Swift package to the "Link with binary libraries" section of your app or tunnel extension, you are bound to hit this error:
+
+```
+ld: library not found for -lwg-go
+```
+
+because part of the WireGuardKit package is based on `make`, which SwiftPM doesn't support yet.
+
+Therefore, make sure to follow the steps below for proper integration:
+
+- Copy `Scripts/build_wireguard_go_bridge.sh` somewhere in your project.
+- In Xcode, click File -> New -> Target. Switch to "Other" tab and choose "External Build System".
+- Type a name for your target.
+- Open the "Info" tab and replace `/usr/bin/make` with `$(PROJECT_DIR)/path/to/build_wireguard_go_bridge.sh` in "Build Tool".
+- Switch to "Build Settings" and find SDKROOT. Type in `macosx` if you target macOS, or type in `iphoneos` if you target iOS.
+- Locate your tunnel extension target and switch to "Build Phases" tab.
+- Locate "Dependencies" section and hit "+" to add the target you have just created.
+- Repeat the process for each platform.
+
## Installation
### Requirements
-- iOS 11.0+ / macOS 10.15+
+- iOS 12.0+ / macOS 10.15+
- SwiftPM 5.3
- Git (preinstalled with Xcode Command Line Tools)
@@ -79,7 +108,7 @@ It's highly recommended to use the Git package provided by [Homebrew][dep-brew].
### Caveats
-Make sure to set "Enable Bitcode" (iOS) to NO, otherwise the library [would not be able to link OpenSSL][about-pr-bitcode].
+Make sure to set "Enable Bitcode" (iOS) to NO, otherwise the library [would not be able to link OpenSSL][about-pr-bitcode] (OpenVPN) and the `wg-go` bridge (WireGuard).
Recent versions of Xcode (latest is 13.1) have an issue where the "Frameworks" directory is replicated inside application extensions. This is not a blocker during development, but will prevent your archive from being validated against App Store Connect due to the following error:
@@ -101,14 +130,14 @@ Download the library codebase locally:
$ git clone https://github.com/passepartoutvpn/tunnelkit.git
-There are demo targets containing a simple app for testing the tunnel, called `BasicTunnel`. Open `Demo/TunnelKit.xcodeproject` in Xcode and run it on both iOS and macOS.
+There are demo targets containing a simple app for testing the tunnels. Open `Demo/TunnelKit.xcodeproject` in Xcode and run it on both iOS and macOS.
-For the VPN to work properly, the `BasicTunnel` demo requires:
+For the VPN to work properly, the demo requires:
- _App Groups_ and _Keychain Sharing_ capabilities
- App IDs with _Packet Tunnel_ entitlements
-both in the main app and the tunnel extension target.
+both in the main app and the tunnel extension targets.
In order to test connectivity in your own environment, modify the file `Demo/Demo/Configuration.swift` to match your VPN server parameters.
@@ -120,10 +149,10 @@ Example:
-----END CERTIFICATE-----
""")
-Make sure to also update the following constants in the same files, according to your developer account and your target bundle identifiers:
+Make sure to also update the following constants in the `*ViewController.swift` files, according to your developer account and your target bundle identifiers:
- public static let appGroup
- public static let tunnelIdentifier
+ private let appGroup = "..."
+ private let tunnelIdentifier = "..."
Remember that the App Group on macOS requires a team ID prefix.
@@ -133,51 +162,32 @@ The library is split into several modules, in order to decouple the low-level pr
Full documentation of the public interface is available and can be generated by opening the package in Xcode and running "Build Documentation" (Xcode 13).
-### TunnelKitCore
-
-Contains the building blocks of a VPN protocol. Eventually, a consumer would implement the `Session` interface, expected to start and control the VPN session. A session is expected to work with generic network interfaces:
-
-- `LinkInterface` (e.g. a socket)
-- `TunnelInterface` (e.g. an `utun` interface)
-
-There are no physical network implementations (e.g. UDP or TCP) in this module.
-
-### TunnelKitManager
+### TunnelKit
This component includes convenient classes to control the VPN tunnel from your app without the NetworkExtension headaches. Have a look at `VPNProvider` implementations:
- `MockVPNProvider` (default, useful to test on simulator)
- `NetworkExtensionVPNProvider` (anything based on NetworkExtension)
-### TunnelKitAppExtension
-
-Provides a layer on top of the NetworkExtension framework. Most importantly, bridges native [NWUDPSession][ne-udp] and [NWTCPConnection][ne-tcp] to an abstract `GenericSocket` interface, thus making a multi-protocol VPN dramatically easier to manage.
-
### TunnelKitIKE
Here you find `NativeProvider`, a generic way to manage a VPN profile based on the native IPSec/IKEv2 protocols. Just wrap a `NEVPNProtocolIPSec` or `NEVPNProtocolIKEv2` object in a `NetworkExtensionVPNConfiguration` and use it to install or connect to the VPN.
-### TunnelKitOpenVPN*
+### TunnelKitOpenVPN
-#### Protocol
+Provides the entities to interact with the OpenVPN tunnel.
-Here are the low-level entities on top of which an OpenVPN connection is established. Code is mixed Swift and Obj-C, most of it is not exposed to consumers. The protocol implementation in particular depends on OpenSSL.
+### TunnelKitOpenVPNAppExtension
-The entry point is the `OpenVPNSession` class. The networking layer is fully abstract and delegated externally with the use of opaque `IOInterface` (`LinkInterface` and `TunnelInterface`) and `OpenVPNSessionDelegate` protocols.
+Contains the `NEPacketTunnelProvider` implementation of a OpenVPN tunnel.
-#### AppExtension
+### TunnelKitWireGuard
-Another goal of this area is packaging up a black box implementation of a [NEPacketTunnelProvider][ne-ptp], which is the essential part of a Packet Tunnel Provider app extension. You will find the main implementation in the `OpenVPNTunnelProvider` class.
+Provides the entities to interact with the WireGuard tunnel.
-A debug log snapshot is optionally maintained and shared by the tunnel provider to host apps via the App Group container.
+### TunnelKitWireGuardAppExtension
-#### Manager
-
-On the client side, you manage the VPN profile with the `OpenVPNProvider` class, which is a specific implementation of `NetworkExtensionVPNProvider`.
-
-### TunnelKitLZO
-
-Due to the restrictive license (GPLv2), LZO support is provided as an optional component.
+Contains the `NEPacketTunnelProvider` implementation of a WireGuard tunnel.
## License
@@ -210,20 +220,29 @@ For more details please see [CONTRIBUTING][contrib-readme].
- [SURFnet][ppl-surfnet]
- [SwiftyBeaver][dep-swiftybeaver-repo] - Copyright (c) 2015 Sebastian Kreutzberger
- [XMB5][ppl-xmb5] for the [XOR patch][ppl-xmb5-xor] - Copyright (c) 2020 Sam Foxman
+- [eduVPN][ppl-eduvpn] for the convenient WireGuardKitGo script
-This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
+### OpenVPN
Copyright (c) 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc.
+### WireGuard
+
+© Copyright 2015-2021 Jason A. Donenfeld. All Rights Reserved. "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.
+
+### OpenSSL
+
+This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
+
## Contacts
Twitter: [@keeshux][about-twitter]
Website: [passepartoutvpn.app][about-website]
-[openvpn]: https://openvpn.net/index.php/open-source/overview.html
-
[dep-brew]: https://brew.sh/
+[dep-openvpn]: https://openvpn.net/index.php/open-source/overview.html
+[dep-wireguard]: https://www.wireguard.com/
[dep-openssl]: https://www.openssl.org/
[ne-home]: https://developer.apple.com/documentation/networkextension
@@ -243,6 +262,7 @@ Website: [passepartoutvpn.app][about-website]
[ppl-surfnet]: https://www.surf.nl/en/about-surf/subsidiaries/surfnet
[ppl-xmb5]: https://github.com/XMB5
[ppl-xmb5-xor]: https://github.com/passepartoutvpn/tunnelkit/pull/170
+[ppl-eduvpn]: https://github.com/eduvpn/apple
[about-tunnelblick-xor]: https://tunnelblick.net/cOpenvpn_xorpatch.html
[about-pr-bitcode]: https://github.com/passepartoutvpn/tunnelkit/issues/51
diff --git a/Scripts/build_wireguard_go_bridge.sh b/Scripts/build_wireguard_go_bridge.sh
new file mode 100755
index 0000000..ab6fa84
--- /dev/null
+++ b/Scripts/build_wireguard_go_bridge.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# build_wireguard_go_bridge.sh - Builds WireGuardKitGo
+#
+# Figures out the directory where the wireguard-apple SPM package
+# is checked out by Xcode (so that it works when building as well as
+# archiving), then cd-s to the WireGuardKitGo directory
+# and runs make there.
+
+project_data_dir="$BUILD_DIR"
+
+# The wireguard-apple README suggests using ${BUILD_DIR%Build/*}, which
+# doesn't seem to work. So here, we do the equivalent in script.
+
+while true; do
+ parent_dir=$(dirname "$project_data_dir")
+ basename=$(basename "$project_data_dir")
+ project_data_dir="$parent_dir"
+ if [ "$basename" = "Build" ]; then
+ break
+ fi
+done
+
+# The wireguard-apple README looks into
+# SourcePackages/checkouts/wireguard-apple, but Xcode seems to place the
+# sources in SourcePackages/checkouts/ so just playing it safe and
+# trying both.
+
+checkouts_dir="$project_data_dir"/SourcePackages/checkouts
+if [ -e "$checkouts_dir"/wireguard-apple ]; then
+ checkouts_dir="$checkouts_dir"/wireguard-apple
+fi
+
+wireguard_go_dir="$checkouts_dir"/Sources/WireGuardKitGo
+
+# To ensure we have Go in our path, we add where
+# Homebrew generally installs executables
+export PATH=${PATH}:/usr/local/bin:/opt/homebrew/bin
+
+cd "$wireguard_go_dir" && /usr/bin/make
diff --git a/Sources/TunnelKitWireGuard/Exports.swift b/Sources/TunnelKitWireGuard/Exports.swift
new file mode 100644
index 0000000..1956691
--- /dev/null
+++ b/Sources/TunnelKitWireGuard/Exports.swift
@@ -0,0 +1,2 @@
+@_exported import TunnelKitWireGuardCore
+@_exported import TunnelKitWireGuardManager
diff --git a/Sources/TunnelKitWireGuardAppExtension/Internal/ErrorNotifier.swift b/Sources/TunnelKitWireGuardAppExtension/Internal/ErrorNotifier.swift
new file mode 100644
index 0000000..37b7e7f
--- /dev/null
+++ b/Sources/TunnelKitWireGuardAppExtension/Internal/ErrorNotifier.swift
@@ -0,0 +1,42 @@
+import TunnelKitWireGuardCore
+import TunnelKitWireGuardManager
+
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import NetworkExtension
+
+class ErrorNotifier {
+ private let appGroupId: String
+
+ private var sharedFolderURL: URL? {
+ guard let sharedFolderURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupId) else {
+ wg_log(.error, message: "Cannot obtain shared folder URL")
+ return nil
+ }
+ return sharedFolderURL
+ }
+
+ init(appGroupId: String) {
+ self.appGroupId = appGroupId
+ removeLastErrorFile()
+ }
+
+ func notify(_ error: WireGuardProviderError) {
+ guard let lastErrorFilePath = networkExtensionLastErrorFileURL?.path else {
+ return
+ }
+ let errorMessageData = "\(error)".data(using: .utf8)
+ FileManager.default.createFile(atPath: lastErrorFilePath, contents: errorMessageData, attributes: nil)
+ }
+
+ func removeLastErrorFile() {
+ if let lastErrorFileURL = networkExtensionLastErrorFileURL {
+ try? FileManager.default.removeItem(at: lastErrorFileURL)
+ }
+ }
+
+ private var networkExtensionLastErrorFileURL: URL? {
+ return sharedFolderURL?.appendingPathComponent("last-error.txt")
+ }
+}
diff --git a/Sources/TunnelKitWireGuardAppExtension/WireGuardTunnelProvider.swift b/Sources/TunnelKitWireGuardAppExtension/WireGuardTunnelProvider.swift
new file mode 100644
index 0000000..3752b0c
--- /dev/null
+++ b/Sources/TunnelKitWireGuardAppExtension/WireGuardTunnelProvider.swift
@@ -0,0 +1,134 @@
+import TunnelKitWireGuardCore
+import TunnelKitWireGuardManager
+import WireGuardKit
+
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+import NetworkExtension
+import os
+
+open class WireGuardTunnelProvider: NEPacketTunnelProvider {
+ private var persistentErrorNotifier: ErrorNotifier?
+
+ private lazy var adapter: WireGuardAdapter = {
+ return WireGuardAdapter(with: self) { logLevel, message in
+ wg_log(logLevel.osLogLevel, message: message)
+ }
+ }()
+
+ open override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
+
+ // BEGIN: TunnelKit
+
+ guard let tunnelProviderProtocol = protocolConfiguration as? NETunnelProviderProtocol else {
+ fatalError("Not a NETunnelProviderProtocol")
+ }
+ guard let appGroup = tunnelProviderProtocol.providerConfiguration?["AppGroup"] as? String else {
+ fatalError("AppGroup not found in providerConfiguration")
+ }
+ let errorNotifier = ErrorNotifier(appGroupId: appGroup)
+ persistentErrorNotifier = errorNotifier
+
+ let tunnelConfiguration: TunnelConfiguration
+ do {
+ tunnelConfiguration = try WireGuardProvider.Configuration.parsed(from: tunnelProviderProtocol).tunnelConfiguration
+ } catch {
+ errorNotifier.notify(WireGuardProviderError.savedProtocolConfigurationIsInvalid)
+ completionHandler(WireGuardProviderError.savedProtocolConfigurationIsInvalid)
+ return
+ }
+
+ // END: TunnelKit
+
+ // Start the tunnel
+ adapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
+ guard let adapterError = adapterError else {
+ let interfaceName = self.adapter.interfaceName ?? "unknown"
+
+ wg_log(.info, message: "Tunnel interface is \(interfaceName)")
+
+ completionHandler(nil)
+ return
+ }
+
+ switch adapterError {
+ case .cannotLocateTunnelFileDescriptor:
+ wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor")
+ errorNotifier.notify(WireGuardProviderError.couldNotDetermineFileDescriptor)
+ completionHandler(WireGuardProviderError.couldNotDetermineFileDescriptor)
+
+ case .dnsResolution(let dnsErrors):
+ let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address }
+ .joined(separator: ", ")
+ wg_log(.error, message: "DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)")
+ errorNotifier.notify(WireGuardProviderError.dnsResolutionFailure)
+ completionHandler(WireGuardProviderError.dnsResolutionFailure)
+
+ case .setNetworkSettings(let error):
+ wg_log(.error, message: "Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)")
+ errorNotifier.notify(WireGuardProviderError.couldNotSetNetworkSettings)
+ completionHandler(WireGuardProviderError.couldNotSetNetworkSettings)
+
+ case .startWireGuardBackend(let errorCode):
+ wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)")
+ errorNotifier.notify(WireGuardProviderError.couldNotStartBackend)
+ completionHandler(WireGuardProviderError.couldNotStartBackend)
+
+ case .invalidState:
+ // Must never happen
+ fatalError()
+ }
+ }
+ }
+
+ open override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
+ wg_log(.info, staticMessage: "Stopping tunnel")
+
+ adapter.stop { error in
+ // BEGIN: TunnelKit
+ self.persistentErrorNotifier?.removeLastErrorFile()
+ // END: TunnelKit
+
+ if let error = error {
+ wg_log(.error, message: "Failed to stop WireGuard adapter: \(error.localizedDescription)")
+ }
+ completionHandler()
+
+ #if os(macOS)
+ // HACK: This is a filthy hack to work around Apple bug 32073323 (dup'd by us as 47526107).
+ // Remove it when they finally fix this upstream and the fix has been rolled out to
+ // sufficient quantities of users.
+ exit(0)
+ #endif
+ }
+ }
+
+ open override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
+ guard let completionHandler = completionHandler else { return }
+
+ if messageData.count == 1 && messageData[0] == 0 {
+ adapter.getRuntimeConfiguration { settings in
+ var data: Data?
+ if let settings = settings {
+ data = settings.data(using: .utf8)!
+ }
+ completionHandler(data)
+ }
+ } else {
+ completionHandler(nil)
+ }
+ }
+}
+
+extension WireGuardLogLevel {
+ var osLogLevel: OSLogType {
+ switch self {
+ case .verbose:
+ return .debug
+ case .error:
+ return .error
+ }
+ }
+}
diff --git a/Sources/TunnelKitWireGuardCore/Configuration+WireGuardKit.swift b/Sources/TunnelKitWireGuardCore/Configuration+WireGuardKit.swift
new file mode 100644
index 0000000..e5e8759
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/Configuration+WireGuardKit.swift
@@ -0,0 +1,48 @@
+//
+// Configuration+WireGuardKit.swift
+// TunnelKit
+//
+// Created by Davide De Rosa on 11/23/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/passepartoutvpn
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Foundation
+import WireGuardKit
+
+extension WireGuard.Configuration {
+ public init(wgQuickConfig: String) throws {
+ tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: wgQuickConfig)
+ }
+
+ public func asWgQuickConfig() -> String {
+ return tunnelConfiguration.asWgQuickConfig()
+ }
+
+ public var endpointRepresentation: String {
+ let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
+ if endpoints.count == 1 {
+ return endpoints[0].stringRepresentation
+ } else if endpoints.isEmpty {
+ return "Unspecified"
+ } else {
+ return "Multiple endpoints"
+ }
+ }
+}
diff --git a/Sources/TunnelKitWireGuardCore/Configuration.swift b/Sources/TunnelKitWireGuardCore/Configuration.swift
new file mode 100644
index 0000000..053c9a0
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/Configuration.swift
@@ -0,0 +1,99 @@
+//
+// Configuration.swift
+// TunnelKit
+//
+// Created by Davide De Rosa on 11/23/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/passepartoutvpn
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Foundation
+import WireGuardKit
+
+extension WireGuard {
+ public struct ConfigurationBuilder {
+ public var privateKey: String?
+
+ public var addresses: [String]?
+
+ public var dns: [String]?
+
+ public var mtu: UInt16?
+
+ public var peerPublicKey: String?
+
+ public var peerPreSharedKey: String?
+
+ public var peerAddress: String?
+
+ public var peerPort: UInt16?
+
+ public var allowedIPs: [String]?
+
+ public var keepAliveInterval: UInt16?
+
+ public init() {
+ }
+
+ public func build() -> Configuration? {
+ guard let privateKey = privateKey, let clientPrivateKey = PrivateKey(base64Key: privateKey) else {
+ return nil
+ }
+ guard let peerPublicKey = peerPublicKey, let serverPublicKey = PublicKey(base64Key: peerPublicKey) else {
+ return nil
+ }
+ guard let peerAddress = peerAddress, let peerPort = peerPort, let endpoint = Endpoint(from: "\(peerAddress):\(peerPort)") else {
+ return nil
+ }
+
+ var interfaceConfiguration = InterfaceConfiguration(privateKey: clientPrivateKey)
+ if let clientAddresses = addresses?.mapOptional({ IPAddressRange(from: $0) }) {
+ interfaceConfiguration.addresses = clientAddresses
+ }
+ if let dnsServers = dns?.mapOptional({ DNSServer(from: $0) }) {
+ interfaceConfiguration.dns = dnsServers
+ }
+ interfaceConfiguration.mtu = mtu
+ var peerConfiguration = PeerConfiguration(publicKey: serverPublicKey)
+ if let peerPreSharedKey = peerPreSharedKey {
+ peerConfiguration.preSharedKey = PreSharedKey(base64Key: peerPreSharedKey)
+ }
+ if let peerAllowedIPs = allowedIPs?.mapOptional({ IPAddressRange(from: $0) }) {
+ peerConfiguration.allowedIPs = peerAllowedIPs
+ }
+ peerConfiguration.endpoint = endpoint
+ peerConfiguration.persistentKeepAlive = keepAliveInterval
+
+ let tunnelConfiguration = TunnelConfiguration(name: nil, interface: interfaceConfiguration, peers: [peerConfiguration])
+ return Configuration(tunnelConfiguration: tunnelConfiguration)
+ }
+ }
+
+ public struct Configuration {
+ public let tunnelConfiguration: TunnelConfiguration
+ }
+}
+
+private extension Array {
+ func mapOptional(_ transform: (Self.Element) throws -> V?) rethrows -> [V] {
+ return try map(transform)
+ .filter { $0 != nil }
+ .map { $0! }
+ }
+}
diff --git a/Sources/TunnelKitWireGuardCore/Internal/Logger.swift b/Sources/TunnelKitWireGuardCore/Internal/Logger.swift
new file mode 100644
index 0000000..8676835
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/Internal/Logger.swift
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+import os.log
+
+public func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
+ os_log(msg, log: OSLog.default, type: type)
+}
+
+public func wg_log(_ type: OSLogType, message msg: String) {
+ os_log("%{public}s", log: OSLog.default, type: type, msg)
+}
diff --git a/Sources/TunnelKitWireGuardCore/Internal/String+ArrayConversion.swift b/Sources/TunnelKitWireGuardCore/Internal/String+ArrayConversion.swift
new file mode 100644
index 0000000..adb959f
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/Internal/String+ArrayConversion.swift
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+
+extension String {
+
+ func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
+ return split(separator: separator)
+ .map {
+ if let charSet = trimmingCharacters {
+ return $0.trimmingCharacters(in: charSet)
+ } else {
+ return String($0)
+ }
+ }
+ }
+
+}
+
+extension Optional where Wrapped == String {
+
+ func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
+ switch self {
+ case .none:
+ return []
+ case .some(let wrapped):
+ return wrapped.splitToArray(separator: separator, trimmingCharacters: trimmingCharacters)
+ }
+ }
+
+}
diff --git a/Sources/TunnelKitWireGuardCore/Internal/TunnelConfiguration+WgQuickConfig.swift b/Sources/TunnelKitWireGuardCore/Internal/TunnelConfiguration+WgQuickConfig.swift
new file mode 100644
index 0000000..72b6e36
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/Internal/TunnelConfiguration+WgQuickConfig.swift
@@ -0,0 +1,254 @@
+import WireGuardKit
+
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+
+extension TunnelConfiguration {
+
+ enum ParserState {
+ case inInterfaceSection
+ case inPeerSection
+ case notInASection
+ }
+
+ enum ParseError: Error {
+ case invalidLine(String.SubSequence)
+ case noInterface
+ case multipleInterfaces
+ case interfaceHasNoPrivateKey
+ case interfaceHasInvalidPrivateKey(String)
+ case interfaceHasInvalidListenPort(String)
+ case interfaceHasInvalidAddress(String)
+ case interfaceHasInvalidDNS(String)
+ case interfaceHasInvalidMTU(String)
+ case interfaceHasUnrecognizedKey(String)
+ case peerHasNoPublicKey
+ case peerHasInvalidPublicKey(String)
+ case peerHasInvalidPreSharedKey(String)
+ case peerHasInvalidAllowedIP(String)
+ case peerHasInvalidEndpoint(String)
+ case peerHasInvalidPersistentKeepAlive(String)
+ case peerHasInvalidTransferBytes(String)
+ case peerHasInvalidLastHandshakeTime(String)
+ case peerHasUnrecognizedKey(String)
+ case multiplePeersWithSamePublicKey
+ case multipleEntriesForKey(String)
+ }
+
+ convenience init(fromWgQuickConfig wgQuickConfig: String, called name: String? = nil) throws {
+ var interfaceConfiguration: InterfaceConfiguration?
+ var peerConfigurations = [PeerConfiguration]()
+
+ let lines = wgQuickConfig.split { $0.isNewline }
+
+ var parserState = ParserState.notInASection
+ var attributes = [String: String]()
+
+ for (lineIndex, line) in lines.enumerated() {
+ var trimmedLine: String
+ if let commentRange = line.range(of: "#") {
+ trimmedLine = String(line[.. = ["address", "allowedips", "dns"]
+ if let presentValue = attributes[key] {
+ if keysWithMultipleEntriesAllowed.contains(key) {
+ attributes[key] = presentValue + "," + value
+ } else {
+ throw ParseError.multipleEntriesForKey(keyWithCase)
+ }
+ } else {
+ attributes[key] = value
+ }
+ let interfaceSectionKeys: Set = ["privatekey", "listenport", "address", "dns", "mtu"]
+ let peerSectionKeys: Set = ["publickey", "presharedkey", "allowedips", "endpoint", "persistentkeepalive"]
+ if parserState == .inInterfaceSection {
+ guard interfaceSectionKeys.contains(key) else {
+ throw ParseError.interfaceHasUnrecognizedKey(keyWithCase)
+ }
+ } else if parserState == .inPeerSection {
+ guard peerSectionKeys.contains(key) else {
+ throw ParseError.peerHasUnrecognizedKey(keyWithCase)
+ }
+ }
+ } 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 {
+ let interface = try TunnelConfiguration.collate(interfaceAttributes: attributes)
+ guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces }
+ interfaceConfiguration = interface
+ } else if parserState == .inPeerSection {
+ let peer = try TunnelConfiguration.collate(peerAttributes: attributes)
+ peerConfigurations.append(peer)
+ }
+ }
+
+ if lowercasedLine == "[interface]" {
+ parserState = .inInterfaceSection
+ attributes.removeAll()
+ } else if lowercasedLine == "[peer]" {
+ parserState = .inPeerSection
+ attributes.removeAll()
+ }
+ }
+
+ let peerPublicKeysArray = peerConfigurations.map { $0.publicKey }
+ let peerPublicKeysSet = Set(peerPublicKeysArray)
+ if peerPublicKeysArray.count != peerPublicKeysSet.count {
+ throw ParseError.multiplePeersWithSamePublicKey
+ }
+
+ if let interfaceConfiguration = interfaceConfiguration {
+ self.init(name: name, interface: interfaceConfiguration, peers: peerConfigurations)
+ } else {
+ throw ParseError.noInterface
+ }
+ }
+
+ func asWgQuickConfig() -> String {
+ var output = "[Interface]\n"
+ output.append("PrivateKey = \(interface.privateKey.base64Key)\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 || !interface.dnsSearch.isEmpty {
+ var dnsLine = interface.dns.map { $0.stringRepresentation }
+ dnsLine.append(contentsOf: interface.dnsSearch)
+ let dnsString = dnsLine.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.base64Key)\n")
+ if let preSharedKey = peer.preSharedKey?.base64Key {
+ output.append("PresharedKey = \(preSharedKey)\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
+ }
+
+ private static func collate(interfaceAttributes attributes: [String: String]) throws -> InterfaceConfiguration {
+ guard let privateKeyString = attributes["privatekey"] else {
+ throw ParseError.interfaceHasNoPrivateKey
+ }
+ guard let privateKey = PrivateKey(base64Key: privateKeyString) else {
+ throw ParseError.interfaceHasInvalidPrivateKey(privateKeyString)
+ }
+ var interface = InterfaceConfiguration(privateKey: privateKey)
+ if let listenPortString = attributes["listenport"] {
+ guard let listenPort = UInt16(listenPortString) else {
+ throw ParseError.interfaceHasInvalidListenPort(listenPortString)
+ }
+ interface.listenPort = listenPort
+ }
+ if let addressesString = attributes["address"] {
+ var addresses = [IPAddressRange]()
+ for addressString in addressesString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
+ guard let address = IPAddressRange(from: addressString) else {
+ throw ParseError.interfaceHasInvalidAddress(addressString)
+ }
+ addresses.append(address)
+ }
+ interface.addresses = addresses
+ }
+ if let dnsString = attributes["dns"] {
+ var dnsServers = [DNSServer]()
+ var dnsSearch = [String]()
+ for dnsServerString in dnsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
+ if let dnsServer = DNSServer(from: dnsServerString) {
+ dnsServers.append(dnsServer)
+ } else {
+ dnsSearch.append(dnsServerString)
+ }
+ }
+ interface.dns = dnsServers
+ interface.dnsSearch = dnsSearch
+ }
+ if let mtuString = attributes["mtu"] {
+ guard let mtu = UInt16(mtuString) else {
+ throw ParseError.interfaceHasInvalidMTU(mtuString)
+ }
+ interface.mtu = mtu
+ }
+ return interface
+ }
+
+ private static func collate(peerAttributes attributes: [String: String]) throws -> PeerConfiguration {
+ guard let publicKeyString = attributes["publickey"] else {
+ throw ParseError.peerHasNoPublicKey
+ }
+ guard let publicKey = PublicKey(base64Key: publicKeyString) else {
+ throw ParseError.peerHasInvalidPublicKey(publicKeyString)
+ }
+ var peer = PeerConfiguration(publicKey: publicKey)
+ if let preSharedKeyString = attributes["presharedkey"] {
+ guard let preSharedKey = PreSharedKey(base64Key: preSharedKeyString) else {
+ throw ParseError.peerHasInvalidPreSharedKey(preSharedKeyString)
+ }
+ peer.preSharedKey = preSharedKey
+ }
+ if let allowedIPsString = attributes["allowedips"] {
+ var allowedIPs = [IPAddressRange]()
+ for allowedIPString in allowedIPsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
+ guard let allowedIP = IPAddressRange(from: allowedIPString) else {
+ throw ParseError.peerHasInvalidAllowedIP(allowedIPString)
+ }
+ allowedIPs.append(allowedIP)
+ }
+ peer.allowedIPs = allowedIPs
+ }
+ if let endpointString = attributes["endpoint"] {
+ guard let endpoint = Endpoint(from: endpointString) else {
+ throw ParseError.peerHasInvalidEndpoint(endpointString)
+ }
+ peer.endpoint = endpoint
+ }
+ if let persistentKeepAliveString = attributes["persistentkeepalive"] {
+ guard let persistentKeepAlive = UInt16(persistentKeepAliveString) else {
+ throw ParseError.peerHasInvalidPersistentKeepAlive(persistentKeepAliveString)
+ }
+ peer.persistentKeepAlive = persistentKeepAlive
+ }
+ return peer
+ }
+
+}
diff --git a/Sources/TunnelKitWireGuardCore/WireGuard.swift b/Sources/TunnelKitWireGuardCore/WireGuard.swift
new file mode 100644
index 0000000..d7dc272
--- /dev/null
+++ b/Sources/TunnelKitWireGuardCore/WireGuard.swift
@@ -0,0 +1,29 @@
+//
+// WireGuard.swift
+// TunnelKit
+//
+// Created by Davide De Rosa on 11/21/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/passepartoutvpn
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Foundation
+
+public class WireGuard {
+}
diff --git a/Sources/TunnelKitWireGuardManager/WireGuardProvider+Configuration.swift b/Sources/TunnelKitWireGuardManager/WireGuardProvider+Configuration.swift
new file mode 100644
index 0000000..a9e9f47
--- /dev/null
+++ b/Sources/TunnelKitWireGuardManager/WireGuardProvider+Configuration.swift
@@ -0,0 +1,79 @@
+//
+// WireGuardProvider+Configuration.swift
+// TunnelKit
+//
+// Created by Davide De Rosa on 11/21/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/passepartoutvpn
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Foundation
+import NetworkExtension
+import TunnelKitManager
+import TunnelKitWireGuardCore
+import WireGuardKit
+
+extension WireGuardProvider {
+ public struct Configuration {
+ public let innerConfiguration: WireGuard.Configuration
+
+ // required by WireGuardTunnelProvider
+ public var tunnelConfiguration: TunnelConfiguration {
+ return innerConfiguration.tunnelConfiguration
+ }
+
+ public init(innerConfiguration: WireGuard.Configuration) {
+ self.innerConfiguration = innerConfiguration
+ }
+
+ private init(wgQuickConfig: String) throws {
+ innerConfiguration = try WireGuard.Configuration(wgQuickConfig: wgQuickConfig)
+ }
+
+ public func generatedTunnelProtocol(withBundleIdentifier bundleIdentifier: String, appGroup: String, context: String) throws -> NETunnelProviderProtocol {
+
+ let protocolConfiguration = NETunnelProviderProtocol()
+ protocolConfiguration.providerBundleIdentifier = bundleIdentifier
+ protocolConfiguration.serverAddress = innerConfiguration.endpointRepresentation
+
+ let keychain = Keychain(group: appGroup)
+ let wgString = innerConfiguration.asWgQuickConfig()
+ protocolConfiguration.passwordReference = try keychain.set(password: wgString, for: "", context: context)
+ protocolConfiguration.providerConfiguration = ["AppGroup": appGroup]
+
+ return protocolConfiguration
+ }
+
+ public static func appGroup(from protocolConfiguration: NETunnelProviderProtocol) throws -> String {
+ guard let appGroup = protocolConfiguration.providerConfiguration?["AppGroup"] as? String else {
+ throw WireGuardProviderError.savedProtocolConfigurationIsInvalid
+ }
+ return appGroup
+ }
+
+ public static func parsed(from protocolConfiguration: NETunnelProviderProtocol) throws -> Configuration {
+ guard let passwordReference = protocolConfiguration.passwordReference,
+ let wgString = try? Keychain.password(forReference: passwordReference) else {
+
+ throw WireGuardProviderError.savedProtocolConfigurationIsInvalid
+ }
+ return try Configuration(wgQuickConfig: wgString)
+ }
+ }
+}
diff --git a/Sources/TunnelKitWireGuardManager/WireGuardProvider.swift b/Sources/TunnelKitWireGuardManager/WireGuardProvider.swift
new file mode 100644
index 0000000..98a3d1f
--- /dev/null
+++ b/Sources/TunnelKitWireGuardManager/WireGuardProvider.swift
@@ -0,0 +1,74 @@
+//
+// WireGuardProvider.swift
+// TunnelKit
+//
+// Created by Davide De Rosa on 11/21/21.
+// Copyright (c) 2021 Davide De Rosa. All rights reserved.
+//
+// https://github.com/passepartoutvpn
+//
+// This file is part of TunnelKit.
+//
+// TunnelKit 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.
+//
+// TunnelKit 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 TunnelKit. If not, see .
+//
+
+import Foundation
+import NetworkExtension
+import TunnelKitManager
+
+public class WireGuardProvider: VPNProvider {
+ private let provider: NetworkExtensionVPNProvider
+
+ public init(bundleIdentifier: String) {
+ provider = NetworkExtensionVPNProvider(locator: NetworkExtensionTunnelLocator(bundleIdentifier: bundleIdentifier))
+ }
+
+ // MARK: VPNProvider
+
+ public var isPrepared: Bool {
+ return provider.isPrepared
+ }
+
+ public var isEnabled: Bool {
+ return provider.isEnabled
+ }
+
+ public var status: VPNStatus {
+ return provider.status
+ }
+
+ public func prepare(completionHandler: (() -> Void)?) {
+ provider.prepare(completionHandler: completionHandler)
+ }
+
+ public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
+ provider.install(configuration: configuration, completionHandler: completionHandler)
+ }
+
+ public func connect(completionHandler: ((Error?) -> Void)?) {
+ provider.connect(completionHandler: completionHandler)
+ }
+
+ public func disconnect(completionHandler: ((Error?) -> Void)?) {
+ provider.disconnect(completionHandler: completionHandler)
+ }
+
+ public func reconnect(configuration: VPNConfiguration, delay: Double? = nil, completionHandler: ((Error?) -> Void)?) {
+ provider.reconnect(configuration: configuration, delay: delay, completionHandler: completionHandler)
+ }
+
+ public func uninstall(completionHandler: (() -> Void)?) {
+ provider.uninstall(completionHandler: completionHandler)
+ }
+}
diff --git a/Sources/TunnelKitWireGuardManager/WireGuardProviderError.swift b/Sources/TunnelKitWireGuardManager/WireGuardProviderError.swift
new file mode 100644
index 0000000..9e05a9c
--- /dev/null
+++ b/Sources/TunnelKitWireGuardManager/WireGuardProviderError.swift
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+
+public enum WireGuardProviderError: String, Error {
+ case savedProtocolConfigurationIsInvalid
+ case dnsResolutionFailure
+ case couldNotStartBackend
+ case couldNotDetermineFileDescriptor
+ case couldNotSetNetworkSettings
+}