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