Merge branch 'feature/custom-factory' into feature/extended-configuration

* feature/custom-factory: (75 commits)
  Update configuration tests
  Update adapter tests
  Delete templates for enum elements
  Remove unnecessary link to sstream
  Update project configuration
  Call clock_tick method
  Reconnect vpn client
  Resume vpn client
  Pause vpn client
  Call handleLog only if delegate responds to selector
  Return core copyright
  Remove expiration class method and convert platform to class property
  Return expiration and platform
  Rename openvpn configuration file
  Return session token
  Remove "defined" property
  Return transport stats and interface stats
  Fix incorrect header
  Return connection info
  Change queue name
  ...

# Conflicts:
#	OpenVPN Adapter Tests/OpenVPNAdapterTests.swift
#	OpenVPN Adapter Tests/Resources/free_openvpn_udp_us.ovpn
#	OpenVPN Adapter/OpenVPNAdapter.mm
This commit is contained in:
Sergey Abramchuk
2017-05-05 17:19:26 +03:00
49 changed files with 2290 additions and 733 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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
}
}
}

View File

@@ -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
}
}

View File

@@ -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
<ca>
-----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-----
</ca>
<cert>
-----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-----
</cert>
<key>
-----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-----
</key>

View File

@@ -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 = "<group>"; };
C93779D31EAE32670030A362 /* OpenVPNCredentials.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNCredentials.h; sourceTree = "<group>"; };
C93779D41EAE32670030A362 /* OpenVPNCredentials.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNCredentials.mm; sourceTree = "<group>"; };
C93779D91EAE32880030A362 /* OpenVPNCredentials+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNCredentials+Internal.h"; sourceTree = "<group>"; };
C94605E81EAA656B00971516 /* OpenVPNConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenVPNConfigurationTests.swift; sourceTree = "<group>"; };
C9657A151EB0A7F800EFF210 /* OpenVPNConnectionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNConnectionInfo.h; sourceTree = "<group>"; };
C9657A161EB0A7F800EFF210 /* OpenVPNConnectionInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNConnectionInfo.mm; sourceTree = "<group>"; };
C9657A1B1EB0A8D800EFF210 /* OpenVPNConnectionInfo+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNConnectionInfo+Internal.h"; sourceTree = "<group>"; };
C9657A231EB0B60200EFF210 /* OpenVPNTransportStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTransportStats.h; sourceTree = "<group>"; };
C9657A241EB0B60200EFF210 /* OpenVPNTransportStats.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNTransportStats.mm; sourceTree = "<group>"; };
C9657A291EB0B6FA00EFF210 /* OpenVPNTransportStats+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNTransportStats+Internal.h"; sourceTree = "<group>"; };
C9657A321EB0BA3900EFF210 /* OpenVPNInterfaceStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNInterfaceStats.h; sourceTree = "<group>"; };
C9657A331EB0BA3900EFF210 /* OpenVPNInterfaceStats.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNInterfaceStats.mm; sourceTree = "<group>"; };
C9657A381EB0BAAB00EFF210 /* OpenVPNInterfaceStats+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNInterfaceStats+Internal.h"; sourceTree = "<group>"; };
C9657A3E1EB0CAC200EFF210 /* OpenVPNServerEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNServerEntry.h; sourceTree = "<group>"; };
C9657A3F1EB0CAC200EFF210 /* OpenVPNServerEntry.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNServerEntry.mm; sourceTree = "<group>"; };
C9657A441EB0CB5900EFF210 /* OpenVPNServerEntry+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNServerEntry+Internal.h"; sourceTree = "<group>"; };
C9657A4A1EB0CD6C00EFF210 /* OpenVPNProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNProperties.h; sourceTree = "<group>"; };
C9657A4B1EB0CD6C00EFF210 /* OpenVPNProperties.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNProperties.mm; sourceTree = "<group>"; };
C9657A501EB0CD9200EFF210 /* OpenVPNProperties+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNProperties+Internal.h"; sourceTree = "<group>"; };
C9657A5D1EB0D60700EFF210 /* OpenVPNTransportProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTransportProtocol.h; sourceTree = "<group>"; };
C9657A601EB0D64E00EFF210 /* OpenVPNIPv6Preference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNIPv6Preference.h; sourceTree = "<group>"; };
C9657A631EB0D6AD00EFF210 /* OpenVPNCompressionMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenVPNCompressionMode.h; sourceTree = "<group>"; };
C9657A661EB0D73200EFF210 /* OpenVPNMinTLSVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNMinTLSVersion.h; sourceTree = "<group>"; };
C9657A691EB0D75700EFF210 /* OpenVPNTLSCertProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNTLSCertProfile.h; sourceTree = "<group>"; };
C98467A11EAA559B00272A9A /* local_vpn_server.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = local_vpn_server.ovpn; sourceTree = "<group>"; };
C98467A41EAA5B7700272A9A /* OpenVPNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNConfiguration.h; sourceTree = "<group>"; };
C98467A51EAA5B7700272A9A /* OpenVPNConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNConfiguration.mm; sourceTree = "<group>"; };
C98467AA1EAA5BB500272A9A /* OpenVPNConfiguration+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenVPNConfiguration+Internal.h"; sourceTree = "<group>"; };
C9B03A7A1EABA6B500268B85 /* ProfileLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileLoader.swift; sourceTree = "<group>"; };
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 = "<group>"; };
C9BB476F1E7171A100F3F98C /* OpenVPNError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = OpenVPNError.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNEvent.h; sourceTree = "<group>"; };
C9BB47731E7171D900F3F98C /* TUNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNConfiguration.h; sourceTree = "<group>"; };
C9BB47741E7171D900F3F98C /* TUNConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNConfiguration.m; sourceTree = "<group>"; };
C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNClient.h; sourceTree = "<group>"; };
C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNClient.mm; sourceTree = "<group>"; };
C9BB477B1E7173C700F3F98C /* OpenVPNAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNAdapter.h; sourceTree = "<group>"; };
@@ -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 = "<group>"; };
C9BB47A11E7183DB00F3F98C /* Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
C9BCE2561EB3C0D9009D6AC1 /* OpenVPNSessionToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNSessionToken.h; sourceTree = "<group>"; };
C9BCE2571EB3C0D9009D6AC1 /* OpenVPNSessionToken.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenVPNSessionToken.mm; sourceTree = "<group>"; };
C9BCE25C1EB3C201009D6AC1 /* OpenVPNSessionToken+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OpenVPNSessionToken+Internal.h"; sourceTree = "<group>"; };
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 = "<group>"; };
@@ -179,9 +269,73 @@
name = Frameworks;
sourceTree = "<group>";
};
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 = "<group>";
};
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 = "<group>";
};
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 = "<group>";
};
C9B376B71EA53CE700B7F423 /* Client */ = {
isa = PBXGroup;
children = (
C9BB47771E7171ED00F3F98C /* OpenVPNClient.h */,
C9BB47781E7171ED00F3F98C /* OpenVPNClient.mm */,
);
name = Client;
sourceTree = "<group>";
};
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 = "<group>";
@@ -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 = "<group>";
};
C9FF73B71EB7421600E995AC /* Helpers */ = {
isa = PBXGroup;
children = (
C9235AC61EB24F2A00C7D303 /* Enums and Constants */,
);
name = Helpers;
sourceTree = "<group>";
};
/* 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;

View File

@@ -26,9 +26,29 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C9BB478D1E71821A00F3F98C"
BuildableName = "OpenVPN Adapter iOS Tests.xctest"
BlueprintName = "OpenVPN Adapter iOS Tests"
ReferencedContainer = "container:OpenVPN Adapter.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C9BB475B1E71663A00F3F98C"
BuildableName = "OpenVPNAdapter.framework"
BlueprintName = "OpenVPN Adapter iOS"
ReferencedContainer = "container:OpenVPN Adapter.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>

View File

@@ -26,9 +26,29 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C9D2ABF21EA212A3007EDF9D"
BuildableName = "OpenVPN Adapter macOS Tests.xctest"
BlueprintName = "OpenVPN Adapter macOS Tests"
ReferencedContainer = "container:OpenVPN Adapter.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C9D2ABD81EA20F99007EDF9D"
BuildableName = "OpenVPNAdapter.framework"
BlueprintName = "OpenVPN Adapter macOS"
ReferencedContainer = "container:OpenVPN Adapter.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>

View File

@@ -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

View File

@@ -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<OpenVPNAdapterDelegate> 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
*/

View File

@@ -1,6 +1,6 @@
//
// OpenVPNAdapter.h
// OpenVPN iOS Client
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 11.02.17.
//
@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
@interface OpenVPNAdapter : NSObject
@end

View File

@@ -1,6 +1,6 @@
//
// OpenVPNAdapter.m
// OpenVPN iOS Client
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 11.02.17.
//
@@ -14,11 +14,16 @@
#import <NetworkExtension/NetworkExtension.h>
#import "OpenVPNClient.h"
#import "OpenVPNError.h"
#import "OpenVPNEvent.h"
#import "OpenVPNClient.h"
#import "TUNConfiguration.h"
#import "OpenVPNConfiguration+Internal.h"
#import "OpenVPNCredentials+Internal.h"
#import "OpenVPNProperties+Internal.h"
#import "OpenVPNConnectionInfo+Internal.h"
#import "OpenVPNSessionToken+Internal.h"
#import "OpenVPNTransportStats+Internal.h"
#import "OpenVPNInterfaceStats+Internal.h"
#import "OpenVPNAdapter.h"
#import "OpenVPNAdapter+Internal.h"
#import "OpenVPNAdapter+Public.h"
@@ -28,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<OpenVPNAdapterDelegate> _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<OpenVPNAdapterPacketFlow> 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<OpenVPNAdapterPacketFlow> _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<OpenVPNAdapterDelegate>)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<NSData *> * _Nonnull packets, NSArray<NSNumber *> * _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);

View File

@@ -6,54 +6,20 @@
//
//
#import <openvpn/tun/client/tunbase.hpp>
#import <client/ovpncli.hpp>
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;
};

View File

@@ -6,119 +6,42 @@
//
//
#import <sstream>
#import <Foundation/Foundation.h>
#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];
}

View File

@@ -0,0 +1,23 @@
//
// OpenVPNCompressionMode.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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
};

View File

@@ -0,0 +1,34 @@
//
// OpenVPNConfiguration+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 21.04.17.
//
//
#import <client/ovpncli.hpp>
#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

View File

@@ -0,0 +1,145 @@
//
// OpenVPNConfiguration.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 21.04.17.
//
//
#import <Foundation/Foundation.h>
#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<NSString *, NSString *> *settings;
/**
Set to identity OpenVPN GUI version.
Format should be "<gui_identifier><space><version>"
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<NSString *, NSString *> *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

View File

@@ -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<NSString *,NSString *> *)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<NSString *,NSString *> *)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<NSString *,NSString *> *)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<NSString *,NSString *> *)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

View File

@@ -0,0 +1,19 @@
//
// OpenVPNConnectionInfo+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNConnectionInfo.h"
using namespace openvpn;
@interface OpenVPNConnectionInfo (Internal)
- (instancetype)initWithConnectionInfo:(ClientAPI::ConnectionInfo)info;
@end

View File

@@ -0,0 +1,30 @@
//
// OpenVPNConnectionInfo.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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

View File

@@ -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

View File

@@ -0,0 +1,19 @@
//
// OpenVPNCredentials+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 24.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNCredentials.h"
using namespace openvpn;
@interface OpenVPNCredentials (Internal)
@property (readonly) ClientAPI::ProvideCreds credentials;
@end

View File

@@ -0,0 +1,53 @@
//
// OpenVPNCredentials.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 24.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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

View File

@@ -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

View File

@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
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,

View File

@@ -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,

View File

@@ -0,0 +1,21 @@
//
// OpenVPNIPv6Preference.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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
};

View File

@@ -0,0 +1,19 @@
//
// OpenVPNInterfaceStats+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNInterfaceStats.h"
using namespace openvpn;
@interface OpenVPNInterfaceStats (Internal)
- (instancetype)initWithInterfaceStats:(ClientAPI::InterfaceStats)stats;
@end

View File

@@ -0,0 +1,48 @@
//
// OpenVPNInterfaceStats.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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

View File

@@ -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

View File

@@ -0,0 +1,25 @@
//
// OpenVPNMinTLSVersion.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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
};

View File

@@ -0,0 +1,19 @@
//
// OpenVPNProperties+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNProperties.h"
using namespace openvpn;
@interface OpenVPNProperties (Internal)
- (instancetype)initWithEvalConfig:(ClientAPI::EvalConfig)eval;
@end

View File

@@ -0,0 +1,79 @@
//
// OpenVPNProperties.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
#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<OpenVPNServerEntry *> *servers;
- (nonnull instancetype) __unavailable init;
@end

View File

@@ -0,0 +1,61 @@
//
// OpenVPNProperties.m
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <openvpn/common/number.hpp>
#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

View File

@@ -0,0 +1,19 @@
//
// OpenVPNServerEntry+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNServerEntry.h"
using namespace openvpn;
@interface OpenVPNServerEntry (Internal)
- (instancetype)initWithServerEntry:(ClientAPI::ServerEntry)entry;
@end

View File

@@ -0,0 +1,18 @@
//
// OpenVPNServerEntry.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
@interface OpenVPNServerEntry : NSObject
@property (nullable, readonly, nonatomic) NSString *server;
@property (nullable, readonly, nonatomic) NSString *friendlyName;
- (nonnull instancetype) __unavailable init;
@end

View File

@@ -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

View File

@@ -0,0 +1,19 @@
//
// OpenVPNSessionToken+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 28.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNSessionToken.h"
using namespace openvpn;
@interface OpenVPNSessionToken (Internal)
- (instancetype)initWithSessionToken:(ClientAPI::SessionToken)token;
@end

View File

@@ -0,0 +1,25 @@
//
// OpenVPNSessionToken.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 28.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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

View File

@@ -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

View File

@@ -0,0 +1,27 @@
//
// OpenVPNTLSCertProfile.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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
};

View File

@@ -0,0 +1,23 @@
//
// OpenVPNTransportProtocol.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
Transport protocol options
*/
typedef NS_ENUM(NSInteger, OpenVPNTransportProtocol) {
///
OpenVPNTransportProtocolUDP,
///
OpenVPNTransportProtocolTCP,
///
OpenVPNTransportProtocolAdaptive,
/// Use a transport protocol specified in the profile
OpenVPNTransportProtocolDefault
};

View File

@@ -0,0 +1,19 @@
//
// OpenVPNTransportStats+Internal.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <client/ovpncli.hpp>
#import "OpenVPNTransportStats.h"
using namespace openvpn;
@interface OpenVPNTransportStats (Internal)
- (instancetype)initWithTransportStats:(ClientAPI::TransportStats)stats;
@end

View File

@@ -0,0 +1,44 @@
//
// OpenVPNTransportStats.h
// OpenVPN Adapter
//
// Created by Sergey Abramchuk on 26.04.17.
//
//
#import <Foundation/Foundation.h>
/**
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

View File

@@ -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

View File

@@ -1,23 +0,0 @@
//
// TUNConfiguration.h
// OpenVPN iOS Client
//
// Created by Sergey Abramchuk on 26.02.17.
//
//
#import <Foundation/Foundation.h>
@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

View File

@@ -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

View File

@@ -18,5 +18,18 @@ FOUNDATION_EXPORT const unsigned char OpenVPNAdapterVersionString[];
#import <OpenVPNAdapter/OpenVPNError.h>
#import <OpenVPNAdapter/OpenVPNEvent.h>
#import <OpenVPNAdapter/OpenVPNTransportProtocol.h>
#import <OpenVPNAdapter/OpenVPNIPv6Preference.h>
#import <OpenVPNAdapter/OpenVPNCompressionMode.h>
#import <OpenVPNAdapter/OpenVPNMinTLSVersion.h>
#import <OpenVPNAdapter/OpenVPNTLSCertProfile.h>
#import <OpenVPNAdapter/OpenVPNConfiguration.h>
#import <OpenVPNAdapter/OpenVPNCredentials.h>
#import <OpenVPNAdapter/OpenVPNServerEntry.h>
#import <OpenVPNAdapter/OpenVPNProperties.h>
#import <OpenVPNAdapter/OpenVPNConnectionInfo.h>
#import <OpenVPNAdapter/OpenVPNSessionToken.h>
#import <OpenVPNAdapter/OpenVPNTransportStats.h>
#import <OpenVPNAdapter/OpenVPNInterfaceStats.h>
#import <OpenVPNAdapter/OpenVPNAdapter.h>
#import <OpenVPNAdapter/OpenVPNAdapter+Public.h>

View File

@@ -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 <typename T>
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);