diff --git a/Configuration/Framework.xcconfig b/Configuration/Framework.xcconfig
index 7925bcc..bb9aef2 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
+OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_EXTERNAL_TUN_FACTORY
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/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..a50537f 100644
--- a/OpenVPN Adapter.xcodeproj/project.pbxproj
+++ b/OpenVPN Adapter.xcodeproj/project.pbxproj
@@ -11,11 +11,67 @@
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 +81,14 @@
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 */; };
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 +100,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 */; };
@@ -75,12 +135,39 @@
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 +177,9 @@
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 = ""; };
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 +269,73 @@
name = Frameworks;
sourceTree = "";
};
+ C9235AC41EB24F0100C7D303 /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ 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 +346,7 @@
C9BB47641E7169AF00F3F98C /* Libraries */ = {
isa = PBXGroup;
children = (
+ C9FF73B71EB7421600E995AC /* Helpers */,
C9BB47681E716ABF00F3F98C /* Vendors */,
);
name = Libraries;
@@ -208,12 +363,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 */,
@@ -253,6 +402,7 @@
isa = PBXGroup;
children = (
C99E2FEF1EA7E20700A6518B /* free_openvpn_udp_us.ovpn */,
+ C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */,
);
path = Resources;
sourceTree = "";
@@ -260,6 +410,7 @@
C9BB479D1E71837200F3F98C /* Adapter Tests */ = {
isa = PBXGroup;
children = (
+ C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */,
C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */,
);
name = "Adapter Tests";
@@ -285,10 +436,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 +457,34 @@
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 */,
+ 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 +493,34 @@
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 */,
+ 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 +612,7 @@
TargetAttributes = {
C9BB475B1E71663A00F3F98C = {
CreatedOnToolsVersion = 8.2.1;
+ LastSwiftMigration = 0830;
ProvisioningStyle = Manual;
};
C9BB478D1E71821A00F3F98C = {
@@ -461,6 +662,7 @@
buildActionMask = 2147483647;
files = (
C99E2FF01EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */,
+ C98467A21EAA559B00272A9A /* local_vpn_server.ovpn in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -476,6 +678,7 @@
buildActionMask = 2147483647;
files = (
C99E2FF11EA7E20700A6518B /* free_openvpn_udp_us.ovpn in Resources */,
+ C98467A31EAA559B00272A9A /* local_vpn_server.ovpn in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -517,10 +720,17 @@
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 */,
+ 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 +738,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 +749,17 @@
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 */,
+ 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 +767,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 +794,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 +823,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 +850,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 +882,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 +899,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 +930,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 +946,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 +999,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 +1046,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 +1097,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..bbc2593 100644
--- a/OpenVPN Adapter/OpenVPNAdapter+Internal.h
+++ b/OpenVPN Adapter/OpenVPNAdapter+Internal.h
@@ -10,29 +10,12 @@
#import "OpenVPNAdapter.h"
-
using namespace openvpn;
-@interface OpenVPNAdapter (Client)
-
-- (BOOL)configureSockets;
-
-- (BOOL)setRemoteAddress:(NSString *)address isIPv6:(BOOL)isIPv6;
-
-- (BOOL)addLocalAddress:(NSString *)address prefixLength:(NSNumber *)prefixLength gateway:(NSString *)gateway isIPv6:(BOOL)isIPv6;
-
-- (BOOL)defaultGatewayRerouteIPv4:(BOOL)rerouteIPv4 rerouteIPv6:(BOOL)rerouteIPv6;
-- (BOOL)addRoute:(NSString *)route prefixLength:(NSNumber *)prefixLength isIPv6:(BOOL)isIPv6;
-- (BOOL)excludeRoute:(NSString *)route prefixLength:(NSNumber *)prefixLength isIPv6:(BOOL)isIPv6;
-
-- (BOOL)addDNSAddress:(NSString *)address isIPv6:(BOOL)isIPv6;
-- (BOOL)addSearchDomain:(NSString *)domain;
-
-- (BOOL)setMTU:(NSNumber *)mtu;
-
-- (NSInteger)establishTunnel;
+@interface OpenVPNAdapter (Internal)
- (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..50dc92e 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,16 @@
#import
+#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,280 +33,20 @@ 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;
}
@property OpenVPNClient *vpnClient;
-@property CFSocketRef vpnSocket;
-@property CFSocketRef tunSocket;
-
-@property (strong, nonatomic) NSString *remoteAddress;
-
-@property (strong, nonatomic) NSString *defaultGatewayIPv6;
-@property (strong, nonatomic) NSString *defaultGatewayIPv4;
-
-@property (strong, nonatomic) TUNConfiguration *tunConfigurationIPv6;
-@property (strong, nonatomic) TUNConfiguration *tunConfigurationIPv4;
-
-@property (strong, nonatomic) NSMutableArray *searchDomains;
-
-@property (strong, nonatomic) NSNumber *mtu;
-
@property (weak, nonatomic) id packetFlow;
-- (void)readTUNPackets;
-- (void)readVPNData:(NSData *)data;
+- (OpenVPNEvent)getEventIdentifierByName:(NSString *)eventName;
- (NSString *)getSubnetFromPrefixLength:(NSNumber *)prefixLength;
@end
-@implementation OpenVPNAdapter (Client)
-
-#pragma mark Sockets Configuration
-
-static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
- OpenVPNAdapter *adapter = (__bridge OpenVPNAdapter *)info;
-
- switch (type) {
- case kCFSocketDataCallBack:
- [adapter readVPNData:(__bridge NSData *)data];
- break;
-
- default:
- break;
- }
-}
-
-- (BOOL)configureSockets {
- int sockets[2];
- if (socketpair(PF_LOCAL, SOCK_DGRAM, IPPROTO_IP, sockets) == -1) {
- NSLog(@"Failed to create a pair of connected sockets: %@", [NSString stringWithUTF8String:strerror(errno)]);
- return NO;
- }
-
- CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL};
-
- self.vpnSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sockets[0], kCFSocketDataCallBack, &socketCallback, &socketCtxt);
- self.tunSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sockets[1], kCFSocketNoCallBack, NULL, NULL);
-
- if (!self.vpnSocket || !self.tunSocket) {
- NSLog(@"Failed to create core foundation sockets from native sockets");
- return NO;
- }
-
- CFRunLoopSourceRef tunSocketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.vpnSocket, 0);
- CFRunLoopAddSource(CFRunLoopGetMain(), tunSocketSource, kCFRunLoopDefaultMode);
-
- CFRelease(tunSocketSource);
-
- return YES;
-}
-
-#pragma mark TUN Configuration
-
-- (BOOL)setRemoteAddress:(NSString *)address isIPv6:(BOOL)isIPv6 {
- if (address == nil) {
- return NO;
- }
-
- self.remoteAddress = address;
-
- return YES;
-}
-
-- (BOOL)addLocalAddress:(NSString *)address prefixLength:(NSNumber *)prefixLength gateway:(NSString *)gateway isIPv6:(BOOL)isIPv6 {
- if (address == nil || prefixLength == nil) {
- return NO;
- }
-
- if (isIPv6) {
- if (!self.tunConfigurationIPv6.initialized) {
- self.tunConfigurationIPv6.initialized = YES;
- }
-
- self.defaultGatewayIPv6 = gateway;
-
- [self.tunConfigurationIPv6.localAddresses addObject:address];
- [self.tunConfigurationIPv6.prefixLengths addObject:prefixLength];
- } else {
- if (!self.tunConfigurationIPv4.initialized) {
- self.tunConfigurationIPv4.initialized = YES;
- }
-
- self.defaultGatewayIPv4 = gateway;
-
- [self.tunConfigurationIPv4.localAddresses addObject:address];
- [self.tunConfigurationIPv4.prefixLengths addObject:prefixLength];
- }
-
- return YES;
-}
-
-- (BOOL)defaultGatewayRerouteIPv4:(BOOL)rerouteIPv4 rerouteIPv6:(BOOL)rerouteIPv6 {
- if (rerouteIPv6) {
- NEIPv6Route *includedRoute = [NEIPv6Route defaultRoute];
- includedRoute.gatewayAddress = self.defaultGatewayIPv6;
-
- [self.tunConfigurationIPv6.includedRoutes addObject:includedRoute];
- }
-
- if (rerouteIPv4) {
- NEIPv4Route *includedRoute = [NEIPv4Route defaultRoute];
- includedRoute.gatewayAddress = self.defaultGatewayIPv4;
-
- [self.tunConfigurationIPv4.includedRoutes addObject:includedRoute];
- }
-
- return YES;
-}
-
-- (BOOL)addRoute:(NSString *)route prefixLength:(NSNumber *)prefixLength isIPv6:(BOOL)isIPv6 {
- if (route == nil || prefixLength == nil) {
- return NO;
- }
-
- if (isIPv6) {
- NEIPv6Route *includedRoute = [[NEIPv6Route alloc] initWithDestinationAddress:route networkPrefixLength:prefixLength];
- includedRoute.gatewayAddress = self.defaultGatewayIPv6;
-
- [self.tunConfigurationIPv6.includedRoutes addObject:includedRoute];
- } else {
- NSString *subnet = [self getSubnetFromPrefixLength:prefixLength];
-
- NEIPv4Route *includedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnet];
- includedRoute.gatewayAddress = self.defaultGatewayIPv4;
-
- [self.tunConfigurationIPv4.includedRoutes addObject:includedRoute];
- }
-
- return YES;
-}
-
-- (BOOL)excludeRoute:(NSString *)route prefixLength:(NSNumber *)prefixLength isIPv6:(BOOL)isIPv6 {
- if (route == nil || prefixLength == nil) {
- return NO;
- }
-
- if (isIPv6) {
- NEIPv6Route *excludedRoute = [[NEIPv6Route alloc] initWithDestinationAddress:route networkPrefixLength:prefixLength];
- [self.tunConfigurationIPv6.excludedRoutes addObject:excludedRoute];
- } else {
- NSString *subnet = [self getSubnetFromPrefixLength:prefixLength];
- NEIPv4Route *excludedRoute = [[NEIPv4Route alloc] initWithDestinationAddress:route subnetMask:subnet];
- [self.tunConfigurationIPv4.excludedRoutes addObject:excludedRoute];
- }
-
- return YES;
-}
-
-- (BOOL)addDNSAddress:(NSString *)address isIPv6:(BOOL)isIPv6 {
- if (address == nil) {
- return NO;
- }
-
- if (isIPv6) {
- [self.tunConfigurationIPv6.dnsAddresses addObject:address];
- } else {
- [self.tunConfigurationIPv4.dnsAddresses addObject:address];
- }
-
- return YES;
-}
-
-- (BOOL)addSearchDomain:(NSString *)domain {
- if (domain == nil) {
- return NO;
- }
-
- [self.searchDomains addObject:domain];
-
- return YES;
-}
-
-- (BOOL)setMTU:(NSNumber *)mtu {
- self.mtu = mtu;
- return YES;
-}
-
-- (NSInteger)establishTunnel {
- NSAssert(self.delegate != nil, @"delegate property should not be nil");
-
- NEPacketTunnelNetworkSettings *networkSettings = [[NEPacketTunnelNetworkSettings alloc] initWithTunnelRemoteAddress:self.remoteAddress];
-
- // Configure IPv6 addresses and routes
- if (self.tunConfigurationIPv6.initialized) {
- NEIPv6Settings *settingsIPv6 = [[NEIPv6Settings alloc] initWithAddresses:self.tunConfigurationIPv6.localAddresses networkPrefixLengths:self.tunConfigurationIPv6.prefixLengths];
- settingsIPv6.includedRoutes = self.tunConfigurationIPv6.includedRoutes;
- settingsIPv6.excludedRoutes = self.tunConfigurationIPv6.excludedRoutes;
-
- networkSettings.IPv6Settings = settingsIPv6;
- }
-
- // Configure IPv4 addresses and routes
- if (self.tunConfigurationIPv4.initialized) {
- NSMutableArray *subnets = [NSMutableArray new];
- [self.tunConfigurationIPv4.prefixLengths enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- NSString *subnet = [self getSubnetFromPrefixLength:obj];
- [subnets addObject:subnet];
- }];
-
- NEIPv4Settings *ipSettings = [[NEIPv4Settings alloc] initWithAddresses:self.tunConfigurationIPv4.localAddresses subnetMasks:subnets];
- ipSettings.includedRoutes = self.tunConfigurationIPv4.includedRoutes;
- ipSettings.excludedRoutes = self.tunConfigurationIPv4.excludedRoutes;
-
- networkSettings.IPv4Settings = ipSettings;
- }
-
- // Configure DNS addresses and search domains
- NSMutableArray *dnsAddresses = [NSMutableArray new];
-
- if (self.tunConfigurationIPv6.dnsAddresses.count > 0) {
- [dnsAddresses addObjectsFromArray:self.tunConfigurationIPv6.dnsAddresses];
- }
-
- if (self.tunConfigurationIPv4.dnsAddresses.count > 0) {
- [dnsAddresses addObjectsFromArray:self.tunConfigurationIPv4.dnsAddresses];
- }
-
- if (dnsAddresses.count > 0) {
- networkSettings.DNSSettings = [[NEDNSSettings alloc] initWithServers:dnsAddresses];
- }
-
- if (networkSettings.DNSSettings && self.searchDomains.count > 0) {
- networkSettings.DNSSettings.searchDomains = self.searchDomains;
- }
-
- // Set MTU
- networkSettings.MTU = self.mtu;
-
- // Establish TUN interface
- dispatch_semaphore_t sema = dispatch_semaphore_create(0);
-
- [self.delegate configureTunnelWithSettings:networkSettings callback:^(id _Nullable flow) {
- self.packetFlow = flow;
- dispatch_semaphore_signal(sema);
- }];
-
- // Wait 10 seconds
- dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);
- if (dispatch_semaphore_wait(sema, timeout) != 0) {
- NSLog(@"Failed to establish tunnel in a reasonable time");
- return -1;
- }
-
- if (self.packetFlow) {
- [self readTUNPackets];
- return CFSocketGetNative(self.tunSocket);
- } else {
- return -1;
- }
-}
+@implementation OpenVPNAdapter (Internal)
#pragma mark Event and Log Handlers
@@ -335,69 +80,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 +120,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()]
@@ -451,13 +172,8 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
- (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, ^{
- self.tunConfigurationIPv6 = [TUNConfiguration new];
- self.tunConfigurationIPv4 = [TUNConfiguration new];
-
- self.searchDomains = [NSMutableArray new];
-
OpenVPNClient::init_process();
try {
@@ -480,28 +196,22 @@ static void socketCallback(CFSocketRef socket, CFSocketCallBackType type, CFData
}
OpenVPNClient::uninit_process();
-
- self.remoteAddress = nil;
-
- self.tunConfigurationIPv6 = nil;
- self.tunConfigurationIPv4 = nil;
-
- self.searchDomains = nil;
-
- self.mtu = nil;
-
- if (self.vpnSocket) {
- CFSocketInvalidate(self.vpnSocket);
- CFRelease(self.vpnSocket);
- }
-
- if (self.tunSocket) {
- CFSocketInvalidate(self.tunSocket);
- CFRelease(self.tunSocket);
- }
});
}
+- (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,61 +226,53 @@ 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;
}
-#pragma mark TUN -> OpenVPN
-
-- (void)readTUNPackets {
- [self.packetFlow readPacketsWithCompletionHandler:^(NSArray * _Nonnull packets, NSArray * _Nonnull protocols) {
- [packets enumerateObjectsUsingBlock:^(NSData * data, NSUInteger idx, BOOL * stop) {
- // Prepend data with network protocol. It should be done because OpenVPN uses uint32_t prefixes containing network protocol.
- NSNumber *protocol = protocols[idx];
- uint32_t prefix = CFSwapInt32HostToBig((uint32_t)[protocol unsignedIntegerValue]);
-
- NSMutableData *packet = [NSMutableData new];
- [packet appendBytes:&prefix length:sizeof(prefix)];
- [packet appendData:data];
-
- // Send data to the VPN server
- CFSocketSendData(self.vpnSocket, NULL, (CFDataRef)packet, 0.05);
- }];
-
- [self readTUNPackets];
- }];
-}
-
-#pragma mark OpenVPN -> TUN
-
-- (void)readVPNData:(NSData *)data {
- // Get network protocol from data
- NSUInteger prefixSize = sizeof(uint32_t);
-
- if (data.length < prefixSize) {
- NSLog(@"Incorrect OpenVPN packet size");
- return;
- }
-
- uint32_t protocol = UINT32_MAX;
- [data getBytes:&protocol length:prefixSize];
-
- protocol = CFSwapInt32BigToHost(protocol);
-
- // Send the packet to the TUN interface
- NSData *packet = [data subdataWithRange:NSMakeRange(prefixSize, data.length - prefixSize)];
- if (![self.packetFlow writePackets:@[packet] withProtocols:@[@(protocol)]]) {
- NSLog(@"Failed to send OpenVPN packet to the TUN interface");
- }
-}
-
#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..dac4247 100644
--- a/OpenVPN Adapter/OpenVPNClient.h
+++ b/OpenVPN Adapter/OpenVPNClient.h
@@ -6,54 +6,20 @@
//
//
+#import
#import
-
using namespace openvpn;
-class OpenVPNClient : public ClientAPI::OpenVPNClient
+class OpenVPNClient : public ClientAPI::OpenVPNClient, public TunClientFactory
{
public:
- OpenVPNClient(void * adapter);
+ OpenVPNClient(void* adapter);
- virtual bool tun_builder_new() override;
-
- virtual bool tun_builder_set_remote_address(const std::string& address, bool ipv6) override;
- virtual bool tun_builder_add_address(const std::string& address,
- int prefix_length,
- const std::string& gateway,
- bool ipv6,
- bool net30) override;
- virtual bool tun_builder_reroute_gw(bool ipv4,
- bool ipv6,
- unsigned int flags) override;
- virtual bool tun_builder_add_route(const std::string& address,
- int prefix_length,
- int metric,
- bool ipv6) override;
- virtual bool tun_builder_exclude_route(const std::string& address,
- int prefix_length,
- int metric,
- bool ipv6) override;
- virtual bool tun_builder_add_dns_server(const std::string& address, bool ipv6) override;
- virtual bool tun_builder_add_search_domain(const std::string& domain) override;
- virtual bool tun_builder_set_mtu(int mtu) override;
- virtual bool tun_builder_set_session_name(const std::string& name) override;
- virtual bool tun_builder_add_proxy_bypass(const std::string& bypass_host) override;
- virtual bool tun_builder_set_proxy_auto_config_url(const std::string& url) override;
- virtual bool tun_builder_set_proxy_http(const std::string& host, int port) override;
- virtual bool tun_builder_set_proxy_https(const std::string& host, int port) override;
- virtual bool tun_builder_add_wins_server(const std::string& address) override;
-
- virtual int tun_builder_establish() override;
-
- virtual bool tun_builder_persist() override;
- virtual void tun_builder_establish_lite() override;
-
- virtual void tun_builder_teardown(bool disconnect) override;
+ virtual TunClientFactory* new_tun_factory(const ExternalTun::Config& conf, const OptionList& opt) override;
+ virtual TunClient::Ptr new_tun_client_obj(openvpn_io::io_context& io_context, TunClientParent& parent, TransportClient* transcli) override;
virtual bool socket_protect(int socket) override;
-
virtual bool pause_on_connection_timeout() override;
virtual void external_pki_cert_request(ClientAPI::ExternalPKICertRequest& certreq) override;
@@ -62,8 +28,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..b7168cb 100644
--- a/OpenVPN Adapter/OpenVPNClient.mm
+++ b/OpenVPN Adapter/OpenVPNClient.mm
@@ -6,119 +6,42 @@
//
//
-#import
-
#import
#import "OpenVPNAdapter+Internal.h"
-
#import "OpenVPNClient.h"
-
-OpenVPNClient::OpenVPNClient(void *adapter) : ClientAPI::OpenVPNClient() {
+OpenVPNClient::OpenVPNClient(void* adapter) : ClientAPI::OpenVPNClient() {
this->adapter = adapter;
}
-bool OpenVPNClient::tun_builder_new() {
- return [(__bridge OpenVPNAdapter *)adapter configureSockets];
+TunClientFactory* OpenVPNClient::new_tun_factory(const ExternalTun::Config& conf, const OptionList& opt) {
+ return this;
}
-bool OpenVPNClient::tun_builder_set_remote_address(const std::string &address, bool ipv6) {
- NSString *remoteAddress = [NSString stringWithUTF8String:address.c_str()];
- return [(__bridge OpenVPNAdapter *)adapter setRemoteAddress:remoteAddress isIPv6:ipv6];
-}
-
-bool OpenVPNClient::tun_builder_add_address(const std::string &address, int prefix_length, const std::string &gateway, bool ipv6, bool net30) {
- NSString *localAddress = [NSString stringWithUTF8String:address.c_str()];
- NSString *gatewayAddress = [NSString stringWithUTF8String:gateway.c_str()];
-
- return [(__bridge OpenVPNAdapter *)adapter addLocalAddress:localAddress prefixLength:@(prefix_length) gateway:gatewayAddress isIPv6:ipv6];
-}
-
-bool OpenVPNClient::tun_builder_reroute_gw(bool ipv4, bool ipv6, unsigned int flags) {
- return [(__bridge OpenVPNAdapter *)adapter defaultGatewayRerouteIPv4:ipv4 rerouteIPv6:ipv6];
-}
-
-bool OpenVPNClient::tun_builder_add_route(const std::string& address, int prefix_length, int metric, bool ipv6) {
- NSString *route = [NSString stringWithUTF8String:address.c_str()];
- return [(__bridge OpenVPNAdapter *)adapter addRoute:route prefixLength:@(prefix_length) isIPv6:ipv6];
-}
-
-bool OpenVPNClient::tun_builder_exclude_route(const std::string& address, int prefix_length, int metric, bool ipv6) {
- NSString *route = [NSString stringWithUTF8String:address.c_str()];
- return [(__bridge OpenVPNAdapter *)adapter excludeRoute:route prefixLength:@(prefix_length) isIPv6: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];
-}
-
-bool OpenVPNClient::tun_builder_add_search_domain(const std::string& domain) {
- NSString *searchDomain = [NSString stringWithUTF8String:domain.c_str()];
- return [(__bridge OpenVPNAdapter *)adapter addSearchDomain:searchDomain];
-}
-
-bool OpenVPNClient::tun_builder_set_mtu(int mtu) {
- return [(__bridge OpenVPNAdapter *)adapter setMTU:@(mtu)];
-}
-
-bool OpenVPNClient::tun_builder_set_session_name(const std::string& name) {
- return true;
-}
-
-bool OpenVPNClient::tun_builder_add_proxy_bypass(const std::string& bypass_host) {
- return true;
-}
-
-bool OpenVPNClient::tun_builder_set_proxy_auto_config_url(const std::string& url) {
- return true;
-}
-
-bool OpenVPNClient::tun_builder_set_proxy_http(const std::string& host, int port) {
- return true;
-}
-
-bool OpenVPNClient::tun_builder_set_proxy_https(const std::string& host, int port) {
- return true;
-}
-
-bool OpenVPNClient::tun_builder_add_wins_server(const std::string& address) {
- return true;
-}
-
-int OpenVPNClient::tun_builder_establish() {
- return (int)[(__bridge OpenVPNAdapter *)adapter establishTunnel];
-}
-
-bool OpenVPNClient::tun_builder_persist() {
- return true;
-}
-
-void OpenVPNClient::tun_builder_establish_lite() {
-
-}
-
-void OpenVPNClient::tun_builder_teardown(bool disconnect) {
-
+TunClient::Ptr OpenVPNClient::new_tun_client_obj(openvpn_io::io_context& io_context, TunClientParent& parent, TransportClient* transcli) {
+ return nullptr;
}
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/TUNConfiguration.h b/OpenVPN Adapter/TUNConfiguration.h
deleted file mode 100644
index 90743db..0000000
--- a/OpenVPN Adapter/TUNConfiguration.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// TUNConfiguration.h
-// OpenVPN iOS Client
-//
-// Created by Sergey Abramchuk on 26.02.17.
-//
-//
-
-#import
-
-@interface TUNConfiguration : NSObject
-
-@property (nonatomic) BOOL initialized;
-
-@property (readonly, strong, nonatomic) NSMutableArray *localAddresses;
-@property (readonly, strong, nonatomic) NSMutableArray *prefixLengths;
-
-@property (readonly, strong, nonatomic) NSMutableArray *includedRoutes;
-@property (readonly, strong, nonatomic) NSMutableArray *excludedRoutes;
-
-@property (readonly, strong, nonatomic) NSMutableArray *dnsAddresses;
-
-@end
diff --git a/OpenVPN Adapter/TUNConfiguration.m b/OpenVPN Adapter/TUNConfiguration.m
deleted file mode 100644
index 2beb564..0000000
--- a/OpenVPN Adapter/TUNConfiguration.m
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// TUNConfiguration.m
-// OpenVPN iOS Client
-//
-// Created by Sergey Abramchuk on 26.02.17.
-//
-//
-
-#import "TUNConfiguration.h"
-
-@implementation TUNConfiguration
-
-- (instancetype)init
-{
- self = [super init];
- if (self) {
- _initialized = NO;
-
- _localAddresses = [NSMutableArray new];
- _prefixLengths = [NSMutableArray new];
-
- _includedRoutes = [NSMutableArray new];
- _excludedRoutes = [NSMutableArray new];
-
- _dnsAddresses = [NSMutableArray new];
- }
- 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);