diff --git a/Configuration/Framework.xcconfig b/Configuration/Framework.xcconfig
index 7925bcc..c929a26 100755
--- a/Configuration/Framework.xcconfig
+++ b/Configuration/Framework.xcconfig
@@ -6,10 +6,11 @@ DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION)
APPLICATION_EXTENSION_API_ONLY = YES
CLANG_CXX_LANGUAGE_STANDARD = gnu++14
CLANG_CXX_LIBRARY = libc++
-HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/asio/asio/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/openvpn"
-LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/sim" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/sim"
-LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/ios" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/ios"
-LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/macos" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/macos"
+VENDORS_PATH = $(PROJECT_DIR)/OpenVPN Adapter/Vendors
+HEADER_SEARCH_PATHS = "$(VENDORS_PATH)/asio/asio/include" "$(VENDORS_PATH)/lz4/include" "$(VENDORS_PATH)/mbedtls/include" "$(VENDORS_PATH)/openvpn"
+LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(VENDORS_PATH)/lz4/lib/sim" "$(VENDORS_PATH)/mbedtls/lib/sim"
+LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(VENDORS_PATH)/lz4/lib/ios" "$(VENDORS_PATH)/mbedtls/lib/ios"
+LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(VENDORS_PATH)/lz4/lib/macos" "$(VENDORS_PATH)/mbedtls/lib/macos"
OTHER_LDFLAGS = -lmbedtls -lmbedx509 -lmbedcrypto -llz4
OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER
GCC_WARN_64_TO_32_BIT_CONVERSION = NO
diff --git a/OpenVPN Adapter Tests/OpenVPNAdapterTests.swift b/OpenVPN Adapter Tests/OpenVPNAdapterTests.swift
index 6a76093..537c8c3 100644
--- a/OpenVPN Adapter Tests/OpenVPNAdapterTests.swift
+++ b/OpenVPN Adapter Tests/OpenVPNAdapterTests.swift
@@ -12,18 +12,10 @@ import NetworkExtension
class OpenVPNAdapterTests: XCTestCase {
- enum ConfigurationType {
- case withoutCredentials, withCredentials
- }
-
enum ExpectationsType {
case connection
}
- let configurations: [ConfigurationType : String] = [
- .withoutCredentials: "free_openvpn_udp_us"
- ]
-
var expectations = [ExpectationsType : XCTestExpectation]()
override func setUp() {
@@ -35,45 +27,86 @@ class OpenVPNAdapterTests: XCTestCase {
super.tearDown()
}
- // Test connection without specifying username and password
- func testConectionWithoutCredentials() {
- let configuration = getVPNConfiguration(type: .withoutCredentials)
-
+ func testApplyConfiguration() {
let adapter = OpenVPNAdapter()
+
+ let configuration = OpenVPNConfiguration()
+ configuration.fileContent = ProfileLoader.getVPNProfile(type: .localVPNServer)
+ configuration.settings = ["auth-user-pass": ""]
+
+ let result: OpenVPNProperties
do {
- try adapter.configure(using: configuration)
+ result = try adapter.apply(configuration: configuration)
} catch {
XCTFail("Failed to configure OpenVPN adapted due to error: \(error)")
+ return
}
- expectations[.connection] = expectation(description: "me.ss-abramchuk.openvpn-adapter.connection-w/o-credentials")
+ XCTAssert(result.remoteHost == "192.168.1.200")
+ XCTAssert(result.remotePort == 1194)
+ XCTAssert(result.remoteProto == .UDP)
+ XCTAssert(result.autologin == false)
+ }
+
+ func testProvideCredentials() {
+ let adapter = OpenVPNAdapter()
+
+ let credentials = OpenVPNCredentials()
+ credentials.username = "username"
+ credentials.password = "password"
+
+ do {
+ try adapter.provide(credentials: credentials)
+ } catch {
+ XCTFail("Failed to provide credentials. \(error)")
+ return
+ }
+ }
+
+ // Test connection without specifying username and password
+ func testConection() {
+ let adapter = OpenVPNAdapter()
+
+ let configuration = OpenVPNConfiguration()
+ configuration.fileContent = ProfileLoader.getVPNProfile(type: .localVPNServer)
+ configuration.settings = ["auth-user-pass": ""]
+
+ let result: OpenVPNProperties
+ do {
+ result = try adapter.apply(configuration: configuration)
+ } catch {
+ XCTFail("Failed to configure OpenVPN adapted due to error: \(error)")
+ return
+ }
+
+ guard !result.autologin else {
+ XCTFail()
+ return
+ }
+
+ let credentials = OpenVPNCredentials()
+ credentials.username = "testuser"
+ credentials.password = "nonsecure"
+
+ do {
+ try adapter.provide(credentials: credentials)
+ } catch {
+ XCTFail("Failed to provide credentials. \(error)")
+ return
+ }
+
+ expectations[.connection] = expectation(description: "me.ss-abramchuk.openvpn-adapter.connection")
adapter.delegate = self
adapter.connect()
- waitForExpectations(timeout: 10.0) { (error) in
+ waitForExpectations(timeout: 30.0) { (error) in
adapter.disconnect()
}
}
}
-extension OpenVPNAdapterTests {
-
- func getVPNConfiguration(type: ConfigurationType) -> Data {
- guard
- let fileName = configurations[type],
- let path = Bundle.current.url(forResource: fileName, withExtension: "ovpn"),
- let configuration = try? Data(contentsOf: path)
- else {
- fatalError("Failed to retrieve OpenVPN configuration")
- }
-
- return configuration
- }
-
-}
-
extension OpenVPNAdapterTests: OpenVPNAdapterDelegate {
func configureTunnel(settings: NEPacketTunnelNetworkSettings, callback: @escaping (OpenVPNAdapterPacketFlow?) -> Void) {
@@ -95,7 +128,10 @@ extension OpenVPNAdapterTests: OpenVPNAdapterDelegate {
}
func handle(error: Error) {
-
+ if let connectionExpectation = expectations[.connection] {
+ XCTFail("Failed to establish conection. \(error.localizedDescription)")
+ connectionExpectation.fulfill()
+ }
}
func handle(logMessage: String) {
diff --git a/OpenVPN Adapter Tests/OpenVPNConfigurationTests.swift b/OpenVPN Adapter Tests/OpenVPNConfigurationTests.swift
new file mode 100644
index 0000000..dcb2aef
--- /dev/null
+++ b/OpenVPN Adapter Tests/OpenVPNConfigurationTests.swift
@@ -0,0 +1,136 @@
+//
+// OpenVPNConfigurationTests.swift
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 21.04.17.
+//
+//
+
+import XCTest
+@testable import OpenVPNAdapter
+
+// TODO: Test getting/setting of all properties of OpenVPNConfiguration
+
+class OpenVPNConfigurationTests: XCTestCase {
+
+ override func setUp() {
+ super.setUp()
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDown() {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ super.tearDown()
+ }
+
+ func testGetSetProfile() {
+ let originalProfile = ProfileLoader.getVPNProfile(type: .localVPNServer)
+
+ let configuration = OpenVPNConfiguration()
+
+ guard configuration.fileContent == nil else {
+ XCTFail("Empty file content should return nil")
+ return
+ }
+
+ configuration.fileContent = originalProfile
+
+ guard let returnedProfile = configuration.fileContent else {
+ XCTFail("Returned file content should not be nil")
+ return
+ }
+
+ XCTAssert(originalProfile.elementsEqual(returnedProfile))
+
+ configuration.fileContent = nil
+ XCTAssert(configuration.fileContent == nil, "Empty file content should return nil")
+
+ configuration.fileContent = Data()
+ XCTAssert(configuration.fileContent == nil, "Empty file content should return nil")
+ }
+
+ func testGetSetSettings() {
+ let originalSettings = [
+ "client": "",
+ "dev": "tun",
+ "remote-cert-tls" : "server"
+ ]
+
+ let configuration = OpenVPNConfiguration()
+
+ guard configuration.settings == nil else {
+ XCTFail("Empty settings should return nil")
+ return
+ }
+
+ configuration.settings = originalSettings
+
+ guard let returnedSettings = configuration.settings else {
+ XCTFail("Returned settings should not be nil")
+ return
+ }
+
+ let equals = originalSettings.elementsEqual(returnedSettings) { (first, second) -> Bool in
+ first.key == second.key && first.value == second.value
+ }
+ XCTAssert(equals)
+
+ configuration.settings = [:]
+ XCTAssert(configuration.settings == nil, "Empty settings should return nil")
+
+ configuration.settings = nil
+ XCTAssert(configuration.settings == nil, "Empty settings should return nil")
+ }
+
+ func testGetSetProto() {
+ let originalOption: OpenVPNTransportProtocol = .UDP
+
+ let configuration = OpenVPNConfiguration()
+
+ guard configuration.proto == .default else {
+ XCTFail("proto option should return default value")
+ return
+ }
+
+ configuration.proto = originalOption
+ guard configuration.proto == originalOption else {
+ XCTFail("proto option should be equal to original value (enabled)")
+ return
+ }
+ }
+
+ func testGetSetIPv6() {
+ let originalOption: OpenVPNIPv6Preference = .enabled
+
+ let configuration = OpenVPNConfiguration()
+
+ guard configuration.ipv6 == .default else {
+ XCTFail("IPv6 option should return default value")
+ return
+ }
+
+ configuration.ipv6 = originalOption
+ guard configuration.ipv6 == originalOption else {
+ XCTFail("IPv6 option should be equal to original value (enabled)")
+ return
+ }
+ }
+
+ func testGetSetTLSCertProfile() {
+ let originalOption: OpenVPNTLSCertProfile = .preferred
+
+ let configuration = OpenVPNConfiguration()
+
+ guard configuration.tlsCertProfile == .default else {
+ XCTFail("TLS Cert Profile option should return default value")
+ return
+ }
+
+ configuration.tlsCertProfile = originalOption
+ guard configuration.tlsCertProfile == originalOption else {
+ XCTFail("TLS Cert Profile option should be equal to original value (preferred)")
+ return
+ }
+ }
+
+}
diff --git a/OpenVPN Adapter Tests/ProfileLoader.swift b/OpenVPN Adapter Tests/ProfileLoader.swift
new file mode 100644
index 0000000..89fd8c2
--- /dev/null
+++ b/OpenVPN Adapter Tests/ProfileLoader.swift
@@ -0,0 +1,31 @@
+//
+// ProfileLoader.swift
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 22.04.17.
+//
+//
+
+import Foundation
+
+enum ProfileType: String {
+ case localVPNServer = "local_vpn_server"
+}
+
+struct ProfileLoader {
+
+ static func getVPNProfile(type: ProfileType) -> Data {
+ let fileName = type.rawValue
+
+ guard
+ let path = Bundle.current.url(forResource: fileName, withExtension: "ovpn"),
+ let profile = try? Data(contentsOf: path)
+ else {
+ fatalError("Failed to retrieve OpenVPN profile")
+ }
+
+ return profile
+ }
+
+}
+
diff --git a/OpenVPN Adapter Tests/Resources/free_openvpn_udp_us.ovpn b/OpenVPN Adapter Tests/Resources/free_openvpn_udp_us.ovpn
deleted file mode 100644
index 05a1332..0000000
--- a/OpenVPN Adapter Tests/Resources/free_openvpn_udp_us.ovpn
+++ /dev/null
@@ -1,99 +0,0 @@
-###############################
-# FreeOpenVPN.Org config file #
-# https://www.freeopenvpn.org #
-###############################
-dev tun
-proto udp
-remote 76.112.143.39 1302
-cipher AES-128-CBC
-auth SHA1
-resolv-retry infinite
-nobind
-persist-key
-persist-tun
-client
-verb 3
-
------BEGIN CERTIFICATE-----
-MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
-hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
-BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
-MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
-EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
-Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
-6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
-pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
-9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
-/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
-Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
-+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
-qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
-SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
-u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
-Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
-crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
-FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
-/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
-wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
-4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
-2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
-FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
-CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
-boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
-jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
-S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
-QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
-0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
-NVOFBkpdn627G190
------END CERTIFICATE-----
-
-
------BEGIN CERTIFICATE-----
-MIICxjCCAa4CAQAwDQYJKoZIhvcNAQEFBQAwKTEaMBgGA1UEAxMRVlBOR2F0ZUNs
-aWVudENlcnQxCzAJBgNVBAYTAkpQMB4XDTEzMDIxMTAzNDk0OVoXDTM3MDExOTAz
-MTQwN1owKTEaMBgGA1UEAxMRVlBOR2F0ZUNsaWVudENlcnQxCzAJBgNVBAYTAkpQ
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5h2lgQQYUjwoKYJbzVZA
-5VcIGd5otPc/qZRMt0KItCFA0s9RwReNVa9fDRFLRBhcITOlv3FBcW3E8h1Us7RD
-4W8GmJe8zapJnLsD39OSMRCzZJnczW4OCH1PZRZWKqDtjlNca9AF8a65jTmlDxCQ
-CjntLIWk5OLLVkFt9/tScc1GDtci55ofhaNAYMPiH7V8+1g66pGHXAoWK6AQVH67
-XCKJnGB5nlQ+HsMYPV/O49Ld91ZN/2tHkcaLLyNtywxVPRSsRh480jju0fcCsv6h
-p/0yXnTB//mWutBGpdUlIbwiITbAmrsbYnjigRvnPqX1RNJUbi9Fp6C2c/HIFJGD
-ywIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQChO5hgcw/4oWfoEFLu9kBa1B//kxH8
-hQkChVNn8BRC7Y0URQitPl3DKEed9URBDdg2KOAz77bb6ENPiliD+a38UJHIRMqe
-UBHhllOHIzvDhHFbaovALBQceeBzdkQxsKQESKmQmR832950UCovoyRB61UyAV7h
-+mZhYPGRKXKSJI6s0Egg/Cri+Cwk4bjJfrb5hVse11yh4D9MHhwSfCOH+0z4hPUT
-Fku7dGavURO5SVxMn/sL6En5D+oSeXkadHpDs+Airym2YHh15h0+jPSOoR6yiVp/
-6zZeZkrN43kuS73KpKDFjfFPh8t4r1gOIjttkNcQqBccusnplQ7HJpsk
------END CERTIFICATE-----
-
-
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA5h2lgQQYUjwoKYJbzVZA5VcIGd5otPc/qZRMt0KItCFA0s9R
-wReNVa9fDRFLRBhcITOlv3FBcW3E8h1Us7RD4W8GmJe8zapJnLsD39OSMRCzZJnc
-zW4OCH1PZRZWKqDtjlNca9AF8a65jTmlDxCQCjntLIWk5OLLVkFt9/tScc1GDtci
-55ofhaNAYMPiH7V8+1g66pGHXAoWK6AQVH67XCKJnGB5nlQ+HsMYPV/O49Ld91ZN
-/2tHkcaLLyNtywxVPRSsRh480jju0fcCsv6hp/0yXnTB//mWutBGpdUlIbwiITbA
-mrsbYnjigRvnPqX1RNJUbi9Fp6C2c/HIFJGDywIDAQABAoIBAERV7X5AvxA8uRiK
-k8SIpsD0dX1pJOMIwakUVyvc4EfN0DhKRNb4rYoSiEGTLyzLpyBc/A28Dlkm5eOY
-fjzXfYkGtYi/Ftxkg3O9vcrMQ4+6i+uGHaIL2rL+s4MrfO8v1xv6+Wky33EEGCou
-QiwVGRFQXnRoQ62NBCFbUNLhmXwdj1akZzLU4p5R4zA3QhdxwEIatVLt0+7owLQ3
-lP8sfXhppPOXjTqMD4QkYwzPAa8/zF7acn4kryrUP7Q6PAfd0zEVqNy9ZCZ9ffho
-zXedFj486IFoc5gnTp2N6jsnVj4LCGIhlVHlYGozKKFqJcQVGsHCqq1oz2zjW6LS
-oRYIHgECgYEA8zZrkCwNYSXJuODJ3m/hOLVxcxgJuwXoiErWd0E42vPanjjVMhnt
-KY5l8qGMJ6FhK9LYx2qCrf/E0XtUAZ2wVq3ORTyGnsMWre9tLYs55X+ZN10Tc75z
-4hacbU0hqKN1HiDmsMRY3/2NaZHoy7MKnwJJBaG48l9CCTlVwMHocIECgYEA8jby
-dGjxTH+6XHWNizb5SRbZxAnyEeJeRwTMh0gGzwGPpH/sZYGzyu0SySXWCnZh3Rgq
-5uLlNxtrXrljZlyi2nQdQgsq2YrWUs0+zgU+22uQsZpSAftmhVrtvet6MjVjbByY
-DADciEVUdJYIXk+qnFUJyeroLIkTj7WYKZ6RjksCgYBoCFIwRDeg42oK89RFmnOr
-LymNAq4+2oMhsWlVb4ejWIWeAk9nc+GXUfrXszRhS01mUnU5r5ygUvRcarV/T3U7
-TnMZ+I7Y4DgWRIDd51znhxIBtYV5j/C/t85HjqOkH+8b6RTkbchaX3mau7fpUfds
-Fq0nhIq42fhEO8srfYYwgQKBgQCyhi1N/8taRwpk+3/IDEzQwjbfdzUkWWSDk9Xs
-H/pkuRHWfTMP3flWqEYgW/LW40peW2HDq5imdV8+AgZxe/XMbaji9Lgwf1RY005n
-KxaZQz7yqHupWlLGF68DPHxkZVVSagDnV/sztWX6SFsCqFVnxIXifXGC4cW5Nm9g
-va8q4QKBgQCEhLVeUfdwKvkZ94g/GFz731Z2hrdVhgMZaU/u6t0V95+YezPNCQZB
-wmE9Mmlbq1emDeROivjCfoGhR3kZXW1pTKlLh6ZMUQUOpptdXva8XxfoqQwa3enA
-M7muBbF0XN7VO80iJPv+PmIZdEIAkpwKfi201YB+BafCIuGxIF50Vg==
------END RSA PRIVATE KEY-----
-
diff --git a/OpenVPN Adapter Tests/Resources/local_vpn_server.ovpn b/OpenVPN Adapter Tests/Resources/local_vpn_server.ovpn
new file mode 100644
index 0000000..e07238c
--- /dev/null
+++ b/OpenVPN Adapter Tests/Resources/local_vpn_server.ovpn
@@ -0,0 +1,89 @@
+dev tun
+proto udp
+remote 192.168.1.200 1194
+cipher AES-256-CBC
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+client
+verb 3
+
+-----BEGIN CERTIFICATE-----
+MIIDpjCCAo6gAwIBAgIBADANBgkqhkiG9w0BAQsFADBSMRUwEwYDVQQDEww5ZTQ3
+NThlOTVlZTIxFTATBgNVBAoTDDllNDc1OGU5NWVlMjEVMBMGA1UECxMMOWU0NzU4
+ZTk1ZWUyMQswCQYDVQQGEwJVUzAeFw0xNzA0MjgxODU3MjhaFw0zNzEyMzExODU3
+MjhaMFIxFTATBgNVBAMTDDllNDc1OGU5NWVlMjEVMBMGA1UEChMMOWU0NzU4ZTk1
+ZWUyMRUwEwYDVQQLEww5ZTQ3NThlOTVlZTIxCzAJBgNVBAYTAlVTMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3ecfScl3JGwRhbmHgIrNx7LItVyTX9V3
+CSZOjBOZymXIKt7/vNt9w6suebtK64/YCRAyPsUbvqUwYqfZhd6jngua/917LrnO
+SKHMrGtwDLfnxKY3WTPl1tI5GlrojgF2Z3wCgzRr/+KkFAk8Fq2iffJDRi2Iptqn
+5PlOosGfpA1fQKYsedKx7DAXbwTvXPbE/tJ0m8WfdiHIUkWWrNxAFOuctWLk+oBi
+vAmlb3/GSctXEIcVPHdF5AKU/GR5AjY1Qqde4LcMS+54YV+g/rpFYNUFsySNSvLQ
+Lxg3zZ79HAd9DMwYSt47MP9pih8dT2jdt7df6y+/RXq32B6SoqrYPwIDAQABo4GG
+MIGDMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgH2MGMGA1UdJQRcMFoGCCsG
+AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDBQYI
+KwYBBQUHAwYGCCsGAQUFBwMHBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcN
+AQELBQADggEBAKnWRxFiKPR7mhbH+JKg8uxu1ONe8TpBygMw6B0XM0WXFY0byTnK
+7IX1X1TzIeJNaeDiBKvrm8o4SJGXy8qC1DM+tFAlcRCwwBl5Yi89TcbLup0SSYnw
+QEJQ169+u1WNS6H14ED2p0Um8kslRXqSC04yLjImy3Sr4d52h1TQNjkpSGKggBbN
+L6YR29j8LX+3ls+Jx5e+allaw6v9Dft+jjsPEZE6KznhtQa6Zyw6Afk44yPLWjne
+ShcnY1Au3meaU98Q/S891i7o1tEFUKNBy+n4Qu3J/BnK77NPw1g7FJOcOD0JZIUq
+XtjqsiTviTpsUFcwp/Bl3BTXT0b6BwKi978=
+-----END CERTIFICATE-----
+
+
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQsFADBnMRwwGgYDVQQDExM2OTg1
+MzIwMzIwNzkwNTYyMDkzMRwwGgYDVQQKExM2OTg1MzIwMzIwNzkwNTYyMDkzMRww
+GgYDVQQLExM2OTg1MzIwMzIwNzkwNTYyMDkzMQswCQYDVQQGEwJVUzAeFw0xNzA0
+MjgxODU3MzFaFw0zNzEyMzExODU3MzFaMGcxHDAaBgNVBAMTEzY5ODUzMjAzMjA3
+OTA1NjIwOTMxHDAaBgNVBAoTEzY5ODUzMjAzMjA3OTA1NjIwOTMxHDAaBgNVBAsT
+EzY5ODUzMjAzMjA3OTA1NjIwOTMxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAx9oRmlK91IFxB3WWjrRJkR8l4csle9EmrH+6r6US
+Utq/Ik9SctVZz7n8L5IrJc1/hpPvdSyD8uq3lI0U9/h0eDca5pKy0b9Oe4qS75wv
+JFkebg/5V2grRL9//125ux/2zytOPG3WIQF0p2NT4Y4OSOPG0RCdQRd2pZBS1sIu
+AMO+jRZGlrLxc+QyokR64wlkTHnv3dWJBUm8iuVaQpr5X22a5urCPk3H79zRPJuO
+1u74a0AaMRREzAp9F547VghvMWKxd6y38jOVteSQyB6E4c/T7rnO0MWk8GPO3JEj
+qNQ/9N0OE9kVWNuKVQf6UHV2cknyfHyg9Va0IgWvRoLt7QIDAQABo4GGMIGDMA8G
+A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgH2MGMGA1UdJQRcMFoGCCsGAQUFBwMB
+BggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDBQYIKwYBBQUH
+AwYGCCsGAQUFBwMHBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQELBQAD
+ggEBAFZZJLTP84lo46eZkaRfvXiv0qKO2FHHTSJtrHl7C6mR9ffZzp6nTd0EPB6T
+AkQZong8LqjcDmTk+3JGTHDSdy+5E6TkDTp1oiOoVApxRd13TIFmxpPslBczyHwt
+u5MrWNMMk+urGHK4tm/TBCm13AQAv20CQBsI+s+3pW3blcUpD7HbZvahZgNg978h
+g/y5hFtffBJbCEzJpYV9bvh7tyI0ndhyxB6ew93jfaGukDtIbpTjLTD1qvmnaGvW
+dEY8VmtmQ7gKuSMvfkW7ClN0XxTfDwkT8jxADF4P9RGHeUW2AUwMKw2dV2LbX933
+BNZuIgS6Lcaxso+R20VwQnefPvM=
+-----END CERTIFICATE-----
+
+
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDH2hGaUr3UgXEH
+dZaOtEmRHyXhyyV70Sasf7qvpRJS2r8iT1Jy1VnPufwvkislzX+Gk+91LIPy6reU
+jRT3+HR4NxrmkrLRv057ipLvnC8kWR5uD/lXaCtEv3//Xbm7H/bPK048bdYhAXSn
+Y1Phjg5I48bREJ1BF3alkFLWwi4Aw76NFkaWsvFz5DKiRHrjCWRMee/d1YkFSbyK
+5VpCmvlfbZrm6sI+Tcfv3NE8m47W7vhrQBoxFETMCn0XnjtWCG8xYrF3rLfyM5W1
+5JDIHoThz9Puuc7QxaTwY87ckSOo1D/03Q4T2RVY24pVB/pQdXZySfJ8fKD1VrQi
+Ba9Ggu3tAgMBAAECggEAU6V8FKFo/pam3j5jI5tl5y2oR1cleytRCoXzdyyZ/L+9
+m/ijQ5j0nDL10FtXX90g8Qzd/qcBGx0OdUiPbDI7XU2DHtprqcpuaNrZIRy3xnje
+eaaJ8AGTipS0WAe8gwuf25n+huBZ7TqUvrKeGxu/8tYTEtHnX6UYbbd4VJa1dm+5
+16LfueOIricLu5JJ7TFLls4kFY6R//cFu6wzmlHwYvU7xsTQg8yWReojCifyvPqW
+yvF/MARb+1XWGCWKfT9B/A64uy8a4vqT52JHoG53t35luAjtHni65r+HDdiEf2Ph
++gvpH/g0bOBBDFLQe5j1CdZr1PdzBNv9a1rxVVVgAQKBgQDoyKM9pTbNjmMPSb64
+3SsbBpF8M4JuIVg2qmu+xs25CoRKT+S6sMnnY/2uLzvYeUQWAQRPCqjL6jYWoLyZ
+AwDAl3uvAGG6LNuMqscSkDfO5hpr2y+fXRyh1+vTl9Fau3ZCSlCwJy/wBIfKbls9
+4Y0aLBlaS4AivMh9dSJe7e9MAQKBgQDbyJ+wcS8QcyRtOAZ7MQMRqsLjXRk6E2aY
+1a/WhLDfcsew56dh6F6VGE75DTvnOVmw19+HHj+bmmqbwU4Ook46E+BIWeonK6yZ
+8hBq6VFYutNaiid9MzV+90u1VYPT1C7/H28WkQ5F2obzSEdpQUs+z/Kb2wTRbgEx
+ECYTGe2R7QKBgF3Do21LRR3bQq9/xuDzxU8ngCaFIP53U+8BClFYBrmIMO017S39
+0/XuYtpskDCL+A7c7f1gj8lDV/IZYJ5JhV4OJnXBM5woQW8RwwoJKVGfgfj72tzY
+RpYyQP2D44ImjGX7RTEPN9H4ITI67Wmplop6ROQIEV7sp91Q9z1BnegBAoGAHMU3
+ej5mvc2E0DNMTeYNk8t5tY+jVMHjZVBbs0YtbSK2V0cL1zo232eONvXviIYuYoLv
+xN1F0FW3bOoyEKJYgSvG6VGz4CrMbl6MnaIrPuU985UwNCh28UboBzXJivo0qLrx
+rM+SQbyoe8JTbsjYU8Ge7Z4PFGdFCqolgcycF8UCgYBEVR50Ze1j8XK8oyySePqn
+YN1/CPQHkMv4Z9J511uDOw+rZpo8BtZX19jj4MWpFtcR7EAj4OyCe8gdn7YRv/n9
+Hw+zm4o54mkL4tgWg0/9jt0eCR3j3Ph03mTlkqwE/PPXaRIb1E8EmEYSwT0hDzjc
+Wb3dqIAxzkHucnvInG+TEw==
+-----END PRIVATE KEY-----
+
diff --git a/OpenVPN Adapter.xcodeproj/project.pbxproj b/OpenVPN Adapter.xcodeproj/project.pbxproj
index c4dcca2..9b1786e 100644
--- a/OpenVPN Adapter.xcodeproj/project.pbxproj
+++ b/OpenVPN Adapter.xcodeproj/project.pbxproj
@@ -9,13 +9,67 @@
/* Begin PBXBuildFile section */
C90BAD311E73FF6C00DEFB32 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C90BAD301E73FF6C00DEFB32 /* SystemConfiguration.framework */; };
C912BB251E7C3339002B9414 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C912BB241E7C3339002B9414 /* NetworkExtension.framework */; };
- C99E2FF01EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = C99E2FEF1EA7E20700A6518B /* free_openvpn_udp_us.ovpn */; };
- C99E2FF11EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = C99E2FEF1EA7E20700A6518B /* free_openvpn_udp_us.ovpn */; };
+ C93779D51EAE32670030A362 /* OpenVPNCredentials.h in Headers */ = {isa = PBXBuildFile; fileRef = C93779D31EAE32670030A362 /* OpenVPNCredentials.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C93779D61EAE32670030A362 /* OpenVPNCredentials.h in Headers */ = {isa = PBXBuildFile; fileRef = C93779D31EAE32670030A362 /* OpenVPNCredentials.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C93779D71EAE32670030A362 /* OpenVPNCredentials.mm in Sources */ = {isa = PBXBuildFile; fileRef = C93779D41EAE32670030A362 /* OpenVPNCredentials.mm */; };
+ C93779D81EAE32670030A362 /* OpenVPNCredentials.mm in Sources */ = {isa = PBXBuildFile; fileRef = C93779D41EAE32670030A362 /* OpenVPNCredentials.mm */; };
+ C93779DB1EAE32880030A362 /* OpenVPNCredentials+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C93779D91EAE32880030A362 /* OpenVPNCredentials+Internal.h */; };
+ C93779DC1EAE32880030A362 /* OpenVPNCredentials+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C93779D91EAE32880030A362 /* OpenVPNCredentials+Internal.h */; };
+ C94605E91EAA656B00971516 /* OpenVPNConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */; };
+ C94605EA1EAA65F200971516 /* OpenVPNConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */; };
+ C9657A171EB0A7F800EFF210 /* OpenVPNConnectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A151EB0A7F800EFF210 /* OpenVPNConnectionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A181EB0A7F800EFF210 /* OpenVPNConnectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A151EB0A7F800EFF210 /* OpenVPNConnectionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A1D1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A1B1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h */; };
+ C9657A1E1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A1B1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h */; };
+ C9657A211EB0ACAE00EFF210 /* OpenVPNConnectionInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A161EB0A7F800EFF210 /* OpenVPNConnectionInfo.mm */; };
+ C9657A221EB0ACAE00EFF210 /* OpenVPNConnectionInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A161EB0A7F800EFF210 /* OpenVPNConnectionInfo.mm */; };
+ C9657A251EB0B60200EFF210 /* OpenVPNTransportStats.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A231EB0B60200EFF210 /* OpenVPNTransportStats.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A261EB0B60200EFF210 /* OpenVPNTransportStats.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A231EB0B60200EFF210 /* OpenVPNTransportStats.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A2B1EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A291EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h */; };
+ C9657A2F1EB0B79500EFF210 /* OpenVPNTransportStats+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A291EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h */; };
+ C9657A301EB0B7A600EFF210 /* OpenVPNTransportStats.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A241EB0B60200EFF210 /* OpenVPNTransportStats.mm */; };
+ C9657A311EB0B7A900EFF210 /* OpenVPNTransportStats.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A241EB0B60200EFF210 /* OpenVPNTransportStats.mm */; };
+ C9657A341EB0BA3900EFF210 /* OpenVPNInterfaceStats.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A321EB0BA3900EFF210 /* OpenVPNInterfaceStats.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A351EB0BA3900EFF210 /* OpenVPNInterfaceStats.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A321EB0BA3900EFF210 /* OpenVPNInterfaceStats.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A361EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A331EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm */; };
+ C9657A371EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A331EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm */; };
+ C9657A3A1EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A381EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h */; };
+ C9657A3B1EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A381EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h */; };
+ C9657A401EB0CAC200EFF210 /* OpenVPNServerEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A3E1EB0CAC200EFF210 /* OpenVPNServerEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A411EB0CAC200EFF210 /* OpenVPNServerEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A3E1EB0CAC200EFF210 /* OpenVPNServerEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A421EB0CAC200EFF210 /* OpenVPNServerEntry.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A3F1EB0CAC200EFF210 /* OpenVPNServerEntry.mm */; };
+ C9657A431EB0CAC200EFF210 /* OpenVPNServerEntry.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A3F1EB0CAC200EFF210 /* OpenVPNServerEntry.mm */; };
+ C9657A461EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A441EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h */; };
+ C9657A471EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A441EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h */; };
+ C9657A4C1EB0CD6C00EFF210 /* OpenVPNProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A4A1EB0CD6C00EFF210 /* OpenVPNProperties.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A4D1EB0CD6C00EFF210 /* OpenVPNProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A4A1EB0CD6C00EFF210 /* OpenVPNProperties.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A561EB0CDFA00EFF210 /* OpenVPNProperties+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A501EB0CD9200EFF210 /* OpenVPNProperties+Internal.h */; };
+ C9657A571EB0CDFB00EFF210 /* OpenVPNProperties+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A501EB0CD9200EFF210 /* OpenVPNProperties+Internal.h */; };
+ C9657A581EB0CE1300EFF210 /* OpenVPNProperties.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A4B1EB0CD6C00EFF210 /* OpenVPNProperties.mm */; };
+ C9657A591EB0CE1400EFF210 /* OpenVPNProperties.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9657A4B1EB0CD6C00EFF210 /* OpenVPNProperties.mm */; };
+ C9657A5E1EB0D60700EFF210 /* OpenVPNTransportProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A5D1EB0D60700EFF210 /* OpenVPNTransportProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A5F1EB0D60700EFF210 /* OpenVPNTransportProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A5D1EB0D60700EFF210 /* OpenVPNTransportProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A611EB0D64E00EFF210 /* OpenVPNIPv6Preference.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A601EB0D64E00EFF210 /* OpenVPNIPv6Preference.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A621EB0D64E00EFF210 /* OpenVPNIPv6Preference.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A601EB0D64E00EFF210 /* OpenVPNIPv6Preference.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A641EB0D6C200EFF210 /* OpenVPNCompressionMode.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A631EB0D6AD00EFF210 /* OpenVPNCompressionMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A651EB0D6C200EFF210 /* OpenVPNCompressionMode.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A631EB0D6AD00EFF210 /* OpenVPNCompressionMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A671EB0D73200EFF210 /* OpenVPNMinTLSVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A661EB0D73200EFF210 /* OpenVPNMinTLSVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A681EB0D73200EFF210 /* OpenVPNMinTLSVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A661EB0D73200EFF210 /* OpenVPNMinTLSVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A6A1EB0D75700EFF210 /* OpenVPNTLSCertProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A691EB0D75700EFF210 /* OpenVPNTLSCertProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9657A6B1EB0D75700EFF210 /* OpenVPNTLSCertProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = C9657A691EB0D75700EFF210 /* OpenVPNTLSCertProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C98467A21EAA559B00272A9A /* local_vpn_server.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */; };
+ C98467A31EAA559B00272A9A /* local_vpn_server.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */; };
+ C98467A61EAA5B7700272A9A /* OpenVPNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C98467A41EAA5B7700272A9A /* OpenVPNConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C98467A71EAA5B7700272A9A /* OpenVPNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C98467A41EAA5B7700272A9A /* OpenVPNConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C98467A81EAA5B7700272A9A /* OpenVPNConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = C98467A51EAA5B7700272A9A /* OpenVPNConfiguration.mm */; };
+ C98467A91EAA5B7700272A9A /* OpenVPNConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = C98467A51EAA5B7700272A9A /* OpenVPNConfiguration.mm */; };
+ C98467AB1EAA5BE100272A9A /* OpenVPNConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C98467AA1EAA5BB500272A9A /* OpenVPNConfiguration+Internal.h */; };
+ C98467AC1EAA5BE200272A9A /* OpenVPNConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C98467AA1EAA5BB500272A9A /* OpenVPNConfiguration+Internal.h */; };
+ C9B03A7C1EABA82200268B85 /* ProfileLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B03A7A1EABA6B500268B85 /* ProfileLoader.swift */; };
+ C9B03A7D1EABA82300268B85 /* ProfileLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B03A7A1EABA6B500268B85 /* ProfileLoader.swift */; };
C9BB47601E71663A00F3F98C /* Umbrella-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB475E1E71663A00F3F98C /* Umbrella-Header.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9BB47711E7171A100F3F98C /* OpenVPNError.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB476F1E7171A100F3F98C /* OpenVPNError.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9BB47721E7171A100F3F98C /* OpenVPNEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */; settings = {ATTRIBUTES = (Public, ); }; };
- C9BB47751E7171D900F3F98C /* TUNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47731E7171D900F3F98C /* TUNConfiguration.h */; };
- C9BB47761E7171D900F3F98C /* TUNConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47741E7171D900F3F98C /* TUNConfiguration.m */; };
C9BB47791E7171ED00F3F98C /* OpenVPNClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */; };
C9BB477A1E7171ED00F3F98C /* OpenVPNClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */; };
C9BB477F1E7173C700F3F98C /* OpenVPNAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB477B1E7173C700F3F98C /* OpenVPNAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -25,9 +79,18 @@
C9BB47911E71821A00F3F98C /* OpenVPNAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */; };
C9BB47931E71821A00F3F98C /* OpenVPNAdapter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9BB475C1E71663A00F3F98C /* OpenVPNAdapter.framework */; };
C9BB47A21E7183DB00F3F98C /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47A11E7183DB00F3F98C /* Bundle.swift */; };
+ C9BCE2581EB3C0D9009D6AC1 /* OpenVPNSessionToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BCE2561EB3C0D9009D6AC1 /* OpenVPNSessionToken.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9BCE2591EB3C0D9009D6AC1 /* OpenVPNSessionToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BCE2561EB3C0D9009D6AC1 /* OpenVPNSessionToken.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ C9BCE25A1EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9BCE2571EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm */; };
+ C9BCE25B1EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9BCE2571EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm */; };
+ C9BCE25E1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BCE25C1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h */; };
+ C9BCE25F1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BCE25C1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h */; };
+ C9BDB1351EBCC3B900C204FF /* TUNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BDB1331EBCC3B900C204FF /* TUNConfiguration.h */; };
+ C9BDB1361EBCC3B900C204FF /* TUNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BDB1331EBCC3B900C204FF /* TUNConfiguration.h */; };
+ C9BDB1371EBCC3B900C204FF /* TUNConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = C9BDB1341EBCC3B900C204FF /* TUNConfiguration.m */; };
+ C9BDB1381EBCC3B900C204FF /* TUNConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = C9BDB1341EBCC3B900C204FF /* TUNConfiguration.m */; };
C9D2ABDB1EA20F99007EDF9D /* OpenVPNAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9BB477E1E7173C700F3F98C /* OpenVPNAdapter.mm */; };
C9D2ABDC1EA20F99007EDF9D /* OpenVPNClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */; };
- C9D2ABDD1EA20F99007EDF9D /* TUNConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47741E7171D900F3F98C /* TUNConfiguration.m */; };
C9D2ABDE1EA20F99007EDF9D /* ovpncli.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9FD92191E9A667600374FC4 /* ovpncli.cpp */; };
C9D2ABE01EA20F99007EDF9D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C912BB241E7C3339002B9414 /* NetworkExtension.framework */; };
C9D2ABE11EA20F99007EDF9D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C90BAD301E73FF6C00DEFB32 /* SystemConfiguration.framework */; };
@@ -39,7 +102,6 @@
C9D2ABE81EA20F99007EDF9D /* OpenVPNError.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB476F1E7171A100F3F98C /* OpenVPNError.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9D2ABE91EA20F99007EDF9D /* OpenVPNAdapter+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB477C1E7173C700F3F98C /* OpenVPNAdapter+Internal.h */; };
C9D2ABEA1EA20F99007EDF9D /* ovpncli.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C9FD92181E9A667600374FC4 /* ovpncli.hpp */; };
- C9D2ABEB1EA20F99007EDF9D /* TUNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47731E7171D900F3F98C /* TUNConfiguration.h */; };
C9D2ABF61EA212A3007EDF9D /* OpenVPNAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */; };
C9D2ABF71EA212A3007EDF9D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47A11E7183DB00F3F98C /* Bundle.swift */; };
C9D2AC051EA214EA007EDF9D /* OpenVPNAdapter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D2ABF01EA20F99007EDF9D /* OpenVPNAdapter.framework */; };
@@ -74,13 +136,39 @@
C90BAD2F1E73FA7400DEFB32 /* Tests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Tests.xcconfig; sourceTree = ""; };
C90BAD301E73FF6C00DEFB32 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
C912BB241E7C3339002B9414 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
- C99E2FEF1EA7E20700A6518B /* free_openvpn_udp_us.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = free_openvpn_udp_us.ovpn; sourceTree = ""; };
+ C93779D31EAE32670030A362 /* OpenVPNCredentials.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNCredentials.h; sourceTree = ""; };
+ C93779D41EAE32670030A362 /* OpenVPNCredentials.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNCredentials.mm; sourceTree = ""; };
+ C93779D91EAE32880030A362 /* OpenVPNCredentials+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNCredentials+Internal.h"; sourceTree = ""; };
+ C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenVPNConfigurationTests.swift; sourceTree = ""; };
+ C9657A151EB0A7F800EFF210 /* OpenVPNConnectionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNConnectionInfo.h; sourceTree = ""; };
+ C9657A161EB0A7F800EFF210 /* OpenVPNConnectionInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNConnectionInfo.mm; sourceTree = ""; };
+ C9657A1B1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNConnectionInfo+Internal.h"; sourceTree = ""; };
+ C9657A231EB0B60200EFF210 /* OpenVPNTransportStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTransportStats.h; sourceTree = ""; };
+ C9657A241EB0B60200EFF210 /* OpenVPNTransportStats.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNTransportStats.mm; sourceTree = ""; };
+ C9657A291EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNTransportStats+Internal.h"; sourceTree = ""; };
+ C9657A321EB0BA3900EFF210 /* OpenVPNInterfaceStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNInterfaceStats.h; sourceTree = ""; };
+ C9657A331EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNInterfaceStats.mm; sourceTree = ""; };
+ C9657A381EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNInterfaceStats+Internal.h"; sourceTree = ""; };
+ C9657A3E1EB0CAC200EFF210 /* OpenVPNServerEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNServerEntry.h; sourceTree = ""; };
+ C9657A3F1EB0CAC200EFF210 /* OpenVPNServerEntry.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNServerEntry.mm; sourceTree = ""; };
+ C9657A441EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNServerEntry+Internal.h"; sourceTree = ""; };
+ C9657A4A1EB0CD6C00EFF210 /* OpenVPNProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNProperties.h; sourceTree = ""; };
+ C9657A4B1EB0CD6C00EFF210 /* OpenVPNProperties.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNProperties.mm; sourceTree = ""; };
+ C9657A501EB0CD9200EFF210 /* OpenVPNProperties+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNProperties+Internal.h"; sourceTree = ""; };
+ C9657A5D1EB0D60700EFF210 /* OpenVPNTransportProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTransportProtocol.h; sourceTree = ""; };
+ C9657A601EB0D64E00EFF210 /* OpenVPNIPv6Preference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNIPv6Preference.h; sourceTree = ""; };
+ C9657A631EB0D6AD00EFF210 /* OpenVPNCompressionMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenVPNCompressionMode.h; sourceTree = ""; };
+ C9657A661EB0D73200EFF210 /* OpenVPNMinTLSVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNMinTLSVersion.h; sourceTree = ""; };
+ C9657A691EB0D75700EFF210 /* OpenVPNTLSCertProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTLSCertProfile.h; sourceTree = ""; };
+ C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = local_vpn_server.ovpn; sourceTree = ""; };
+ C98467A41EAA5B7700272A9A /* OpenVPNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNConfiguration.h; sourceTree = ""; };
+ C98467A51EAA5B7700272A9A /* OpenVPNConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNConfiguration.mm; sourceTree = ""; };
+ C98467AA1EAA5BB500272A9A /* OpenVPNConfiguration+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenVPNConfiguration+Internal.h"; sourceTree = ""; };
+ C9B03A7A1EABA6B500268B85 /* ProfileLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileLoader.swift; sourceTree = ""; };
C9BB475C1E71663A00F3F98C /* OpenVPNAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenVPNAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C9BB475E1E71663A00F3F98C /* Umbrella-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Umbrella-Header.h"; sourceTree = ""; };
C9BB476F1E7171A100F3F98C /* OpenVPNError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = OpenVPNError.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNEvent.h; sourceTree = ""; };
- C9BB47731E7171D900F3F98C /* TUNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNConfiguration.h; sourceTree = ""; };
- C9BB47741E7171D900F3F98C /* TUNConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNConfiguration.m; sourceTree = ""; };
C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNClient.h; sourceTree = ""; };
C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNClient.mm; sourceTree = ""; };
C9BB477B1E7173C700F3F98C /* OpenVPNAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNAdapter.h; sourceTree = ""; };
@@ -90,6 +178,11 @@
C9BB478E1E71821A00F3F98C /* OpenVPN Adapter iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OpenVPN Adapter iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNAdapterTests.swift; sourceTree = ""; };
C9BB47A11E7183DB00F3F98C /* Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = ""; };
+ C9BCE2561EB3C0D9009D6AC1 /* OpenVPNSessionToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNSessionToken.h; sourceTree = ""; };
+ C9BCE2571EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNSessionToken.mm; sourceTree = ""; };
+ C9BCE25C1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNSessionToken+Internal.h"; sourceTree = ""; };
+ C9BDB1331EBCC3B900C204FF /* TUNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNConfiguration.h; sourceTree = ""; };
+ C9BDB1341EBCC3B900C204FF /* TUNConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNConfiguration.m; sourceTree = ""; };
C9D2ABF01EA20F99007EDF9D /* OpenVPNAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenVPNAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C9D2ABFF1EA212A3007EDF9D /* OpenVPN Adapter macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OpenVPN Adapter macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
C9FD92181E9A667600374FC4 /* ovpncli.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ovpncli.hpp; path = Vendors/openvpn/client/ovpncli.hpp; sourceTree = ""; };
@@ -179,9 +272,75 @@
name = Frameworks;
sourceTree = "";
};
+ C9235AC41EB24F0100C7D303 /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ C9BDB1331EBCC3B900C204FF /* TUNConfiguration.h */,
+ C9BDB1341EBCC3B900C204FF /* TUNConfiguration.m */,
+ C98467A41EAA5B7700272A9A /* OpenVPNConfiguration.h */,
+ C98467AA1EAA5BB500272A9A /* OpenVPNConfiguration+Internal.h */,
+ C98467A51EAA5B7700272A9A /* OpenVPNConfiguration.mm */,
+ C93779D31EAE32670030A362 /* OpenVPNCredentials.h */,
+ C93779D91EAE32880030A362 /* OpenVPNCredentials+Internal.h */,
+ C93779D41EAE32670030A362 /* OpenVPNCredentials.mm */,
+ C9657A3E1EB0CAC200EFF210 /* OpenVPNServerEntry.h */,
+ C9657A441EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h */,
+ C9657A3F1EB0CAC200EFF210 /* OpenVPNServerEntry.mm */,
+ C9657A4A1EB0CD6C00EFF210 /* OpenVPNProperties.h */,
+ C9657A501EB0CD9200EFF210 /* OpenVPNProperties+Internal.h */,
+ C9657A4B1EB0CD6C00EFF210 /* OpenVPNProperties.mm */,
+ );
+ name = Configuration;
+ sourceTree = "";
+ };
+ C9235AC51EB24F1100C7D303 /* Stats and Info */ = {
+ isa = PBXGroup;
+ children = (
+ C9657A151EB0A7F800EFF210 /* OpenVPNConnectionInfo.h */,
+ C9657A1B1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h */,
+ C9657A161EB0A7F800EFF210 /* OpenVPNConnectionInfo.mm */,
+ C9BCE2561EB3C0D9009D6AC1 /* OpenVPNSessionToken.h */,
+ C9BCE25C1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h */,
+ C9BCE2571EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm */,
+ C9657A231EB0B60200EFF210 /* OpenVPNTransportStats.h */,
+ C9657A291EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h */,
+ C9657A241EB0B60200EFF210 /* OpenVPNTransportStats.mm */,
+ C9657A321EB0BA3900EFF210 /* OpenVPNInterfaceStats.h */,
+ C9657A381EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h */,
+ C9657A331EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm */,
+ );
+ name = "Stats and Info";
+ sourceTree = "";
+ };
+ C9235AC61EB24F2A00C7D303 /* Enums and Constants */ = {
+ isa = PBXGroup;
+ children = (
+ C9BB476F1E7171A100F3F98C /* OpenVPNError.h */,
+ C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */,
+ C9657A5D1EB0D60700EFF210 /* OpenVPNTransportProtocol.h */,
+ C9657A601EB0D64E00EFF210 /* OpenVPNIPv6Preference.h */,
+ C9657A631EB0D6AD00EFF210 /* OpenVPNCompressionMode.h */,
+ C9657A661EB0D73200EFF210 /* OpenVPNMinTLSVersion.h */,
+ C9657A691EB0D75700EFF210 /* OpenVPNTLSCertProfile.h */,
+ );
+ name = "Enums and Constants";
+ sourceTree = "";
+ };
+ C9B376B71EA53CE700B7F423 /* Client */ = {
+ isa = PBXGroup;
+ children = (
+ C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */,
+ C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */,
+ );
+ name = Client;
+ sourceTree = "";
+ };
C9BB475D1E71663A00F3F98C /* OpenVPN Adapter */ = {
isa = PBXGroup;
children = (
+ C9235AC41EB24F0100C7D303 /* Configuration */,
+ C9235AC51EB24F1100C7D303 /* Stats and Info */,
+ C9B376B71EA53CE700B7F423 /* Client */,
C9BB47671E7169F000F3F98C /* Adapter */,
C9BB47641E7169AF00F3F98C /* Libraries */,
C9BB47651E7169B700F3F98C /* Framework */,
@@ -192,6 +351,7 @@
C9BB47641E7169AF00F3F98C /* Libraries */ = {
isa = PBXGroup;
children = (
+ C9FF73B71EB7421600E995AC /* Helpers */,
C9BB47681E716ABF00F3F98C /* Vendors */,
);
name = Libraries;
@@ -208,12 +368,6 @@
C9BB47671E7169F000F3F98C /* Adapter */ = {
isa = PBXGroup;
children = (
- C9BB476F1E7171A100F3F98C /* OpenVPNError.h */,
- C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */,
- C9BB47731E7171D900F3F98C /* TUNConfiguration.h */,
- C9BB47741E7171D900F3F98C /* TUNConfiguration.m */,
- C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */,
- C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */,
C9BB477B1E7173C700F3F98C /* OpenVPNAdapter.h */,
C9BB477C1E7173C700F3F98C /* OpenVPNAdapter+Internal.h */,
C9BB477D1E7173C700F3F98C /* OpenVPNAdapter+Public.h */,
@@ -252,7 +406,7 @@
C9BB479A1E71836100F3F98C /* Resources */ = {
isa = PBXGroup;
children = (
- C99E2FEF1EA7E20700A6518B /* free_openvpn_udp_us.ovpn */,
+ C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */,
);
path = Resources;
sourceTree = "";
@@ -260,6 +414,7 @@
C9BB479D1E71837200F3F98C /* Adapter Tests */ = {
isa = PBXGroup;
children = (
+ C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */,
C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */,
);
name = "Adapter Tests";
@@ -285,10 +440,19 @@
isa = PBXGroup;
children = (
C9BB47A11E7183DB00F3F98C /* Bundle.swift */,
+ C9B03A7A1EABA6B500268B85 /* ProfileLoader.swift */,
);
name = Utils;
sourceTree = "";
};
+ C9FF73B71EB7421600E995AC /* Helpers */ = {
+ isa = PBXGroup;
+ children = (
+ C9235AC61EB24F2A00C7D303 /* Enums and Constants */,
+ );
+ name = Helpers;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -297,14 +461,35 @@
buildActionMask = 2147483647;
files = (
C9BB47791E7171ED00F3F98C /* OpenVPNClient.h in Headers */,
+ C9657A3A1EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h in Headers */,
+ C9BCE25E1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h in Headers */,
C9BB47721E7171A100F3F98C /* OpenVPNEvent.h in Headers */,
C9BB477F1E7173C700F3F98C /* OpenVPNAdapter.h in Headers */,
+ C9657A4C1EB0CD6C00EFF210 /* OpenVPNProperties.h in Headers */,
+ C9657A571EB0CDFB00EFF210 /* OpenVPNProperties+Internal.h in Headers */,
+ C9BCE2581EB3C0D9009D6AC1 /* OpenVPNSessionToken.h in Headers */,
+ C9657A341EB0BA3900EFF210 /* OpenVPNInterfaceStats.h in Headers */,
+ C9BDB1351EBCC3B900C204FF /* TUNConfiguration.h in Headers */,
+ C9657A401EB0CAC200EFF210 /* OpenVPNServerEntry.h in Headers */,
+ C98467AB1EAA5BE100272A9A /* OpenVPNConfiguration+Internal.h in Headers */,
+ C98467A61EAA5B7700272A9A /* OpenVPNConfiguration.h in Headers */,
+ C9657A2B1EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h in Headers */,
C9BB47601E71663A00F3F98C /* Umbrella-Header.h in Headers */,
+ C9657A5E1EB0D60700EFF210 /* OpenVPNTransportProtocol.h in Headers */,
+ C9657A1D1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h in Headers */,
+ C9657A171EB0A7F800EFF210 /* OpenVPNConnectionInfo.h in Headers */,
C9BB47811E7173C700F3F98C /* OpenVPNAdapter+Public.h in Headers */,
C9BB47711E7171A100F3F98C /* OpenVPNError.h in Headers */,
C9BB47801E7173C700F3F98C /* OpenVPNAdapter+Internal.h in Headers */,
+ C9657A611EB0D64E00EFF210 /* OpenVPNIPv6Preference.h in Headers */,
+ C9657A671EB0D73200EFF210 /* OpenVPNMinTLSVersion.h in Headers */,
+ C93779D51EAE32670030A362 /* OpenVPNCredentials.h in Headers */,
+ C9657A641EB0D6C200EFF210 /* OpenVPNCompressionMode.h in Headers */,
C9FD921A1E9A667600374FC4 /* ovpncli.hpp in Headers */,
- C9BB47751E7171D900F3F98C /* TUNConfiguration.h in Headers */,
+ C93779DB1EAE32880030A362 /* OpenVPNCredentials+Internal.h in Headers */,
+ C9657A6A1EB0D75700EFF210 /* OpenVPNTLSCertProfile.h in Headers */,
+ C9657A461EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h in Headers */,
+ C9657A251EB0B60200EFF210 /* OpenVPNTransportStats.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -313,14 +498,35 @@
buildActionMask = 2147483647;
files = (
C9D2ABE31EA20F99007EDF9D /* OpenVPNClient.h in Headers */,
+ C9657A3B1EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h in Headers */,
+ C9BCE25F1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h in Headers */,
C9D2ABE41EA20F99007EDF9D /* OpenVPNEvent.h in Headers */,
C9D2ABE51EA20F99007EDF9D /* OpenVPNAdapter.h in Headers */,
+ C9657A4D1EB0CD6C00EFF210 /* OpenVPNProperties.h in Headers */,
+ C9657A561EB0CDFA00EFF210 /* OpenVPNProperties+Internal.h in Headers */,
+ C9BCE2591EB3C0D9009D6AC1 /* OpenVPNSessionToken.h in Headers */,
+ C9657A351EB0BA3900EFF210 /* OpenVPNInterfaceStats.h in Headers */,
+ C9BDB1361EBCC3B900C204FF /* TUNConfiguration.h in Headers */,
+ C9657A411EB0CAC200EFF210 /* OpenVPNServerEntry.h in Headers */,
+ C98467AC1EAA5BE200272A9A /* OpenVPNConfiguration+Internal.h in Headers */,
+ C98467A71EAA5B7700272A9A /* OpenVPNConfiguration.h in Headers */,
+ C9657A2F1EB0B79500EFF210 /* OpenVPNTransportStats+Internal.h in Headers */,
C9D2ABE61EA20F99007EDF9D /* Umbrella-Header.h in Headers */,
+ C9657A5F1EB0D60700EFF210 /* OpenVPNTransportProtocol.h in Headers */,
+ C9657A1E1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h in Headers */,
+ C9657A181EB0A7F800EFF210 /* OpenVPNConnectionInfo.h in Headers */,
C9D2ABE71EA20F99007EDF9D /* OpenVPNAdapter+Public.h in Headers */,
C9D2ABE81EA20F99007EDF9D /* OpenVPNError.h in Headers */,
C9D2ABE91EA20F99007EDF9D /* OpenVPNAdapter+Internal.h in Headers */,
+ C9657A621EB0D64E00EFF210 /* OpenVPNIPv6Preference.h in Headers */,
+ C9657A681EB0D73200EFF210 /* OpenVPNMinTLSVersion.h in Headers */,
+ C93779D61EAE32670030A362 /* OpenVPNCredentials.h in Headers */,
+ C9657A651EB0D6C200EFF210 /* OpenVPNCompressionMode.h in Headers */,
C9D2ABEA1EA20F99007EDF9D /* ovpncli.hpp in Headers */,
- C9D2ABEB1EA20F99007EDF9D /* TUNConfiguration.h in Headers */,
+ C93779DC1EAE32880030A362 /* OpenVPNCredentials+Internal.h in Headers */,
+ C9657A6B1EB0D75700EFF210 /* OpenVPNTLSCertProfile.h in Headers */,
+ C9657A471EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h in Headers */,
+ C9657A261EB0B60200EFF210 /* OpenVPNTransportStats.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -412,6 +618,7 @@
TargetAttributes = {
C9BB475B1E71663A00F3F98C = {
CreatedOnToolsVersion = 8.2.1;
+ LastSwiftMigration = 0830;
ProvisioningStyle = Manual;
};
C9BB478D1E71821A00F3F98C = {
@@ -460,7 +667,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C99E2FF01EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */,
+ C98467A21EAA559B00272A9A /* local_vpn_server.ovpn in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -475,7 +682,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C99E2FF11EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */,
+ C98467A31EAA559B00272A9A /* local_vpn_server.ovpn in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -517,10 +724,18 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C9657A421EB0CAC200EFF210 /* OpenVPNServerEntry.mm in Sources */,
+ C9BCE25A1EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm in Sources */,
C9BB47821E7173C700F3F98C /* OpenVPNAdapter.mm in Sources */,
+ C98467A81EAA5B7700272A9A /* OpenVPNConfiguration.mm in Sources */,
+ C9BDB1371EBCC3B900C204FF /* TUNConfiguration.m in Sources */,
+ C9657A311EB0B7A900EFF210 /* OpenVPNTransportStats.mm in Sources */,
+ C9657A581EB0CE1300EFF210 /* OpenVPNProperties.mm in Sources */,
C9BB477A1E7171ED00F3F98C /* OpenVPNClient.mm in Sources */,
- C9BB47761E7171D900F3F98C /* TUNConfiguration.m in Sources */,
C9FD921B1E9A667600374FC4 /* ovpncli.cpp in Sources */,
+ C9657A361EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm in Sources */,
+ C9657A211EB0ACAE00EFF210 /* OpenVPNConnectionInfo.mm in Sources */,
+ C93779D71EAE32670030A362 /* OpenVPNCredentials.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -528,7 +743,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C94605E91EAA656B00971516 /* OpenVPNConfigurationTests.swift in Sources */,
C9BB47911E71821A00F3F98C /* OpenVPNAdapterTests.swift in Sources */,
+ C9B03A7C1EABA82200268B85 /* ProfileLoader.swift in Sources */,
C9BB47A21E7183DB00F3F98C /* Bundle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -537,10 +754,18 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C9657A431EB0CAC200EFF210 /* OpenVPNServerEntry.mm in Sources */,
+ C9BCE25B1EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm in Sources */,
C9D2ABDB1EA20F99007EDF9D /* OpenVPNAdapter.mm in Sources */,
+ C98467A91EAA5B7700272A9A /* OpenVPNConfiguration.mm in Sources */,
+ C9BDB1381EBCC3B900C204FF /* TUNConfiguration.m in Sources */,
+ C9657A301EB0B7A600EFF210 /* OpenVPNTransportStats.mm in Sources */,
+ C9657A591EB0CE1400EFF210 /* OpenVPNProperties.mm in Sources */,
C9D2ABDC1EA20F99007EDF9D /* OpenVPNClient.mm in Sources */,
- C9D2ABDD1EA20F99007EDF9D /* TUNConfiguration.m in Sources */,
C9D2ABDE1EA20F99007EDF9D /* ovpncli.cpp in Sources */,
+ C9657A371EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm in Sources */,
+ C9657A221EB0ACAE00EFF210 /* OpenVPNConnectionInfo.mm in Sources */,
+ C93779D81EAE32670030A362 /* OpenVPNCredentials.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -548,7 +773,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C94605EA1EAA65F200971516 /* OpenVPNConfigurationTests.swift in Sources */,
C9D2ABF61EA212A3007EDF9D /* OpenVPNAdapterTests.swift in Sources */,
+ C9B03A7D1EABA82300268B85 /* ProfileLoader.swift in Sources */,
C9D2ABF71EA212A3007EDF9D /* Bundle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -573,6 +800,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2A1E73F5AF00DEFB32 /* Project.xcconfig */;
buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -601,6 +829,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2A1E73F5AF00DEFB32 /* Project.xcconfig */;
buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -627,7 +856,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2B1E73F69500DEFB32 /* Debug.xcconfig */;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = YES;
@@ -660,6 +888,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
@@ -676,7 +905,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2C1E73F69500DEFB32 /* Release.xcconfig */;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = YES;
@@ -708,6 +936,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
@@ -723,7 +952,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2F1E73FA7400DEFB32 /* Tests.xcconfig */;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -777,7 +1005,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2F1E73FA7400DEFB32 /* Tests.xcconfig */;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -825,7 +1052,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2B1E73F69500DEFB32 /* Debug.xcconfig */;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = YES;
@@ -877,7 +1103,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2C1E73F69500DEFB32 /* Release.xcconfig */;
buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_MODULES = YES;
diff --git a/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter iOS.xcscheme b/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter iOS.xcscheme
index 42a85a6..d707d21 100644
--- a/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter iOS.xcscheme
+++ b/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter iOS.xcscheme
@@ -26,9 +26,29 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
+
+
+
+
+
+
+
+
diff --git a/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter macOS.xcscheme b/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter macOS.xcscheme
index a27b6c3..9aa010d 100644
--- a/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter macOS.xcscheme
+++ b/OpenVPN Adapter.xcodeproj/xcshareddata/xcschemes/OpenVPN Adapter macOS.xcscheme
@@ -26,9 +26,29 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
+
+
+
+
+
+
+
+
diff --git a/OpenVPN Adapter/OpenVPNAdapter+Internal.h b/OpenVPN Adapter/OpenVPNAdapter+Internal.h
index 8a61302..d2b6f50 100644
--- a/OpenVPN Adapter/OpenVPNAdapter+Internal.h
+++ b/OpenVPN Adapter/OpenVPNAdapter+Internal.h
@@ -10,10 +10,9 @@
#import "OpenVPNAdapter.h"
-
using namespace openvpn;
-@interface OpenVPNAdapter (Client)
+@interface OpenVPNAdapter (Internal)
- (BOOL)configureSockets;
@@ -35,4 +34,6 @@ using namespace openvpn;
- (void)handleEvent:(const ClientAPI::Event *)event;
- (void)handleLog:(const ClientAPI::LogInfo *)log;
+- (void)tick;
+
@end
diff --git a/OpenVPN Adapter/OpenVPNAdapter+Public.h b/OpenVPN Adapter/OpenVPNAdapter+Public.h
index 5bd5a09..7eb5831 100644
--- a/OpenVPN Adapter/OpenVPNAdapter+Public.h
+++ b/OpenVPN Adapter/OpenVPNAdapter+Public.h
@@ -1,15 +1,21 @@
//
-// OpenVPNAdapter+Provider.h
-// OpenVPN iOS Client
+// OpenVPNAdapter+Public.h
+// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 11.02.17.
//
//
#import "OpenVPNEvent.h"
-
#import "OpenVPNAdapter.h"
+@class OpenVPNConfiguration;
+@class OpenVPNProperties;
+@class OpenVPNCredentials;
+@class OpenVPNConnectionInfo;
+@class OpenVPNSessionToken;
+@class OpenVPNTransportStats;
+@class OpenVPNInterfaceStats;
@class NEPacketTunnelNetworkSettings;
// TODO: Add documentation to properties and methods
@@ -70,6 +76,8 @@ NS_SWIFT_NAME(handle(event:message:));
- (void)handleError:(nonnull NSError *)error
NS_SWIFT_NAME(handle(error:));
+@optional
+
/**
<#Description#>
@@ -78,44 +86,103 @@ NS_SWIFT_NAME(handle(error:));
- (void)handleLog:(nonnull NSString *)logMessage
NS_SWIFT_NAME(handle(logMessage:));
+/**
+ <#Description#>
+ */
+- (void)tick;
+
@end
/**
<#Description#>
*/
-@interface OpenVPNAdapter (Provider)
+@interface OpenVPNAdapter (Public)
/**
- <#Description#>
+ Return core copyright
*/
-@property (strong, nonatomic, nullable) NSString *username;
+@property (class, nonnull, readonly, nonatomic) NSString *copyright;
/**
- <#Description#>
+ Return platform description
*/
-@property (strong, nonatomic, nullable) NSString *password;
+@property (class, nonnull, readonly, nonatomic) NSString *platform;
/**
<#Description#>
*/
@property (weak, nonatomic, null_unspecified) id delegate;
+/**
+ Return information about the most recent connection. Will be available
+ after an event of type "OpenVPNEventConnected, otherwise return nil.
+ */
+@property (nullable, readonly, nonatomic) OpenVPNConnectionInfo *connectionInfo;
+
+/**
+ Return current session token or nil if session token is unavailable
+ */
+@property (nullable, readonly, nonatomic) OpenVPNSessionToken *sessionToken;
+
+/**
+ Return transport stats
+ */
+@property (nonnull, readonly, nonatomic) OpenVPNTransportStats *transportStats;
+
+/**
+ Return tun stats
+ */
+@property (nonnull, readonly, nonatomic) OpenVPNInterfaceStats *interfaceStats;
+
/**
<#Description#>
- @param settings <#settings description#>
+ @param configuration <#configuration description#>
@param error <#error description#>
@return <#return value description#>
*/
-- (BOOL)configureUsingSettings:(nonnull NSData *)settings
- error:(out NSError * __nullable * __nullable)error
-NS_SWIFT_NAME(configure(using:));
+- (nullable OpenVPNProperties *)applyConfiguration:(nonnull OpenVPNConfiguration *)configuration
+ error:(out NSError * __nullable * __nullable)error
+NS_SWIFT_NAME(apply(configuration:));
+
+/**
+ <#Description#>
+
+ @param credentials <#credentials description#>
+ @param error <#error description#>
+ @return <#return value description#>
+ */
+- (BOOL)provideCredentials:(nonnull OpenVPNCredentials *)credentials
+ error:(out NSError * __nullable * __nullable)error
+NS_SWIFT_NAME(provide(credentials:));
/**
Establish connection with the VPN server
*/
- (void)connect;
+/**
+ Pause the client –- useful to avoid continuous reconnection attempts
+ when network is down
+
+ @param pauseReason <#reason description#>
+ */
+- (void)pauseWithReason:(nullable NSString *)pauseReason
+NS_SWIFT_NAME(pause(reason:));
+
+/**
+ Resume the client after it has been paused
+ */
+- (void)resume;
+
+/**
+ Do a disconnect/reconnect cycle after given amount of seconds from now
+
+ @param interval <#interval description#>
+ */
+- (void)reconnectAfterTimeInterval:(NSInteger)interval
+NS_SWIFT_NAME(reconnect(interval:));
+
/**
Close connection with the VPN server
*/
diff --git a/OpenVPN Adapter/OpenVPNAdapter.h b/OpenVPN Adapter/OpenVPNAdapter.h
index 15ef157..5ee94d7 100644
--- a/OpenVPN Adapter/OpenVPNAdapter.h
+++ b/OpenVPN Adapter/OpenVPNAdapter.h
@@ -1,6 +1,6 @@
//
// OpenVPNAdapter.h
-// OpenVPN iOS Client
+// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 11.02.17.
//
@@ -8,7 +8,6 @@
#import
-
@interface OpenVPNAdapter : NSObject
@end
diff --git a/OpenVPN Adapter/OpenVPNAdapter.mm b/OpenVPN Adapter/OpenVPNAdapter.mm
index 0ae491a..907a064 100644
--- a/OpenVPN Adapter/OpenVPNAdapter.mm
+++ b/OpenVPN Adapter/OpenVPNAdapter.mm
@@ -1,6 +1,6 @@
//
// OpenVPNAdapter.m
-// OpenVPN iOS Client
+// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 11.02.17.
//
@@ -14,11 +14,17 @@
#import
+#import "TUNConfiguration.h"
+#import "OpenVPNClient.h"
#import "OpenVPNError.h"
#import "OpenVPNEvent.h"
-#import "OpenVPNClient.h"
-#import "TUNConfiguration.h"
-
+#import "OpenVPNConfiguration+Internal.h"
+#import "OpenVPNCredentials+Internal.h"
+#import "OpenVPNProperties+Internal.h"
+#import "OpenVPNConnectionInfo+Internal.h"
+#import "OpenVPNSessionToken+Internal.h"
+#import "OpenVPNTransportStats+Internal.h"
+#import "OpenVPNInterfaceStats+Internal.h"
#import "OpenVPNAdapter.h"
#import "OpenVPNAdapter+Internal.h"
#import "OpenVPNAdapter+Public.h"
@@ -28,11 +34,7 @@ NSString * const OpenVPNAdapterErrorDomain = @"me.ss-abramchuk.openvpn-adapter.e
NSString * const OpenVPNAdapterErrorFatalKey = @"me.ss-abramchuk.openvpn-adapter.error-key.fatal";
NSString * const OpenVPNAdapterErrorEventKey = @"me.ss-abramchuk.openvpn-adapter.error-key.event";
-
@interface OpenVPNAdapter () {
- NSString *_username;
- NSString *_password;
-
__weak id _delegate;
}
@@ -57,11 +59,12 @@ NSString * const OpenVPNAdapterErrorEventKey = @"me.ss-abramchuk.openvpn-adapter
- (void)readTUNPackets;
- (void)readVPNData:(NSData *)data;
+- (OpenVPNEvent)getEventIdentifierByName:(NSString *)eventName;
- (NSString *)getSubnetFromPrefixLength:(NSNumber *)prefixLength;
@end
-@implementation OpenVPNAdapter (Client)
+@implementation OpenVPNAdapter (Internal)
#pragma mark Sockets Configuration
@@ -280,7 +283,7 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
// Set MTU
networkSettings.MTU = self.mtu;
- // Establish TUN interface
+ // Establish TUN interface
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self.delegate configureTunnelWithSettings:networkSettings callback:^(id _Nullable flow) {
@@ -335,69 +338,36 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
- (void)handleLog:(const ClientAPI::LogInfo *)log {
NSAssert(self.delegate != nil, @"delegate property should not be nil");
- NSString *message = [NSString stringWithCString:log->text.c_str() encoding:NSUTF8StringEncoding];
- [self.delegate handleLog:message];
+ if ([self.delegate respondsToSelector:@selector(handleLog:)]) {
+ NSString *message = [NSString stringWithCString:log->text.c_str() encoding:NSUTF8StringEncoding];
+ [self.delegate handleLog:message];
+ }
}
-- (OpenVPNEvent)getEventIdentifierByName:(NSString *)eventName {
- NSDictionary *events = @{
- @"DISCONNECTED": @(OpenVPNEventDisconnected),
- @"CONNECTED": @(OpenVPNEventConnected),
- @"RECONNECTING": @(OpenVPNEventReconnecting),
- @"RESOLVE": @(OpenVPNEventResolve),
- @"WAIT": @(OpenVPNEventWait),
- @"WAIT_PROXY": @(OpenVPNEventWaitProxy),
- @"CONNECTING": @(OpenVPNEventConnecting),
- @"GET_CONFIG": @(OpenVPNEventGetConfig),
- @"ASSIGN_IP": @(OpenVPNEventAssignIP),
- @"ADD_ROUTES": @(OpenVPNEventAddRoutes),
- @"ECHO": @(OpenVPNEventEcho),
- @"INFO": @(OpenVPNEventInfo),
- @"PAUSE": @(OpenVPNEventPause),
- @"RESUME": @(OpenVPNEventResume),
- @"TRANSPORT_ERROR": @(OpenVPNEventTransportError),
- @"TUN_ERROR": @(OpenVPNEventTunError),
- @"CLIENT_RESTART": @(OpenVPNEventClientRestart),
- @"AUTH_FAILED": @(OpenVPNEventAuthFailed),
- @"CERT_VERIFY_FAIL": @(OpenVPNEventCertVerifyFail),
- @"TLS_VERSION_MIN": @(OpenVPNEventTLSVersionMin),
- @"CLIENT_HALT": @(OpenVPNEventClientHalt),
- @"CONNECTION_TIMEOUT": @(OpenVPNEventConnectionTimeout),
- @"INACTIVE_TIMEOUT": @(OpenVPNEventInactiveTimeout),
- @"DYNAMIC_CHALLENGE": @(OpenVPNEventDynamicChallenge),
- @"PROXY_NEED_CREDS": @(OpenVPNEventProxyNeedCreds),
- @"PROXY_ERROR": @(OpenVPNEventProxyError),
- @"TUN_SETUP_FAILED": @(OpenVPNEventTunSetupFailed),
- @"TUN_IFACE_CREATE": @(OpenVPNEventTunIfaceCreate),
- @"TUN_IFACE_DISABLED": @(OpenVPNEventTunIfaceDisabled),
- @"EPKI_ERROR": @(OpenVPNEventEPKIError),
- @"EPKI_INVALID_ALIAS": @(OpenVPNEventEPKIInvalidAlias),
- };
+#pragma mark Clock Tick
+
+- (void)tick {
+ NSAssert(self.delegate != nil, @"delegate property should not be nil");
- OpenVPNEvent event = events[eventName] != nil ? (OpenVPNEvent)[(NSNumber *)events[eventName] unsignedIntegerValue] : OpenVPNEventUnknown;
- return event;
+ if ([self.delegate respondsToSelector:@selector(tick)]) {
+ [self.delegate tick];
+ }
}
@end
-@implementation OpenVPNAdapter (Provider)
+@implementation OpenVPNAdapter (Public)
-#pragma mark Properties Gettters/Setters
+#pragma mark Properties
-- (void)setUsername:(NSString *)username {
- _username = username;
++ (NSString *)copyright {
+ std::string copyright = OpenVPNClient::copyright();
+ return [NSString stringWithUTF8String:copyright.c_str()];
}
-- (NSString *)username {
- return _username;
-}
-
-- (void)setPassword:(NSString *)password {
- _password = password;
-}
-
-- (NSString *)password {
- return _password;
++ (NSString *)platform {
+ std::string platform = OpenVPNClient::platform();
+ return [NSString stringWithUTF8String:platform.c_str()];
}
- (void)setDelegate:(id)delegate {
@@ -408,35 +378,44 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
return _delegate;
}
+- (OpenVPNConnectionInfo *)connectionInfo {
+ ClientAPI::ConnectionInfo info = self.vpnClient->connection_info();
+ return info.defined ? [[OpenVPNConnectionInfo alloc] initWithConnectionInfo:info] : nil;
+}
+
+- (OpenVPNSessionToken *)sessionToken {
+ ClientAPI::SessionToken token;
+ bool gotToken = self.vpnClient->session_token(token);
+
+ return gotToken ? [[OpenVPNSessionToken alloc] initWithSessionToken:token] : nil;
+}
+
+- (OpenVPNTransportStats *)transportStats {
+ ClientAPI::TransportStats stats = self.vpnClient->transport_stats();
+ return [[OpenVPNTransportStats alloc] initWithTransportStats:stats];
+}
+
+- (OpenVPNInterfaceStats *)interfaceStats {
+ ClientAPI::InterfaceStats stats = self.vpnClient->tun_stats();
+ return [[OpenVPNInterfaceStats alloc] initWithInterfaceStats:stats];
+}
+
#pragma mark Client Configuration
-- (BOOL)configureUsingSettings:(NSData *)settings error:(out NSError * __autoreleasing _Nullable *)error {
- NSString *vpnConfiguration = [[NSString alloc] initWithData:settings encoding:NSUTF8StringEncoding];
-
- if (vpnConfiguration == nil) {
- if (error) *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:OpenVPNErrorConfigurationFailure userInfo:@{
- NSLocalizedDescriptionKey: @"Failed to read VPN configuration"
- }];
- return NO;
- }
-
- ClientAPI::Config clientConfiguration;
- clientConfiguration.content = std::string([vpnConfiguration UTF8String]);
- clientConfiguration.connTimeout = 30;
-
- ClientAPI::EvalConfig eval = self.vpnClient->eval_config(clientConfiguration);
+- (OpenVPNProperties *)applyConfiguration:(nonnull OpenVPNConfiguration *)configuration error:(out NSError * __nullable * __nullable)error {
+ ClientAPI::EvalConfig eval = self.vpnClient->eval_config(configuration.config);
if (eval.error) {
if (error) *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:OpenVPNErrorConfigurationFailure userInfo:@{
NSLocalizedDescriptionKey: [NSString stringWithUTF8String:eval.message.c_str()]
}];
- return NO;
+ return nil;
}
-
- ClientAPI::ProvideCreds creds;
- creds.username = self.username == nil? "" : [self.username UTF8String];
- creds.password = self.password == nil ? "" : [self.password UTF8String];
- ClientAPI::Status creds_status = self.vpnClient->provide_creds(creds);
+ return [[OpenVPNProperties alloc] initWithEvalConfig:eval];
+}
+
+- (BOOL)provideCredentials:(nonnull OpenVPNCredentials *)credentials error:(out NSError * __nullable * __nullable)error {
+ ClientAPI::Status creds_status = self.vpnClient->provide_creds(credentials.credentials);
if (creds_status.error) {
if (error) *error = [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:OpenVPNErrorConfigurationFailure userInfo:@{
NSLocalizedDescriptionKey: [NSString stringWithUTF8String:creds_status.message.c_str()]
@@ -450,16 +429,15 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
#pragma mark Connection Control
- (void)connect {
- // TODO: Describe why we use async invocation here
- dispatch_queue_t connectQueue = dispatch_queue_create("me.ss-abramchuk.openvpn-ios-client.connection", NULL);
+ dispatch_queue_t connectQueue = dispatch_queue_create("me.ss-abramchuk.openvpn-adapter.connection", NULL);
dispatch_async(connectQueue, ^{
+ OpenVPNClient::init_process();
+
self.tunConfigurationIPv6 = [TUNConfiguration new];
self.tunConfigurationIPv4 = [TUNConfiguration new];
self.searchDomains = [NSMutableArray new];
- OpenVPNClient::init_process();
-
try {
ClientAPI::Status status = self.vpnClient->connect();
if (status.error) {
@@ -479,8 +457,6 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
[self.delegate handleError:error];
}
- OpenVPNClient::uninit_process();
-
self.remoteAddress = nil;
self.tunConfigurationIPv6 = nil;
@@ -499,9 +475,24 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
CFSocketInvalidate(self.tunSocket);
CFRelease(self.tunSocket);
}
+
+ OpenVPNClient::uninit_process();
});
}
+- (void)pauseWithReason:(NSString *)pauseReason {
+ std::string reason = pauseReason ? std::string([pauseReason UTF8String]) : "";
+ self.vpnClient->pause(reason);
+}
+
+- (void)resume {
+ self.vpnClient->resume();
+}
+
+- (void)reconnectAfterTimeInterval:(NSInteger)interval {
+ self.vpnClient->reconnect(interval);
+}
+
- (void)disconnect {
self.vpnClient->stop();
}
@@ -516,10 +507,7 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
{
self = [super init];
if (self) {
- _username = nil;
- _password = nil;
_delegate = nil;
-
self.vpnClient = new OpenVPNClient((__bridge void *)self);
}
return self;
@@ -571,6 +559,45 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
#pragma mark Utils
+- (OpenVPNEvent)getEventIdentifierByName:(NSString *)eventName {
+ NSDictionary *events = @{
+ @"DISCONNECTED": @(OpenVPNEventDisconnected),
+ @"CONNECTED": @(OpenVPNEventConnected),
+ @"RECONNECTING": @(OpenVPNEventReconnecting),
+ @"RESOLVE": @(OpenVPNEventResolve),
+ @"WAIT": @(OpenVPNEventWait),
+ @"WAIT_PROXY": @(OpenVPNEventWaitProxy),
+ @"CONNECTING": @(OpenVPNEventConnecting),
+ @"GET_CONFIG": @(OpenVPNEventGetConfig),
+ @"ASSIGN_IP": @(OpenVPNEventAssignIP),
+ @"ADD_ROUTES": @(OpenVPNEventAddRoutes),
+ @"ECHO": @(OpenVPNEventEcho),
+ @"INFO": @(OpenVPNEventInfo),
+ @"PAUSE": @(OpenVPNEventPause),
+ @"RESUME": @(OpenVPNEventResume),
+ @"TRANSPORT_ERROR": @(OpenVPNEventTransportError),
+ @"TUN_ERROR": @(OpenVPNEventTunError),
+ @"CLIENT_RESTART": @(OpenVPNEventClientRestart),
+ @"AUTH_FAILED": @(OpenVPNEventAuthFailed),
+ @"CERT_VERIFY_FAIL": @(OpenVPNEventCertVerifyFail),
+ @"TLS_VERSION_MIN": @(OpenVPNEventTLSVersionMin),
+ @"CLIENT_HALT": @(OpenVPNEventClientHalt),
+ @"CONNECTION_TIMEOUT": @(OpenVPNEventConnectionTimeout),
+ @"INACTIVE_TIMEOUT": @(OpenVPNEventInactiveTimeout),
+ @"DYNAMIC_CHALLENGE": @(OpenVPNEventDynamicChallenge),
+ @"PROXY_NEED_CREDS": @(OpenVPNEventProxyNeedCreds),
+ @"PROXY_ERROR": @(OpenVPNEventProxyError),
+ @"TUN_SETUP_FAILED": @(OpenVPNEventTunSetupFailed),
+ @"TUN_IFACE_CREATE": @(OpenVPNEventTunIfaceCreate),
+ @"TUN_IFACE_DISABLED": @(OpenVPNEventTunIfaceDisabled),
+ @"EPKI_ERROR": @(OpenVPNEventEPKIError),
+ @"EPKI_INVALID_ALIAS": @(OpenVPNEventEPKIInvalidAlias),
+ };
+
+ OpenVPNEvent event = events[eventName] != nil ? (OpenVPNEvent)[(NSNumber *)events[eventName] unsignedIntegerValue] : OpenVPNEventUnknown;
+ return event;
+}
+
- (NSString *)getSubnetFromPrefixLength:(NSNumber *)prefixLength {
uint32_t bitmask = UINT_MAX << (sizeof(uint32_t) * 8 - prefixLength.integerValue);
diff --git a/OpenVPN Adapter/OpenVPNClient.h b/OpenVPN Adapter/OpenVPNClient.h
index fe80486..1fbeec3 100644
--- a/OpenVPN Adapter/OpenVPNClient.h
+++ b/OpenVPN Adapter/OpenVPNClient.h
@@ -6,9 +6,9 @@
//
//
+#import
#import
-
using namespace openvpn;
class OpenVPNClient : public ClientAPI::OpenVPNClient
@@ -62,8 +62,8 @@ public:
virtual void event(const ClientAPI::Event& ev) override;
virtual void log(const ClientAPI::LogInfo& log) override;
-private:
- std::string get_subnet(int prefix_length);
+ virtual void clock_tick() override;
- void *adapter;
+private:
+ void* adapter;
};
diff --git a/OpenVPN Adapter/OpenVPNClient.mm b/OpenVPN Adapter/OpenVPNClient.mm
index ea94a07..95fabe0 100644
--- a/OpenVPN Adapter/OpenVPNClient.mm
+++ b/OpenVPN Adapter/OpenVPNClient.mm
@@ -6,15 +6,11 @@
//
//
-#import
-
#import
#import "OpenVPNAdapter+Internal.h"
-
#import "OpenVPNClient.h"
-
OpenVPNClient::OpenVPNClient(void *adapter) : ClientAPI::OpenVPNClient() {
this->adapter = adapter;
}
@@ -49,7 +45,7 @@ bool OpenVPNClient::tun_builder_exclude_route(const std::string& address, int pr
return [(__bridge OpenVPNAdapter *)adapter excludeRoute:route prefixLength:@(prefix_length) isIPv6:ipv6];
}
-bool OpenVPNClient::tun_builder_add_dns_server(const std::string& address, bool ipv6) {
+bool OpenVPNClient::tun_builder_add_dns_server(const std::string& address, bool ipv6) {
NSString *dnsAddress = [NSString stringWithUTF8String:address.c_str()];
return [(__bridge OpenVPNAdapter *)adapter addDNSAddress:dnsAddress isIPv6:ipv6];
}
@@ -95,30 +91,29 @@ bool OpenVPNClient::tun_builder_persist() {
return true;
}
-void OpenVPNClient::tun_builder_establish_lite() {
-
-}
+void OpenVPNClient::tun_builder_establish_lite() { }
-void OpenVPNClient::tun_builder_teardown(bool disconnect) {
-
-}
+void OpenVPNClient::tun_builder_teardown(bool disconnect) { }
bool OpenVPNClient::socket_protect(int socket) {
return true;
}
-// TODO: Provide interfacing with an OS-layer Keychain
-void OpenVPNClient::external_pki_cert_request(ClientAPI::ExternalPKICertRequest& certreq) { }
-void OpenVPNClient::external_pki_sign_request(ClientAPI::ExternalPKISignRequest& signreq) { }
-
bool OpenVPNClient::pause_on_connection_timeout() {
return false;
}
+void OpenVPNClient::external_pki_cert_request(ClientAPI::ExternalPKICertRequest& certreq) { }
+void OpenVPNClient::external_pki_sign_request(ClientAPI::ExternalPKISignRequest& signreq) { }
+
void OpenVPNClient::event(const ClientAPI::Event& ev) {
- [(__bridge OpenVPNAdapter *)adapter handleEvent:&ev];
+ [(__bridge OpenVPNAdapter* )adapter handleEvent:&ev];
}
void OpenVPNClient::log(const ClientAPI::LogInfo& log) {
- [(__bridge OpenVPNAdapter *)adapter handleLog:&log];
+ [(__bridge OpenVPNAdapter* )adapter handleLog:&log];
+}
+
+void OpenVPNClient::clock_tick() {
+ [(__bridge OpenVPNAdapter* )adapter tick];
}
diff --git a/OpenVPN Adapter/OpenVPNCompressionMode.h b/OpenVPN Adapter/OpenVPNCompressionMode.h
new file mode 100644
index 0000000..3154398
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNCompressionMode.h
@@ -0,0 +1,23 @@
+//
+// OpenVPNCompressionMode.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Compression mode options
+ */
+typedef NS_ENUM(NSInteger, OpenVPNCompressionMode) {
+ /// Allow compression on both uplink and downlink
+ OpenVPNCompressionModeEnabled,
+ /// Support compression stubs only
+ OpenVPNCompressionModeDisabled,
+ /// Allow compression on downlink only (i.e. server -> client)
+ OpenVPNCompressionModeAsym,
+ /// Default behavior (support compression stubs only)
+ OpenVPNCompressionModeDefault
+};
diff --git a/OpenVPN Adapter/OpenVPNConfiguration+Internal.h b/OpenVPN Adapter/OpenVPNConfiguration+Internal.h
new file mode 100644
index 0000000..62d01cf
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConfiguration+Internal.h
@@ -0,0 +1,34 @@
+//
+// OpenVPNConfiguration+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 21.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNConfiguration.h"
+
+using namespace openvpn;
+
+@interface OpenVPNConfiguration (Internal)
+
+@property (readonly) ClientAPI::Config config;
+
++ (OpenVPNTransportProtocol)getTransportProtocolFromValue:(nullable NSString *)value;
++ (nonnull NSString *)getValueFromTransportProtocol:(OpenVPNTransportProtocol)protocol;
+
++ (OpenVPNIPv6Preference)getIPv6PreferenceFromValue:(nullable NSString *)value;
++ (nonnull NSString *)getValueFromIPv6Preference:(OpenVPNIPv6Preference)preference;
+
++ (OpenVPNCompressionMode)getCompressionModeFromValue:(nullable NSString *)value;
++ (nonnull NSString *)getValueFromCompressionMode:(OpenVPNCompressionMode)compressionMode;
+
++ (OpenVPNMinTLSVersion)getMinTLSFromValue:(nullable NSString *)value;
++ (nonnull NSString *)getValueFromMinTLS:(OpenVPNMinTLSVersion)minTLS;
+
++ (OpenVPNTLSCertProfile)getTLSCertProfileFromValue:(nullable NSString *)value;
++ (nonnull NSString *)getValueFromTLSCertProfile:(OpenVPNTLSCertProfile)tlsCertProfile;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNConfiguration.h b/OpenVPN Adapter/OpenVPNConfiguration.h
new file mode 100644
index 0000000..5c431d5
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConfiguration.h
@@ -0,0 +1,145 @@
+//
+// OpenVPNConfiguration.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 21.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNTransportProtocol.h"
+#import "OpenVPNIPv6Preference.h"
+#import "OpenVPNCompressionMode.h"
+#import "OpenVPNMinTLSVersion.h"
+#import "OpenVPNTLSCertProfile.h"
+
+/**
+ Class used to pass configuration
+ */
+@interface OpenVPNConfiguration : NSObject
+
+/**
+ OpenVPN profile as a NSData
+ */
+@property (nullable, nonatomic) NSData *fileContent;
+
+/**
+ OpenVPN profile as series of key/value pairs (may be provided exclusively
+ or in addition to file content).
+ */
+@property (nullable, nonatomic) NSDictionary *settings;
+
+/**
+ Set to identity OpenVPN GUI version.
+ Format should be ""
+ Passed to server as IV_GUI_VER.
+ */
+@property (nullable, nonatomic) NSString *guiVersion;
+
+/**
+ Use a different server than that specified in "remote"
+ option of profile
+ */
+@property (nullable, nonatomic) NSString *server;
+
+/**
+ Force a given transport protocol
+ */
+@property (nonatomic) OpenVPNTransportProtocol proto;
+
+/**
+ IPv6 preference
+ */
+@property (nonatomic) OpenVPNIPv6Preference ipv6;
+
+/**
+ Connection timeout in seconds, or 0 to retry indefinitely
+ */
+@property (nonatomic) NSInteger connectionTimeout;
+
+/**
+ Keep tun interface active during pauses or reconnections
+ */
+@property (nonatomic) BOOL tunPersist;
+
+/**
+ If true and a redirect-gateway profile doesn't also define
+ DNS servers, use the standard Google DNS servers.
+ */
+@property (nonatomic) BOOL googleDNSFallback;
+
+/**
+ Enable autologin sessions
+ */
+@property (nonatomic) BOOL autologinSessions;
+
+/**
+ If YES, don't send client cert/key to peer
+ */
+@property (nonatomic) BOOL disableClientCert;
+
+/**
+ SSL library debug level
+ */
+@property (nonatomic) NSInteger sslDebugLevel;
+
+/**
+ Compression mode
+ */
+@property (nonatomic) OpenVPNCompressionMode compressionMode;
+
+/**
+ Private key password
+ */
+@property (nullable, nonatomic) NSString *privateKeyPassword;
+
+/**
+ Default key direction parameter for tls-auth (0, 1,
+ or -1 (bidirectional -- default)) if no key-direction
+ parameter defined in profile
+ */
+@property (nonatomic) NSInteger keyDirection;
+
+/**
+ If YES, force ciphersuite to be one of:
+ 1. TLS_DHE_RSA_WITH_AES_256_CBC_SHA, or
+ 2. TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ and disable setting TLS minimum version.
+ This is intended for compatibility with legacy systems.
+ */
+@property (nonatomic) BOOL forceCiphersuitesAESCBC;
+
+/**
+ Override the minimum TLS version
+ */
+@property (nonatomic) OpenVPNMinTLSVersion minTLSVersion;
+
+/**
+ Override or default the tls-cert-profile setting
+ */
+@property (nonatomic) OpenVPNTLSCertProfile tlsCertProfile;
+
+/**
+ Pass custom key/value pairs to OpenVPN server
+ */
+@property (nullable, nonatomic) NSDictionary *peerInfo;
+
+/**
+ Pass through pushed "echo" directives via "ECHO" event
+ */
+@property (nonatomic) BOOL echo;
+
+/**
+ Pass through control channel INFO notifications via "INFO" event
+ */
+@property (nonatomic) BOOL info;
+
+/**
+ Periodic convenience clock tick in milliseconds. Will call
+ [OpenVPNAdapterDelegate tick] at a frequency defined by this parameter.
+ Set to 0 to disable.
+ */
+@property (nonatomic) NSUInteger clockTick;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNConfiguration.mm b/OpenVPN Adapter/OpenVPNConfiguration.mm
new file mode 100644
index 0000000..5008af8
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConfiguration.mm
@@ -0,0 +1,440 @@
+//
+// OpenVPNConfiguration.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 21.04.17.
+//
+//
+
+#import "OpenVPNConfiguration+Internal.h"
+
+using namespace openvpn;
+
+NSString *const OpenVPNTransportProtocolUDPValue = @"udp";
+NSString *const OpenVPNTransportProtocolTCPValue = @"tcp";
+NSString *const OpenVPNTransportProtocolAdaptiveValue = @"adaptive";
+NSString *const OpenVPNTransportProtocolDefaultValue = @"";
+
+NSString *const OpenVPNIPv6PreferenceEnabledValue = @"yes";
+NSString *const OpenVPNIPv6PreferenceDisabledValue = @"no";
+NSString *const OpenVPNIPv6PreferenceDefaultValue = @"default";
+
+NSString *const OpenVPNCompressionModeEnabledValue = @"yes";
+NSString *const OpenVPNCompressionModeDisabledValue = @"no";
+NSString *const OpenVPNCompressionModeAsymValue = @"asym";
+NSString *const OpenVPNCompressionModeDefaultValue = @"";
+
+NSString *const OpenVPNMinTLSVersionDisabledValue = @"disabled";
+NSString *const OpenVPNMinTLSVersion10Value = @"tls_1_0";
+NSString *const OpenVPNMinTLSVersion11Value = @"tls_1_1";
+NSString *const OpenVPNMinTLSVersion12Value = @"tls_1_2";
+NSString *const OpenVPNMinTLSVersionDefaultValue = @"default";
+
+NSString *const OpenVPNTLSCertProfileLegacyValue = @"legacy";
+NSString *const OpenVPNTLSCertProfilePreferredValue = @"preferred";
+NSString *const OpenVPNTLSCertProfileSuiteBValue = @"suiteb";
+NSString *const OpenVPNTLSCertProfileLegacyDefaultValue = @"legacy-default";
+NSString *const OpenVPNTLSCertProfilePreferredDefaultValue = @"preferred-default";
+NSString *const OpenVPNTLSCertProfileDefaultValue = @"default";
+
+@interface OpenVPNConfiguration () {
+ ClientAPI::Config _config;
+}
+
+@end
+
+@implementation OpenVPNConfiguration (Internal)
+
+- (ClientAPI::Config)config {
+ return _config;
+}
+
++ (OpenVPNTransportProtocol)getTransportProtocolFromValue:(NSString *)value {
+ NSDictionary *options = @{
+ OpenVPNTransportProtocolUDPValue: @(OpenVPNTransportProtocolUDP),
+ OpenVPNTransportProtocolTCPValue: @(OpenVPNTransportProtocolTCP),
+ OpenVPNTransportProtocolAdaptiveValue: @(OpenVPNTransportProtocolAdaptive),
+ OpenVPNTransportProtocolDefaultValue: @(OpenVPNTransportProtocolDefault)
+ };
+
+ NSString *currentValue = [value length] == 0 ? OpenVPNTransportProtocolDefaultValue : value;
+
+ NSNumber *transportProtocol = options[currentValue];
+ NSAssert(transportProtocol != nil, @"Incorrect protocol value: %@", currentValue);
+
+ return (OpenVPNTransportProtocol)[transportProtocol integerValue];
+}
+
++ (nonnull NSString *)getValueFromTransportProtocol:(OpenVPNTransportProtocol)protocol {
+ NSDictionary *options = @{
+ @(OpenVPNTransportProtocolUDP): OpenVPNTransportProtocolUDPValue,
+ @(OpenVPNTransportProtocolTCP): OpenVPNTransportProtocolTCPValue,
+ @(OpenVPNTransportProtocolAdaptive): OpenVPNTransportProtocolAdaptiveValue,
+ @(OpenVPNTransportProtocolDefault): OpenVPNTransportProtocolDefaultValue
+ };
+
+ NSString *value = options[@(protocol)];
+ NSAssert(value != nil, @"Incorrect protocol value: %li", (NSInteger)protocol);
+
+ return value;
+}
+
++ (OpenVPNIPv6Preference)getIPv6PreferenceFromValue:(nullable NSString *)value {
+ NSDictionary *options = @{
+ OpenVPNIPv6PreferenceEnabledValue: @(OpenVPNIPv6PreferenceEnabled),
+ OpenVPNIPv6PreferenceDisabledValue: @(OpenVPNIPv6PreferenceDisabled),
+ OpenVPNIPv6PreferenceDefaultValue: @(OpenVPNIPv6PreferenceDefault)
+ };
+
+ NSString *currentValue = [value length] == 0 ? OpenVPNIPv6PreferenceDefaultValue : value;
+
+ NSNumber *ipv6 = options[currentValue];
+ NSAssert(ipv6 != nil, @"Incorrect ipv6 value: %@", currentValue);
+
+ return (OpenVPNIPv6Preference)[ipv6 integerValue];
+}
+
++ (nonnull NSString *)getValueFromIPv6Preference:(OpenVPNIPv6Preference)preference {
+ NSDictionary *options = @{
+ @(OpenVPNIPv6PreferenceEnabled): OpenVPNIPv6PreferenceEnabledValue,
+ @(OpenVPNIPv6PreferenceDisabled): OpenVPNIPv6PreferenceDisabledValue,
+ @(OpenVPNIPv6PreferenceDefault): OpenVPNIPv6PreferenceDefaultValue
+ };
+
+ NSString *value = options[@(preference)];
+ NSAssert(value != nil, @"Incorrect ipv6 value: %li", (NSInteger)preference);
+
+ return value;
+}
+
++ (OpenVPNCompressionMode)getCompressionModeFromValue:(nullable NSString *)value {
+ NSDictionary *options = @{
+ OpenVPNCompressionModeEnabledValue: @(OpenVPNCompressionModeEnabled),
+ OpenVPNCompressionModeDisabledValue: @(OpenVPNCompressionModeDisabled),
+ OpenVPNCompressionModeAsymValue: @(OpenVPNCompressionModeAsym),
+ OpenVPNCompressionModeDefaultValue: @(OpenVPNCompressionModeDefault)
+ };
+
+ NSString *currentValue = [value length] == 0 ? OpenVPNCompressionModeDefaultValue : value;
+
+ NSNumber *compressionMode = options[currentValue];
+ NSAssert(compressionMode != nil, @"Incorrect compressionMode value: %@", currentValue);
+
+ return (OpenVPNCompressionMode)[compressionMode integerValue];
+}
+
++ (nonnull NSString *)getValueFromCompressionMode:(OpenVPNCompressionMode)compressionMode {
+ NSDictionary *options = @{
+ @(OpenVPNCompressionModeEnabled): OpenVPNCompressionModeEnabledValue,
+ @(OpenVPNCompressionModeDisabled): OpenVPNCompressionModeDisabledValue,
+ @(OpenVPNCompressionModeAsym): OpenVPNCompressionModeAsymValue,
+ @(OpenVPNCompressionModeDefault): OpenVPNCompressionModeDefaultValue
+ };
+
+ NSString *value = options[@(compressionMode)];
+ NSAssert(value != nil, @"Incorrect compressionMode value: %li", (NSInteger)compressionMode);
+
+ return value;
+}
+
++ (OpenVPNMinTLSVersion)getMinTLSFromValue:(nullable NSString *)value {
+ NSDictionary *options = @{
+ OpenVPNMinTLSVersionDisabledValue: @(OpenVPNMinTLSVersionDisabled),
+ OpenVPNMinTLSVersion10Value: @(OpenVPNMinTLSVersion10),
+ OpenVPNMinTLSVersion11Value: @(OpenVPNMinTLSVersion11),
+ OpenVPNMinTLSVersion12Value: @(OpenVPNMinTLSVersion12),
+ OpenVPNMinTLSVersionDefaultValue: @(OpenVPNMinTLSVersionDefault)
+ };
+
+ NSString *currentValue = [value length] == 0 ? OpenVPNMinTLSVersionDefaultValue : value;
+
+ NSNumber *minTLSVersion = options[currentValue];
+ NSAssert(minTLSVersion != nil, @"Incorrect minTLS value: %@", currentValue);
+
+ return (OpenVPNMinTLSVersion)[minTLSVersion integerValue];
+}
+
++ (nonnull NSString *)getValueFromMinTLS:(OpenVPNMinTLSVersion)minTLS {
+ NSDictionary *options = @{
+ @(OpenVPNMinTLSVersionDisabled): OpenVPNMinTLSVersionDisabledValue,
+ @(OpenVPNMinTLSVersion10): OpenVPNMinTLSVersion10Value,
+ @(OpenVPNMinTLSVersion11): OpenVPNMinTLSVersion11Value,
+ @(OpenVPNMinTLSVersion12): OpenVPNMinTLSVersion12Value,
+ @(OpenVPNMinTLSVersionDefault): OpenVPNMinTLSVersionDefaultValue
+ };
+
+ NSString *value = options[@(minTLS)];
+ NSAssert(value != nil, @"Incorrect minTLS value: %li", (NSInteger)minTLS);
+
+ return value;
+}
+
++ (OpenVPNTLSCertProfile)getTLSCertProfileFromValue:(nullable NSString *)value {
+ NSDictionary *options = @{
+ OpenVPNTLSCertProfileLegacyValue: @(OpenVPNTLSCertProfileLegacy),
+ OpenVPNTLSCertProfilePreferredValue: @(OpenVPNTLSCertProfilePreferred),
+ OpenVPNTLSCertProfileSuiteBValue: @(OpenVPNTLSCertProfileSuiteB),
+ OpenVPNTLSCertProfileLegacyDefaultValue: @(OpenVPNTLSCertProfileLegacyDefault),
+ OpenVPNTLSCertProfilePreferredDefaultValue: @(OpenVPNTLSCertProfilePreferredDefault),
+ OpenVPNTLSCertProfileDefaultValue: @(OpenVPNTLSCertProfileDefault),
+ };
+
+ NSString *currentValue = [value length] == 0 ? OpenVPNTLSCertProfileDefaultValue : value;
+
+ NSNumber *tlsCertProfile = options[currentValue];
+ NSAssert(tlsCertProfile != nil, @"Incorrect tlsCertProfile value: %@", currentValue);
+
+ return (OpenVPNTLSCertProfile)[tlsCertProfile integerValue];
+}
+
++ (nonnull NSString *)getValueFromTLSCertProfile:(OpenVPNTLSCertProfile)tlsCertProfile {
+ NSDictionary *options = @{
+ @(OpenVPNTLSCertProfileLegacy): OpenVPNTLSCertProfileLegacyValue,
+ @(OpenVPNTLSCertProfilePreferred): OpenVPNTLSCertProfilePreferredValue,
+ @(OpenVPNTLSCertProfileSuiteB): OpenVPNTLSCertProfileSuiteBValue,
+ @(OpenVPNTLSCertProfileLegacyDefault): OpenVPNTLSCertProfileLegacyDefaultValue,
+ @(OpenVPNTLSCertProfilePreferredDefault): OpenVPNTLSCertProfilePreferredDefaultValue,
+ @(OpenVPNTLSCertProfileDefault): OpenVPNTLSCertProfileDefaultValue
+ };
+
+ NSString *value = options[@(tlsCertProfile)];
+ NSAssert(value != nil, @"Incorrect tlsCertProfile value: %li", (NSInteger)tlsCertProfile);
+
+ return value;
+}
+
+@end
+
+@implementation OpenVPNConfiguration
+
+- (NSData *)fileContent {
+ return !_config.content.empty() ? [NSData dataWithBytes:_config.content.data() length:_config.content.size()] : nil;
+}
+
+- (void)setFileContent:(NSData *)fileContent {
+ _config.content = fileContent ? std::string((const char *)fileContent.bytes) : "";
+}
+
+- (NSDictionary *)settings {
+ if (_config.contentList.size() == 0) {
+ return nil;
+ }
+
+ NSMutableDictionary *settings = [NSMutableDictionary new];
+
+ for (ClientAPI::KeyValue param : _config.contentList) {
+ NSString *key = [NSString stringWithCString:param.key.c_str() encoding:NSUTF8StringEncoding];
+ NSString *value = [NSString stringWithCString:param.value.c_str() encoding:NSUTF8StringEncoding];
+
+ settings[key] = value;
+ }
+
+ return [settings copy];
+}
+
+- (void)setSettings:(NSDictionary *)settings {
+ _config.contentList.clear();
+
+ if (!settings) {
+ return;
+ }
+
+ [settings enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
+ ClientAPI::KeyValue param = ClientAPI::KeyValue(std::string([key UTF8String]), std::string([obj UTF8String]));
+ _config.contentList.push_back(param);
+ }];
+}
+
+- (NSString *)guiVersion {
+ return !_config.guiVersion.empty() ? [NSString stringWithUTF8String:_config.guiVersion.c_str()] : nil;
+}
+
+- (void)setGuiVersion:(NSString *)guiVersion {
+ _config.guiVersion = guiVersion ? std::string([guiVersion UTF8String]) : "";
+}
+
+- (NSString *)server {
+ return !_config.serverOverride.empty() ? [NSString stringWithUTF8String:_config.serverOverride.c_str()] : nil;
+}
+
+- (void)setServer:(NSString *)serverOverride {
+ _config.serverOverride = serverOverride ? std::string([serverOverride UTF8String]) : "";
+}
+
+- (OpenVPNTransportProtocol)proto {
+ NSString *currentValue = [NSString stringWithUTF8String:_config.protoOverride.c_str()];
+ return [OpenVPNConfiguration getTransportProtocolFromValue:currentValue];
+}
+
+- (void)setProto:(OpenVPNTransportProtocol)proto {
+ NSString *value = [OpenVPNConfiguration getValueFromTransportProtocol:proto];
+ _config.protoOverride = std::string([value UTF8String]);
+}
+
+- (OpenVPNIPv6Preference)ipv6 {
+ NSString *currentValue = [NSString stringWithUTF8String:_config.ipv6.c_str()];
+ return [OpenVPNConfiguration getIPv6PreferenceFromValue:currentValue];
+}
+
+- (void)setIpv6:(OpenVPNIPv6Preference)ipv6 {
+ NSString *value = [OpenVPNConfiguration getValueFromIPv6Preference:ipv6];
+ _config.ipv6 = std::string([value UTF8String]);
+}
+
+- (NSInteger)connectionTimeout {
+ return _config.connTimeout;
+}
+
+- (void)setConnectionTimeout:(NSInteger)connectionTimeout {
+ _config.connTimeout = connectionTimeout;
+}
+
+- (BOOL)tunPersist {
+ return _config.tunPersist;
+}
+
+- (void)setTunPersist:(BOOL)tunPersist {
+ _config.tunPersist = tunPersist;
+}
+
+- (BOOL)googleDNSFallback {
+ return _config.googleDnsFallback;
+}
+
+- (void)setGoogleDNSFallback:(BOOL)googleDNSFallback {
+ _config.googleDnsFallback = googleDNSFallback;
+}
+
+- (BOOL)autologinSessions {
+ return _config.autologinSessions;
+}
+
+- (void)setAutologinSessions:(BOOL)autologinSessions {
+ _config.autologinSessions = autologinSessions;
+}
+
+- (BOOL)disableClientCert {
+ return _config.disableClientCert;
+}
+
+- (void)setDisableClientCert:(BOOL)disableClientCert {
+ _config.disableClientCert = disableClientCert;
+}
+
+- (NSInteger)sslDebugLevel {
+ return _config.sslDebugLevel;
+}
+
+- (void)setSslDebugLevel:(NSInteger)sslDebugLevel {
+ _config.sslDebugLevel = sslDebugLevel;
+}
+
+- (OpenVPNCompressionMode)compressionMode {
+ NSString *currentValue = [NSString stringWithUTF8String:_config.compressionMode.c_str()];
+ return [OpenVPNConfiguration getCompressionModeFromValue:currentValue];
+}
+
+- (void)setCompressionMode:(OpenVPNCompressionMode)compressionMode {
+ NSString *value = [OpenVPNConfiguration getValueFromCompressionMode:compressionMode];
+ _config.compressionMode = std::string([value UTF8String]);
+}
+
+- (NSString *)privateKeyPassword {
+ return !_config.privateKeyPassword.empty() ? [NSString stringWithUTF8String:_config.privateKeyPassword.c_str()] : nil;
+}
+
+- (void)setPrivateKeyPassword:(NSString *)privateKeyPassword {
+ _config.privateKeyPassword = privateKeyPassword ? std::string([privateKeyPassword UTF8String]) : "";
+}
+
+- (NSInteger)keyDirection {
+ return _config.defaultKeyDirection;
+}
+
+- (void)setKeyDirection:(NSInteger)keyDirection {
+ _config.defaultKeyDirection = keyDirection;
+}
+
+- (BOOL)forceCiphersuitesAESCBC {
+ return _config.forceAesCbcCiphersuites;
+}
+
+- (void)setForceCiphersuitesAESCBC:(BOOL)forceCiphersuitesAESCBC {
+ _config.forceAesCbcCiphersuites = forceCiphersuitesAESCBC;
+}
+
+- (OpenVPNMinTLSVersion)minTLSVersion {
+ NSString *currentValue = [NSString stringWithUTF8String:_config.tlsVersionMinOverride.c_str()];
+ return [OpenVPNConfiguration getMinTLSFromValue:currentValue];
+}
+
+- (void)setMinTLSVersion:(OpenVPNMinTLSVersion)minTLSVersion {
+ NSString *value = [OpenVPNConfiguration getValueFromMinTLS:minTLSVersion];
+ _config.tlsVersionMinOverride = std::string([value UTF8String]);
+}
+
+- (OpenVPNTLSCertProfile)tlsCertProfile {
+ NSString *currentValue = [NSString stringWithUTF8String:_config.tlsCertProfileOverride.c_str()];
+ return [OpenVPNConfiguration getTLSCertProfileFromValue:currentValue];
+}
+
+- (void)setTlsCertProfile:(OpenVPNTLSCertProfile)tlsCertProfile {
+ NSString *value = [OpenVPNConfiguration getValueFromTLSCertProfile:tlsCertProfile];
+ _config.tlsCertProfileOverride = std::string([value UTF8String]);
+}
+
+- (NSDictionary *)peerInfo {
+ if (_config.peerInfo.empty()) {
+ return nil;
+ }
+
+ NSMutableDictionary *peerInfo = [NSMutableDictionary new];
+
+ for (ClientAPI::KeyValue param : _config.peerInfo) {
+ NSString *key = [NSString stringWithCString:param.key.c_str() encoding:NSUTF8StringEncoding];
+ NSString *value = [NSString stringWithCString:param.value.c_str() encoding:NSUTF8StringEncoding];
+
+ peerInfo[key] = value;
+ }
+
+ return [peerInfo copy];
+}
+
+- (void)setPeerInfo:(NSDictionary *)peerInfo {
+ _config.peerInfo.clear();
+
+ if (!peerInfo) {
+ return;
+ }
+
+ [peerInfo enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
+ ClientAPI::KeyValue param = ClientAPI::KeyValue(std::string([key UTF8String]), std::string([obj UTF8String]));
+ _config.peerInfo.push_back(param);
+ }];
+}
+
+- (BOOL)echo {
+ return _config.echo;
+}
+
+- (void)setEcho:(BOOL)echo {
+ _config.echo = echo;
+}
+
+- (BOOL)info {
+ return _config.info;
+}
+
+- (void)setInfo:(BOOL)info {
+ _config.info = info;
+}
+
+- (NSUInteger)clockTick {
+ return _config.clockTickMS;
+}
+
+- (void)setClockTick:(NSUInteger)clockTick {
+ _config.clockTickMS = clockTick;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNConnectionInfo+Internal.h b/OpenVPN Adapter/OpenVPNConnectionInfo+Internal.h
new file mode 100644
index 0000000..829beea
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConnectionInfo+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNConnectionInfo+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNConnectionInfo.h"
+
+using namespace openvpn;
+
+@interface OpenVPNConnectionInfo (Internal)
+
+- (instancetype)initWithConnectionInfo:(ClientAPI::ConnectionInfo)info;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNConnectionInfo.h b/OpenVPN Adapter/OpenVPNConnectionInfo.h
new file mode 100644
index 0000000..895b87a
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConnectionInfo.h
@@ -0,0 +1,30 @@
+//
+// OpenVPNConnectionInfo.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Class used to provide extra details about successful connection
+ */
+@interface OpenVPNConnectionInfo : NSObject
+
+@property (nullable, readonly, nonatomic) NSString *user;
+@property (nullable, readonly, nonatomic) NSString *serverHost;
+@property (nullable, readonly, nonatomic) NSString *serverPort;
+@property (nullable, readonly, nonatomic) NSString *serverProto;
+@property (nullable, readonly, nonatomic) NSString *serverIP;
+@property (nullable, readonly, nonatomic) NSString *vpnIPv4;
+@property (nullable, readonly, nonatomic) NSString *vpnIPv6;
+@property (nullable, readonly, nonatomic) NSString *gatewayIPv4;
+@property (nullable, readonly, nonatomic) NSString *gatewayIPv6;
+@property (nullable, readonly, nonatomic) NSString *clientIP;
+@property (nullable, readonly, nonatomic) NSString *tunName;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNConnectionInfo.mm b/OpenVPN Adapter/OpenVPNConnectionInfo.mm
new file mode 100644
index 0000000..9854fa0
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNConnectionInfo.mm
@@ -0,0 +1,35 @@
+//
+// OpenVPNConnectionInfo.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import "OpenVPNConnectionInfo.h"
+#import "OpenVPNConnectionInfo+Internal.h"
+
+using namespace openvpn;
+
+@implementation OpenVPNConnectionInfo
+
+- (instancetype)initWithConnectionInfo:(ClientAPI::ConnectionInfo)info
+{
+ self = [super init];
+ if (self) {
+ _user = !info.user.empty() ? [NSString stringWithUTF8String:info.user.c_str()] : nil;
+ _serverHost = !info.serverHost.empty() ? [NSString stringWithUTF8String:info.serverHost.c_str()] : nil;
+ _serverPort = !info.serverPort.empty() ? [NSString stringWithUTF8String:info.serverPort.c_str()] : nil;
+ _serverProto = !info.serverProto.empty() ? [NSString stringWithUTF8String:info.serverProto.c_str()] : nil;
+ _serverIP = !info.serverIp.empty() ? [NSString stringWithUTF8String:info.serverIp.c_str()] : nil;
+ _vpnIPv4 = !info.vpnIp4.empty() ? [NSString stringWithUTF8String:info.vpnIp4.c_str()] : nil;
+ _vpnIPv6 = !info.vpnIp6.empty() ? [NSString stringWithUTF8String:info.vpnIp6.c_str()] : nil;
+ _gatewayIPv4 = !info.gw4.empty() ? [NSString stringWithUTF8String:info.gw4.c_str()] : nil;
+ _gatewayIPv6 = !info.gw6.empty() ? [NSString stringWithUTF8String:info.gw6.c_str()] : nil;
+ _clientIP = !info.clientIp.empty() ? [NSString stringWithUTF8String:info.clientIp.c_str()] : nil;
+ _tunName = !info.tunName.empty() ? [NSString stringWithUTF8String:info.tunName.c_str()] : nil;
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNCredentials+Internal.h b/OpenVPN Adapter/OpenVPNCredentials+Internal.h
new file mode 100644
index 0000000..bd6cb6f
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNCredentials+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNCredentials+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 24.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNCredentials.h"
+
+using namespace openvpn;
+
+@interface OpenVPNCredentials (Internal)
+
+@property (readonly) ClientAPI::ProvideCreds credentials;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNCredentials.h b/OpenVPN Adapter/OpenVPNCredentials.h
new file mode 100644
index 0000000..6c310c8
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNCredentials.h
@@ -0,0 +1,53 @@
+//
+// OpenVPNCredentials.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 24.04.17.
+//
+//
+
+#import
+
+/**
+ Class used to pass credentials
+ */
+@interface OpenVPNCredentials : NSObject
+
+/**
+ Client username
+ */
+@property (nullable, nonatomic) NSString *username;
+
+/**
+ Client password
+ */
+@property (nullable, nonatomic) NSString *password;
+
+/**
+ Response to challenge
+ */
+@property (nullable, nonatomic) NSString *response;
+
+/**
+ Dynamic challenge/response cookie
+ */
+@property (nullable, nonatomic) NSString *dynamicChallengeCookie;
+
+/**
+ If YES, on successful connect, we will replace the password
+ with the session ID we receive from the server (if provided).
+ If NO, the password will be cached for future reconnects
+ and will not be replaced with a session ID, even if the
+ server provides one.
+ */
+@property (nonatomic) BOOL replacePasswordWithSessionID;
+
+/**
+ If YES, and if replacePasswordWithSessionID is YES, and if
+ we actually receive a session ID from the server, cache
+ the user-provided password for future use before replacing
+ the active password with the session ID.
+ */
+@property (nonatomic) BOOL cachePassword;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNCredentials.mm b/OpenVPN Adapter/OpenVPNCredentials.mm
new file mode 100644
index 0000000..5c7bbf6
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNCredentials.mm
@@ -0,0 +1,78 @@
+//
+// OpenVPNCredentials.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 24.04.17.
+//
+//
+
+#import "OpenVPNCredentials.h"
+#import "OpenVPNCredentials+Internal.h"
+
+using namespace openvpn;
+
+@interface OpenVPNCredentials () {
+ ClientAPI::ProvideCreds _credentials;
+}
+
+@end
+
+@implementation OpenVPNCredentials (Internal)
+
+- (ClientAPI::ProvideCreds)credentials {
+ return _credentials;
+}
+
+@end
+
+@implementation OpenVPNCredentials
+
+- (NSString *)username {
+ return !_credentials.username.empty() ? [NSString stringWithUTF8String:_credentials.username.c_str()] : nil;
+}
+
+- (void)setUsername:(NSString *)username {
+ _credentials.username = username ? std::string([username UTF8String]) : "";
+}
+
+- (NSString *)password {
+ return !_credentials.password.empty() ? [NSString stringWithUTF8String:_credentials.password.c_str()] : nil;
+}
+
+- (void)setPassword:(NSString *)password {
+ _credentials.password = password ? std::string([password UTF8String]) : "";
+}
+
+- (NSString *)response {
+ return !_credentials.response.empty() ? [NSString stringWithUTF8String:_credentials.response.c_str()] : nil;
+}
+
+- (void)setResponse:(NSString *)response {
+ _credentials.response = response ? std::string([response UTF8String]) : "";
+}
+
+- (NSString *)dynamicChallengeCookie {
+ return !_credentials.dynamicChallengeCookie.empty() ? [NSString stringWithUTF8String:_credentials.dynamicChallengeCookie.c_str()] : nil;
+}
+
+- (void)setDynamicChallengeCookie:(NSString *)dynamicChallengeCookie {
+ _credentials.dynamicChallengeCookie = dynamicChallengeCookie ? std::string([dynamicChallengeCookie UTF8String]) : "";
+}
+
+- (BOOL)replacePasswordWithSessionID {
+ return _credentials.replacePasswordWithSessionID;
+}
+
+- (void)setReplacePasswordWithSessionID:(BOOL)replacePasswordWithSessionID {
+ _credentials.replacePasswordWithSessionID = replacePasswordWithSessionID;
+}
+
+- (BOOL)cachePassword {
+ return _credentials.cachePassword;
+}
+
+- (void)setCachePassword:(BOOL)cachePassword {
+ _credentials.cachePassword = cachePassword;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNError.h b/OpenVPN Adapter/OpenVPNError.h
index 4c202c7..9911d81 100644
--- a/OpenVPN Adapter/OpenVPNError.h
+++ b/OpenVPN Adapter/OpenVPNError.h
@@ -8,7 +8,6 @@
#import
-
extern NSString * __nonnull const OpenVPNAdapterErrorDomain;
extern NSString * __nonnull const OpenVPNAdapterErrorFatalKey;
@@ -16,9 +15,6 @@ extern NSString * __nonnull const OpenVPNAdapterErrorEventKey;
/**
<#Description#>
-
- - OpenVPNErrorConfigurationFailure: <#OpenVPNErrorConfigurationFailure description#>
- - OpenVPNErrorClientFailure: <#OpenVPNErrorClientFailure description#>
*/
typedef NS_ENUM(NSUInteger, OpenVPNError) {
OpenVPNErrorConfigurationFailure,
diff --git a/OpenVPN Adapter/OpenVPNEvent.h b/OpenVPN Adapter/OpenVPNEvent.h
index fae7e00..7a531dd 100644
--- a/OpenVPN Adapter/OpenVPNEvent.h
+++ b/OpenVPN Adapter/OpenVPNEvent.h
@@ -10,41 +10,6 @@
/**
<#Description#>
-
- - OpenVPNEventDisconnected: <#OpenVPNEventDisconnected description#>
- - OpenVPNEventConnected: <#OpenVPNEventConnected description#>
- - OpenVPNEventReconnecting: <#OpenVPNEventReconnecting description#>
- - OpenVPNEventResolve: <#OpenVPNEventResolve description#>
- - OpenVPNEventWait: <#OpenVPNEventWait description#>
- - OpenVPNEventWaitProxy: <#OpenVPNEventWaitProxy description#>
- - OpenVPNEventConnecting: <#OpenVPNEventConnecting description#>
- - OpenVPNEventGetConfig: <#OpenVPNEventGetConfig description#>
- - OpenVPNEventAssignIP: <#OpenVPNEventAssignIP description#>
- - OpenVPNEventAddRoutes: <#OpenVPNEventAddRoutes description#>
- - OpenVPNEventEcho: <#OpenVPNEventEcho description#>
- - OpenVPNEventInfo: <#OpenVPNEventInfo description#>
- - OpenVPNEventPause: <#OpenVPNEventPause description#>
- - OpenVPNEventResume: <#OpenVPNEventResume description#>
- - OpenVPNEventTransportError: <#OpenVPNEventTransportError description#>
- - OpenVPNEventTunError: <#OpenVPNEventTunError description#>
- - OpenVPNEventClientRestart: <#OpenVPNEventClientRestart description#>
- - OpenVPNEventAuthFailed: <#OpenVPNEventAuthFailed description#>
- - OpenVPNEventCertVerifyFail: <#OpenVPNEventCertVerifyFail description#>
- - OpenVPNEventTLSVersionMin: <#OpenVPNEventTLSVersionMin description#>
- - OpenVPNEventClientHalt: <#OpenVPNEventClientHalt description#>
- - OpenVPNEventConnectionTimeout: <#OpenVPNEventConnectionTimeout description#>
- - OpenVPNEventInactiveTimeout: <#OpenVPNEventInactiveTimeout description#>
- - OpenVPNEventDynamicChallenge: <#OpenVPNEventDynamicChallenge description#>
- - OpenVPNEventProxyNeedCreds: <#OpenVPNEventProxyNeedCreds description#>
- - OpenVPNEventProxyError: <#OpenVPNEventProxyError description#>
- - OpenVPNEventTunSetupFailed: <#OpenVPNEventTunSetupFailed description#>
- - OpenVPNEventTunIfaceCreate: <#OpenVPNEventTunIfaceCreate description#>
- - OpenVPNEventTunIfaceDisabled: <#OpenVPNEventTunIfaceDisabled description#>
- - OpenVPNEventEPKIError: <#OpenVPNEventEPKIError description#>
- - OpenVPNEventEPKIInvalidAlias: <#OpenVPNEventEPKIInvalidAlias description#>
- - OpenVPNEventInitializationFailed: <#OpenVPNEventInitializationFailed description#>
- - OpenVPNEventConnectionFailed: <#OpenVPNEventConnectionFailed description#>
- - OpenVPNEventUnknown: <#OpenVPNEventUnknown description#>
*/
typedef NS_ENUM(NSUInteger, OpenVPNEvent) {
OpenVPNEventDisconnected,
diff --git a/OpenVPN Adapter/OpenVPNIPv6Preference.h b/OpenVPN Adapter/OpenVPNIPv6Preference.h
new file mode 100644
index 0000000..6cfc051
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNIPv6Preference.h
@@ -0,0 +1,21 @@
+//
+// OpenVPNIPv6Preference.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ IPv6 preference options
+ */
+typedef NS_ENUM(NSInteger, OpenVPNIPv6Preference) {
+ /// Request combined IPv4/IPv6 tunnel
+ OpenVPNIPv6PreferenceEnabled,
+ /// Disable IPv6, so tunnel will be IPv4-only
+ OpenVPNIPv6PreferenceDisabled,
+ /// Leave decision to server
+ OpenVPNIPv6PreferenceDefault
+};
diff --git a/OpenVPN Adapter/OpenVPNInterfaceStats+Internal.h b/OpenVPN Adapter/OpenVPNInterfaceStats+Internal.h
new file mode 100644
index 0000000..9c58773
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNInterfaceStats+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNInterfaceStats+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNInterfaceStats.h"
+
+using namespace openvpn;
+
+@interface OpenVPNInterfaceStats (Internal)
+
+- (instancetype)initWithInterfaceStats:(ClientAPI::InterfaceStats)stats;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNInterfaceStats.h b/OpenVPN Adapter/OpenVPNInterfaceStats.h
new file mode 100644
index 0000000..81cddde
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNInterfaceStats.h
@@ -0,0 +1,48 @@
+//
+// OpenVPNInterfaceStats.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Class used to provide stats for an interface
+ */
+@interface OpenVPNInterfaceStats : NSObject
+
+/**
+ Amount of received bytes
+ */
+@property (readonly, nonatomic) NSInteger bytesIn;
+
+/**
+ Amout of sent bytes
+ */
+@property (readonly, nonatomic) NSInteger bytesOut;
+
+/**
+ Amount of received packets
+ */
+@property (readonly, nonatomic) NSInteger packetsIn;
+
+/**
+ Amout of sent packets
+ */
+@property (readonly, nonatomic) NSInteger packetsOut;
+
+/**
+ Amount of incoming packets handling errors
+ */
+@property (readonly, nonatomic) NSInteger errorsIn;
+
+/**
+ Amount of outgoing packets handling errors
+ */
+@property (readonly, nonatomic) NSInteger errorsOut;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNInterfaceStats.mm b/OpenVPN Adapter/OpenVPNInterfaceStats.mm
new file mode 100644
index 0000000..256a97c
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNInterfaceStats.mm
@@ -0,0 +1,27 @@
+//
+// OpenVPNInterfaceStats.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import "OpenVPNInterfaceStats.h"
+#import "OpenVPNInterfaceStats+Internal.h"
+
+@implementation OpenVPNInterfaceStats
+
+- (instancetype)initWithInterfaceStats:(ClientAPI::InterfaceStats)stats {
+ self = [super init];
+ if (self) {
+ _bytesIn = stats.bytesIn;
+ _bytesOut = stats.bytesOut;
+ _packetsIn = stats.packetsIn;
+ _packetsOut = stats.packetsOut;
+ _errorsIn = stats.errorsIn;
+ _errorsOut = stats.errorsOut;
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNMinTLSVersion.h b/OpenVPN Adapter/OpenVPNMinTLSVersion.h
new file mode 100644
index 0000000..deafb05
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNMinTLSVersion.h
@@ -0,0 +1,25 @@
+//
+// OpenVPNMinTLSVersion.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Minimum TLS version options
+ */
+typedef NS_ENUM(NSInteger, OpenVPNMinTLSVersion) {
+ /// Don't specify a minimum, and disable any minimum specified in profile
+ OpenVPNMinTLSVersionDisabled,
+ /// Use TLS 1.0 minimum (overrides profile)
+ OpenVPNMinTLSVersion10,
+ /// Use TLS 1.1 minimum (overrides profile)
+ OpenVPNMinTLSVersion11,
+ /// Use TLS 1.2 minimum (overrides profile)
+ OpenVPNMinTLSVersion12,
+ /// Use profile minimum
+ OpenVPNMinTLSVersionDefault
+};
diff --git a/OpenVPN Adapter/OpenVPNProperties+Internal.h b/OpenVPN Adapter/OpenVPNProperties+Internal.h
new file mode 100644
index 0000000..c4f0ea9
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNProperties+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNProperties+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNProperties.h"
+
+using namespace openvpn;
+
+@interface OpenVPNProperties (Internal)
+
+- (instancetype)initWithEvalConfig:(ClientAPI::EvalConfig)eval;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNProperties.h b/OpenVPN Adapter/OpenVPNProperties.h
new file mode 100644
index 0000000..1182d2d
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNProperties.h
@@ -0,0 +1,79 @@
+//
+// OpenVPNProperties.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNTransportProtocol.h"
+
+@class OpenVPNServerEntry;
+
+@interface OpenVPNProperties : NSObject
+
+/**
+ This username must be used with profile
+ */
+@property (nullable, readonly, nonatomic) NSString *username;
+
+/**
+ Profile name of config
+ */
+@property (nullable, readonly, nonatomic) NSString *profileName;
+
+/**
+ "Friendly" name of config
+ */
+@property (nullable, readonly, nonatomic) NSString *friendlyName;
+
+/**
+ If YES no creds required, otherwise username/password required
+ */
+@property (readonly, nonatomic) BOOL autologin;
+
+/**
+ Static challenge, may be empty, ignored if autologin
+ */
+@property (nullable, readonly, nonatomic) NSString *staticChallenge;
+
+/**
+ YES if static challenge response should be echoed to UI, ignored if autologin
+ */
+@property (readonly, nonatomic) BOOL staticChallengeEcho;
+
+/**
+ YES if this profile requires a private key password
+ */
+@property (readonly, nonatomic) BOOL privateKeyPasswordRequired;
+
+/**
+ YES if user is allowed to save authentication password in UI
+ */
+@property (readonly, nonatomic) BOOL allowPasswordSave;
+
+/**
+ Address of the first remote item in config
+ */
+@property (nullable, readonly, nonatomic) NSString *remoteHost;
+
+/**
+ Port of the first remote item in config
+ */
+@property (readonly, nonatomic) NSUInteger remotePort;
+
+/**
+ Transport protocol of the first remote item in config
+ */
+@property (readonly, nonatomic) OpenVPNTransportProtocol remoteProto;
+
+/**
+ Optional list of user-selectable VPN servers
+ */
+@property (nullable, readonly, nonatomic) NSArray *servers;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNProperties.mm b/OpenVPN Adapter/OpenVPNProperties.mm
new file mode 100644
index 0000000..edf54a7
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNProperties.mm
@@ -0,0 +1,61 @@
+//
+// OpenVPNProperties.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNConfiguration+Internal.h"
+#import "OpenVPNServerEntry+Internal.h"
+#import "OpenVPNProperties.h"
+#import "OpenVPNProperties+Internal.h"
+
+using namespace openvpn;
+
+@implementation OpenVPNProperties
+
+- (instancetype)initWithEvalConfig:(ClientAPI::EvalConfig)eval {
+ self = [super init];
+ if (self) {
+ _username = !eval.userlockedUsername.empty() ? [NSString stringWithUTF8String:eval.userlockedUsername.c_str()] : nil;
+
+ _profileName = !eval.profileName.empty() ? [NSString stringWithUTF8String:eval.profileName.c_str()] : nil;
+ _friendlyName = !eval.friendlyName.empty() ? [NSString stringWithUTF8String:eval.friendlyName.c_str()] : nil;
+
+ _autologin = eval.autologin;
+
+ _staticChallenge = !eval.staticChallenge.empty() ? [NSString stringWithUTF8String:eval.staticChallenge.c_str()] : nil;
+ _staticChallengeEcho = eval.staticChallengeEcho;
+
+ _privateKeyPasswordRequired = eval.privateKeyPasswordRequired;
+ _allowPasswordSave = eval.allowPasswordSave;
+
+ _remoteHost = !eval.remoteHost.empty() ? [NSString stringWithUTF8String:eval.remoteHost.c_str()] : nil;
+
+ uint16_t port = 0;
+ parse_number(eval.remotePort, port);
+
+ _remotePort = port;
+
+ NSString *currentProto = [NSString stringWithUTF8String:eval.remoteProto.c_str()];
+ _remoteProto = [OpenVPNConfiguration getTransportProtocolFromValue:currentProto];
+
+ _servers = nil;
+ if (!eval.serverList.empty()) {
+ NSMutableArray *servers = [NSMutableArray new];
+
+ for (ClientAPI::ServerEntry entry : eval.serverList) {
+ OpenVPNServerEntry *serverEntry = [[OpenVPNServerEntry alloc] initWithServerEntry:entry];
+ [servers addObject:serverEntry];
+ }
+
+ _servers = servers;
+ }
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNServerEntry+Internal.h b/OpenVPN Adapter/OpenVPNServerEntry+Internal.h
new file mode 100644
index 0000000..e8685f5
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNServerEntry+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNServerEntry+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNServerEntry.h"
+
+using namespace openvpn;
+
+@interface OpenVPNServerEntry (Internal)
+
+- (instancetype)initWithServerEntry:(ClientAPI::ServerEntry)entry;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNServerEntry.h b/OpenVPN Adapter/OpenVPNServerEntry.h
new file mode 100644
index 0000000..75ecb40
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNServerEntry.h
@@ -0,0 +1,18 @@
+//
+// OpenVPNServerEntry.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+@interface OpenVPNServerEntry : NSObject
+
+@property (nullable, readonly, nonatomic) NSString *server;
+@property (nullable, readonly, nonatomic) NSString *friendlyName;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNServerEntry.mm b/OpenVPN Adapter/OpenVPNServerEntry.mm
new file mode 100644
index 0000000..b87e7d0
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNServerEntry.mm
@@ -0,0 +1,23 @@
+//
+// OpenVPNServerEntry.mm
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import "OpenVPNServerEntry.h"
+#import "OpenVPNServerEntry+Internal.h"
+
+@implementation OpenVPNServerEntry
+
+- (instancetype)initWithServerEntry:(ClientAPI::ServerEntry)entry {
+ self = [super init];
+ if (self) {
+ _server = !entry.server.empty() ? [NSString stringWithUTF8String:entry.server.c_str()] : nil;
+ _friendlyName = !entry.friendlyName.empty() ? [NSString stringWithUTF8String:entry.friendlyName.c_str()] : nil;
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNSessionToken+Internal.h b/OpenVPN Adapter/OpenVPNSessionToken+Internal.h
new file mode 100644
index 0000000..667bf3b
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNSessionToken+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNSessionToken+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 28.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNSessionToken.h"
+
+using namespace openvpn;
+
+@interface OpenVPNSessionToken (Internal)
+
+- (instancetype)initWithSessionToken:(ClientAPI::SessionToken)token;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNSessionToken.h b/OpenVPN Adapter/OpenVPNSessionToken.h
new file mode 100644
index 0000000..c7bbb42
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNSessionToken.h
@@ -0,0 +1,25 @@
+//
+// OpenVPNSessionToken.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 28.04.17.
+//
+//
+
+#import
+
+/**
+ Class used to get session token from VPN core
+ */
+@interface OpenVPNSessionToken : NSObject
+
+@property (nullable, readonly, nonatomic) NSString *username;
+
+/**
+ An OpenVPN Session ID, used as a proxy for password
+ */
+@property (nullable, readonly, nonatomic) NSString *session;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNSessionToken.mm b/OpenVPN Adapter/OpenVPNSessionToken.mm
new file mode 100644
index 0000000..027e0f9
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNSessionToken.mm
@@ -0,0 +1,24 @@
+//
+// OpenVPNSessionToken.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 28.04.17.
+//
+//
+
+#import "OpenVPNSessionToken+Internal.h"
+
+using namespace openvpn;
+
+@implementation OpenVPNSessionToken
+
+- (instancetype)initWithSessionToken:(ClientAPI::SessionToken)token {
+ self = [super init];
+ if (self) {
+ _username = !token.username.empty() ? [NSString stringWithUTF8String:token.username.c_str()] : nil;
+ _session = !token.session_id.empty() ? [NSString stringWithUTF8String:token.session_id.c_str()] : nil;
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNTLSCertProfile.h b/OpenVPN Adapter/OpenVPNTLSCertProfile.h
new file mode 100644
index 0000000..6893379
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNTLSCertProfile.h
@@ -0,0 +1,27 @@
+//
+// OpenVPNTLSCertProfile.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Options of the tls-cert-profile setting
+ */
+typedef NS_ENUM(NSInteger, OpenVPNTLSCertProfile) {
+ /// Allow 1024-bit RSA certs signed with SHA1
+ OpenVPNTLSCertProfileLegacy,
+ /// Require at least 2048-bit RSA certs signed with SHA256 or higher
+ OpenVPNTLSCertProfilePreferred,
+ /// Require NSA Suite-B
+ OpenVPNTLSCertProfileSuiteB,
+ /// Use legacy as the default if profile doesn't specify tls-cert-profile
+ OpenVPNTLSCertProfileLegacyDefault,
+ /// Use preferred as the default if profile doesn't specify tls-cert-profile
+ OpenVPNTLSCertProfilePreferredDefault,
+ /// Use profile default
+ OpenVPNTLSCertProfileDefault
+};
diff --git a/OpenVPN Adapter/OpenVPNTransportProtocol.h b/OpenVPN Adapter/OpenVPNTransportProtocol.h
new file mode 100644
index 0000000..64a83c8
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNTransportProtocol.h
@@ -0,0 +1,23 @@
+//
+// OpenVPNTransportProtocol.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Transport protocol options
+ */
+typedef NS_ENUM(NSInteger, OpenVPNTransportProtocol) {
+ ///
+ OpenVPNTransportProtocolUDP,
+ ///
+ OpenVPNTransportProtocolTCP,
+ ///
+ OpenVPNTransportProtocolAdaptive,
+ /// Use a transport protocol specified in the profile
+ OpenVPNTransportProtocolDefault
+};
diff --git a/OpenVPN Adapter/OpenVPNTransportStats+Internal.h b/OpenVPN Adapter/OpenVPNTransportStats+Internal.h
new file mode 100644
index 0000000..974d694
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNTransportStats+Internal.h
@@ -0,0 +1,19 @@
+//
+// OpenVPNTransportStats+Internal.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+#import "OpenVPNTransportStats.h"
+
+using namespace openvpn;
+
+@interface OpenVPNTransportStats (Internal)
+
+- (instancetype)initWithTransportStats:(ClientAPI::TransportStats)stats;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNTransportStats.h b/OpenVPN Adapter/OpenVPNTransportStats.h
new file mode 100644
index 0000000..7c07003
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNTransportStats.h
@@ -0,0 +1,44 @@
+//
+// OpenVPNTransportStats.h
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import
+
+/**
+ Class used to provide basic transport stats
+ */
+@interface OpenVPNTransportStats : NSObject
+
+/**
+ Amount of received bytes
+ */
+@property (readonly, nonatomic) NSInteger bytesIn;
+
+/**
+ Amout of sent bytes
+ */
+@property (readonly, nonatomic) NSInteger bytesOut;
+
+/**
+ Amount of received packets
+ */
+@property (readonly, nonatomic) NSInteger packetsIn;
+
+/**
+ Amout of sent packets
+ */
+@property (readonly, nonatomic) NSInteger packetsOut;
+
+/**
+ Number of binary milliseconds (1/1024th of a second) since
+ last packet was received, or -1 if undefined
+ */
+@property (readonly, nonatomic) NSInteger lastPacketReceived;
+
+- (nonnull instancetype) __unavailable init;
+
+@end
diff --git a/OpenVPN Adapter/OpenVPNTransportStats.mm b/OpenVPN Adapter/OpenVPNTransportStats.mm
new file mode 100644
index 0000000..bb7cb83
--- /dev/null
+++ b/OpenVPN Adapter/OpenVPNTransportStats.mm
@@ -0,0 +1,28 @@
+//
+// OpenVPNTransportStats.m
+// OpenVPN Adapter
+//
+// Created by Sergey Abramchuk on 26.04.17.
+//
+//
+
+#import "OpenVPNTransportStats+Internal.h"
+
+using namespace openvpn;
+
+@implementation OpenVPNTransportStats
+
+- (instancetype)initWithTransportStats:(ClientAPI::TransportStats)stats
+{
+ self = [super init];
+ if (self) {
+ _bytesIn = stats.bytesIn;
+ _bytesOut = stats.bytesOut;
+ _packetsIn = stats.packetsIn;
+ _packetsOut = stats.packetsOut;
+ _lastPacketReceived = stats.lastPacketReceived;
+ }
+ return self;
+}
+
+@end
diff --git a/OpenVPN Adapter/Umbrella-Header.h b/OpenVPN Adapter/Umbrella-Header.h
index eca3f8d..96c85a6 100644
--- a/OpenVPN Adapter/Umbrella-Header.h
+++ b/OpenVPN Adapter/Umbrella-Header.h
@@ -18,5 +18,18 @@ FOUNDATION_EXPORT const unsigned char OpenVPNAdapterVersionString[];
#import
#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
#import
#import
diff --git a/OpenVPN Adapter/Vendors/openvpn/openvpn/common/hexstr.hpp b/OpenVPN Adapter/Vendors/openvpn/openvpn/common/hexstr.hpp
index e0a2f41..caf2e4e 100644
--- a/OpenVPN Adapter/Vendors/openvpn/openvpn/common/hexstr.hpp
+++ b/OpenVPN Adapter/Vendors/openvpn/openvpn/common/hexstr.hpp
@@ -180,7 +180,7 @@ namespace openvpn {
dest.push_back((high<<4) + low);
}
if (i != len)
- throw parse_hex_error(); // straggler char
+ throw parse_hex_error(); // straggler char
}
// note -- currently doesn't detect overflow
@@ -226,7 +226,7 @@ namespace openvpn {
}
template
- std::string render_hex_number(T value, const bool caps=false)
+ inline std::string render_hex_number(T value, const bool caps=false)
{
unsigned char buf[sizeof(T)];
for (size_t i = sizeof(T); i --> 0 ;)
@@ -237,7 +237,7 @@ namespace openvpn {
return render_hex(buf, sizeof(T), caps);
}
- std::string render_hex_number(unsigned char uc, const bool caps=false)
+ inline std::string render_hex_number(unsigned char uc, const bool caps=false)
{
RenderHexByte b(uc, caps);
return std::string(b.str2(), 2);