Increase components granularity
Minimize target dependency on OpenSSL (easier to drop later). Outside of OpenVPN tunnel extension, OpenSSL is only used to decrypt encrypted private keys in CryptoContainer (found in TunnelKitOpenVPNCore, therefore "temporarily" dependent on CTunnelKitOpenVPNAppExtension for TLSBox/CryptoBox).
This commit is contained in:
parent
d1f70171cb
commit
50064fc3d0
|
@ -169,7 +169,7 @@ M69t86apMrAxkUxVJAWLRBd9fbYyzJgTW61tFqXWTZpiz6bhuWApSEzaHcL3/f5l
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
""")
|
""")
|
||||||
|
|
||||||
static func make(hostname: String, port: UInt16, socketType: SocketType) -> OpenVPNTunnelProvider.Configuration {
|
static func make(hostname: String, port: UInt16, socketType: SocketType) -> OpenVPNProvider.Configuration {
|
||||||
var sessionBuilder = OpenVPN.ConfigurationBuilder()
|
var sessionBuilder = OpenVPN.ConfigurationBuilder()
|
||||||
sessionBuilder.ca = ca
|
sessionBuilder.ca = ca
|
||||||
sessionBuilder.cipher = .aes128cbc
|
sessionBuilder.cipher = .aes128cbc
|
||||||
|
@ -181,7 +181,7 @@ M69t86apMrAxkUxVJAWLRBd9fbYyzJgTW61tFqXWTZpiz6bhuWApSEzaHcL3/f5l
|
||||||
sessionBuilder.clientCertificate = clientCertificate
|
sessionBuilder.clientCertificate = clientCertificate
|
||||||
sessionBuilder.clientKey = clientKey
|
sessionBuilder.clientKey = clientKey
|
||||||
sessionBuilder.mtu = 1350
|
sessionBuilder.mtu = 1350
|
||||||
var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||||
builder.shouldDebug = true
|
builder.shouldDebug = true
|
||||||
builder.masksPrivateData = false
|
builder.masksPrivateData = false
|
||||||
return builder.build()
|
return builder.build()
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
import TunnelKitOpenVPN
|
import TunnelKitOpenVPNAppExtension
|
||||||
|
|
||||||
class PacketTunnelProvider: OpenVPNTunnelProvider {
|
class PacketTunnelProvider: OpenVPNTunnelProvider {
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,10 @@
|
||||||
0E1108B11F77B9F900A92462 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108AF1F77B9F900A92462 /* Main.storyboard */; };
|
0E1108B11F77B9F900A92462 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108AF1F77B9F900A92462 /* Main.storyboard */; };
|
||||||
0E1108B31F77B9F900A92462 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B21F77B9F900A92462 /* Assets.xcassets */; };
|
0E1108B31F77B9F900A92462 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B21F77B9F900A92462 /* Assets.xcassets */; };
|
||||||
0E1108B61F77B9F900A92462 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B41F77B9F900A92462 /* LaunchScreen.storyboard */; };
|
0E1108B61F77B9F900A92462 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B41F77B9F900A92462 /* LaunchScreen.storyboard */; };
|
||||||
|
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */; };
|
||||||
|
0E80FA5327396F66000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */; };
|
||||||
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */; };
|
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */; };
|
||||||
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */; };
|
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */; };
|
||||||
0EFD5B352727250E00C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B342727250E00C7D5FD /* TunnelKitOpenVPN */; };
|
|
||||||
0EFD5B372727251200C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B362727251200C7D5FD /* TunnelKitOpenVPN */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -166,8 +166,8 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0EFD5B352727250E00C7D5FD /* TunnelKitOpenVPN in Frameworks */,
|
|
||||||
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
|
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
|
||||||
|
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0EFD5B372727251200C7D5FD /* TunnelKitOpenVPN in Frameworks */,
|
0E80FA5327396F66000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */,
|
||||||
0E05427825A239C600EFC5FF /* NetworkExtension.framework in Frameworks */,
|
0E05427825A239C600EFC5FF /* NetworkExtension.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -343,7 +343,7 @@
|
||||||
);
|
);
|
||||||
name = "TunnelKitDemoTunnel-iOS";
|
name = "TunnelKitDemoTunnel-iOS";
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
0EFD5B342727250E00C7D5FD /* TunnelKitOpenVPN */,
|
0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */,
|
||||||
);
|
);
|
||||||
productName = Tunnel;
|
productName = Tunnel;
|
||||||
productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */;
|
productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */;
|
||||||
|
@ -386,7 +386,7 @@
|
||||||
);
|
);
|
||||||
name = "TunnelKitDemoTunnel-macOS";
|
name = "TunnelKitDemoTunnel-macOS";
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
0EFD5B362727251200C7D5FD /* TunnelKitOpenVPN */,
|
0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */,
|
||||||
);
|
);
|
||||||
productName = Tunnel;
|
productName = Tunnel;
|
||||||
productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */;
|
productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */;
|
||||||
|
@ -1032,6 +1032,14 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = TunnelKitOpenVPNAppExtension;
|
||||||
|
};
|
||||||
|
0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = TunnelKitOpenVPNAppExtension;
|
||||||
|
};
|
||||||
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */ = {
|
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = TunnelKitOpenVPN;
|
productName = TunnelKitOpenVPN;
|
||||||
|
@ -1040,14 +1048,6 @@
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = TunnelKitOpenVPN;
|
productName = TunnelKitOpenVPN;
|
||||||
};
|
};
|
||||||
0EFD5B342727250E00C7D5FD /* TunnelKitOpenVPN */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
productName = TunnelKitOpenVPN;
|
|
||||||
};
|
|
||||||
0EFD5B362727251200C7D5FD /* TunnelKitOpenVPN */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
productName = TunnelKitOpenVPN;
|
|
||||||
};
|
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 0E17D7F01F730D9F009EE129 /* Project object */;
|
rootObject = 0E17D7F01F730D9F009EE129 /* Project object */;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"repositoryURL": "https://github.com/keeshux/openssl-apple",
|
"repositoryURL": "https://github.com/keeshux/openssl-apple",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "1889136399ba40e4fc358cfe7fafef7170aac3f7",
|
"revision": "37043e7c92c9fb348d1d668b0402148c9fa9873c",
|
||||||
"version": "1.1.112"
|
"version": "1.1.112"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,11 +12,7 @@ let package = Package(
|
||||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||||
.library(
|
.library(
|
||||||
name: "TunnelKit",
|
name: "TunnelKit",
|
||||||
targets: [
|
targets: ["TunnelKit"]
|
||||||
"TunnelKitCore",
|
|
||||||
"TunnelKitAppExtension",
|
|
||||||
"TunnelKitManager"
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
.library(
|
.library(
|
||||||
name: "TunnelKitIKE",
|
name: "TunnelKitIKE",
|
||||||
|
@ -26,6 +22,10 @@ let package = Package(
|
||||||
name: "TunnelKitOpenVPN",
|
name: "TunnelKitOpenVPN",
|
||||||
targets: ["TunnelKitOpenVPN"]
|
targets: ["TunnelKitOpenVPN"]
|
||||||
),
|
),
|
||||||
|
.library(
|
||||||
|
name: "TunnelKitOpenVPNAppExtension",
|
||||||
|
targets: ["TunnelKitOpenVPNAppExtension"]
|
||||||
|
),
|
||||||
.library(
|
.library(
|
||||||
name: "TunnelKitLZO",
|
name: "TunnelKitLZO",
|
||||||
targets: ["TunnelKitLZO"]
|
targets: ["TunnelKitLZO"]
|
||||||
|
@ -40,41 +40,71 @@ let package = Package(
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||||
|
.target(
|
||||||
|
name: "TunnelKit",
|
||||||
|
dependencies: [
|
||||||
|
"TunnelKitCore",
|
||||||
|
"TunnelKitManager"
|
||||||
|
]
|
||||||
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "TunnelKitCore",
|
name: "TunnelKitCore",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"_TunnelKitUtils",
|
"__TunnelKitUtils",
|
||||||
"_TunnelKitCoreObjC",
|
"CTunnelKitCore",
|
||||||
"SwiftyBeaver"]),
|
"SwiftyBeaver"
|
||||||
|
]),
|
||||||
.target(
|
.target(
|
||||||
name: "_TunnelKitCoreObjC",
|
name: "TunnelKitManager",
|
||||||
dependencies: []),
|
dependencies: [
|
||||||
|
"TunnelKitCore"
|
||||||
|
]),
|
||||||
.target(
|
.target(
|
||||||
name: "TunnelKitAppExtension",
|
name: "TunnelKitAppExtension",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"TunnelKitCore",
|
"TunnelKitCore",
|
||||||
"SwiftyBeaver"]),
|
"SwiftyBeaver"
|
||||||
.target(
|
]),
|
||||||
name: "TunnelKitManager",
|
|
||||||
dependencies: [
|
|
||||||
"TunnelKitCore"]),
|
|
||||||
.target(
|
.target(
|
||||||
name: "TunnelKitIKE",
|
name: "TunnelKitIKE",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"TunnelKitCore",
|
"TunnelKitCore",
|
||||||
"TunnelKitManager"]),
|
"TunnelKitManager"
|
||||||
|
]),
|
||||||
.target(
|
.target(
|
||||||
name: "TunnelKitOpenVPN",
|
name: "TunnelKitOpenVPN",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"TunnelKitCore",
|
"TunnelKitOpenVPNCore",
|
||||||
"_TunnelKitOpenVPNObjC",
|
"TunnelKitOpenVPNManager"
|
||||||
"TunnelKitAppExtension",
|
]),
|
||||||
"TunnelKitManager"]),
|
//
|
||||||
.target(
|
.target(
|
||||||
name: "_TunnelKitOpenVPNObjC",
|
name: "TunnelKitOpenVPNCore",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"openssl-apple",
|
"TunnelKitCore",
|
||||||
"_TunnelKitCoreObjC"]),
|
"CTunnelKitOpenVPNCore",
|
||||||
|
"CTunnelKitOpenVPNProtocol" // FIXME: remove dependency on TLSBox
|
||||||
|
]),
|
||||||
|
.target(
|
||||||
|
name: "TunnelKitOpenVPNManager",
|
||||||
|
dependencies: [
|
||||||
|
"TunnelKitManager",
|
||||||
|
"TunnelKitOpenVPNCore"
|
||||||
|
]),
|
||||||
|
.target(
|
||||||
|
name: "TunnelKitOpenVPNProtocol",
|
||||||
|
dependencies: [
|
||||||
|
"TunnelKitOpenVPNCore",
|
||||||
|
"CTunnelKitOpenVPNProtocol"
|
||||||
|
]),
|
||||||
|
.target(
|
||||||
|
name: "TunnelKitOpenVPNAppExtension",
|
||||||
|
dependencies: [
|
||||||
|
"TunnelKitAppExtension",
|
||||||
|
"TunnelKitOpenVPNCore",
|
||||||
|
"TunnelKitOpenVPNManager",
|
||||||
|
"TunnelKitOpenVPNProtocol"
|
||||||
|
]),
|
||||||
.target(
|
.target(
|
||||||
name: "TunnelKitLZO",
|
name: "TunnelKitLZO",
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
@ -84,9 +114,24 @@ let package = Package(
|
||||||
"lib/README.LZO",
|
"lib/README.LZO",
|
||||||
"lib/testmini.c"
|
"lib/testmini.c"
|
||||||
]),
|
]),
|
||||||
|
//
|
||||||
.target(
|
.target(
|
||||||
name: "_TunnelKitUtils",
|
name: "CTunnelKitCore",
|
||||||
dependencies: []),
|
dependencies: []),
|
||||||
|
.target(
|
||||||
|
name: "CTunnelKitOpenVPNCore",
|
||||||
|
dependencies: []),
|
||||||
|
.target(
|
||||||
|
name: "CTunnelKitOpenVPNProtocol",
|
||||||
|
dependencies: [
|
||||||
|
"CTunnelKitCore",
|
||||||
|
"CTunnelKitOpenVPNCore",
|
||||||
|
"openssl-apple"
|
||||||
|
]),
|
||||||
|
.target(
|
||||||
|
name: "__TunnelKitUtils",
|
||||||
|
dependencies: []),
|
||||||
|
//
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "TunnelKitCoreTests",
|
name: "TunnelKitCoreTests",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
@ -95,7 +140,8 @@ let package = Package(
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "TunnelKitOpenVPNTests",
|
name: "TunnelKitOpenVPNTests",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"TunnelKitOpenVPN",
|
"TunnelKitOpenVPNCore",
|
||||||
|
"TunnelKitOpenVPNAppExtension",
|
||||||
"TunnelKitLZO"
|
"TunnelKitLZO"
|
||||||
],
|
],
|
||||||
resources: [
|
resources: [
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import "CompressionFramingNative.h"
|
@import CTunnelKitOpenVPNCore;
|
||||||
#import "CompressionAlgorithmNative.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
@_exported import TunnelKitCore
|
||||||
|
@_exported import TunnelKitManager
|
|
@ -24,7 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
|
|
||||||
extension Error {
|
extension Error {
|
||||||
public func isTunnelKitError() -> Bool {
|
public func isTunnelKitError() -> Bool {
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import Security.SecRandom
|
import Security.SecRandom
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import _TunnelKitUtils
|
import __TunnelKitUtils
|
||||||
|
|
||||||
/// :nodoc:
|
/// :nodoc:
|
||||||
public enum SecureRandomError: Error {
|
public enum SecureRandomError: Error {
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
|
|
||||||
public func Z() -> ZeroingData {
|
public func Z() -> ZeroingData {
|
||||||
return ZeroingData()
|
return ZeroingData()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
../../_TunnelKitCoreObjC/include/Errors.h
|
../../CTunnelKitCore/include/Errors.h
|
|
@ -1,151 +0,0 @@
|
||||||
//
|
|
||||||
// OpenVPNTunnelProvider+Interaction.swift
|
|
||||||
// TunnelKit
|
|
||||||
//
|
|
||||||
// Created by Davide De Rosa on 9/24/17.
|
|
||||||
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
|
||||||
//
|
|
||||||
// https://github.com/passepartoutvpn
|
|
||||||
//
|
|
||||||
// This file is part of TunnelKit.
|
|
||||||
//
|
|
||||||
// TunnelKit is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// TunnelKit is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
//
|
|
||||||
// This file incorporates work covered by the following copyright and
|
|
||||||
// permission notice:
|
|
||||||
//
|
|
||||||
// Copyright (c) 2018-Present Private Internet Access
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension OpenVPNTunnelProvider {
|
|
||||||
|
|
||||||
// MARK: Interaction
|
|
||||||
|
|
||||||
/// The messages accepted by `OpenVPNTunnelProvider`.
|
|
||||||
public class Message: Equatable {
|
|
||||||
|
|
||||||
/// Requests a snapshot of the latest debug log. Returns the log data decoded from UTF-8.
|
|
||||||
public static let requestLog = Message(0xff)
|
|
||||||
|
|
||||||
/// Requests the current bytes count from data channel (if connected).
|
|
||||||
///
|
|
||||||
/// Data is 16 bytes: low 8 = received, high 8 = sent.
|
|
||||||
public static let dataCount = Message(0xfe)
|
|
||||||
|
|
||||||
/// Requests the configuration pulled from the server (if connected and available).
|
|
||||||
///
|
|
||||||
/// Data is JSON (Decodable).
|
|
||||||
public static let serverConfiguration = Message(0xfd)
|
|
||||||
|
|
||||||
/// The underlying raw message `Data` to forward to the tunnel via IPC.
|
|
||||||
public let data: Data
|
|
||||||
|
|
||||||
private init(_ byte: UInt8) {
|
|
||||||
data = Data([byte])
|
|
||||||
}
|
|
||||||
|
|
||||||
init(_ data: Data) {
|
|
||||||
self.data = data
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Equatable
|
|
||||||
|
|
||||||
/// :nodoc:
|
|
||||||
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
|
||||||
return (lhs.data == rhs.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mostly programming errors by host app
|
|
||||||
enum ProviderConfigurationError: Error {
|
|
||||||
|
|
||||||
/// A field in the `OpenVPNTunnelProvider.Configuration` provided is incorrect or incomplete.
|
|
||||||
case parameter(name: String)
|
|
||||||
|
|
||||||
/// Credentials are missing or inaccessible.
|
|
||||||
case credentials(details: String)
|
|
||||||
|
|
||||||
/// The pseudo-random number generator could not be initialized.
|
|
||||||
case prngInitialization
|
|
||||||
|
|
||||||
/// The TLS certificate could not be serialized.
|
|
||||||
case certificateSerialization
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The errors causing a tunnel disconnection.
|
|
||||||
public enum ProviderError: String, Error {
|
|
||||||
|
|
||||||
/// Socket endpoint could not be resolved.
|
|
||||||
case dnsFailure
|
|
||||||
|
|
||||||
/// No more protocols available to try.
|
|
||||||
case exhaustedProtocols
|
|
||||||
|
|
||||||
/// Socket failed to reach active state.
|
|
||||||
case socketActivity
|
|
||||||
|
|
||||||
/// Credentials authentication failed.
|
|
||||||
case authentication
|
|
||||||
|
|
||||||
/// TLS could not be initialized (e.g. malformed CA or client PEMs).
|
|
||||||
case tlsInitialization
|
|
||||||
|
|
||||||
/// TLS server verification failed.
|
|
||||||
case tlsServerVerification
|
|
||||||
|
|
||||||
/// TLS handshake failed.
|
|
||||||
case tlsHandshake
|
|
||||||
|
|
||||||
/// The encryption logic could not be initialized (e.g. PRNG, algorithms).
|
|
||||||
case encryptionInitialization
|
|
||||||
|
|
||||||
/// Data encryption/decryption failed.
|
|
||||||
case encryptionData
|
|
||||||
|
|
||||||
/// The LZO engine failed.
|
|
||||||
case lzo
|
|
||||||
|
|
||||||
/// Server uses an unsupported compression algorithm.
|
|
||||||
case serverCompression
|
|
||||||
|
|
||||||
/// Tunnel timed out.
|
|
||||||
case timeout
|
|
||||||
|
|
||||||
/// An error occurred at the link level.
|
|
||||||
case linkError
|
|
||||||
|
|
||||||
/// Network routing information is missing or incomplete.
|
|
||||||
case routing
|
|
||||||
|
|
||||||
/// The current network changed (e.g. switched from WiFi to data connection).
|
|
||||||
case networkChanged
|
|
||||||
|
|
||||||
/// Default gateway could not be attained.
|
|
||||||
case gatewayUnattainable
|
|
||||||
|
|
||||||
/// Remove server has shut down.
|
|
||||||
case serverShutdown
|
|
||||||
|
|
||||||
/// The server replied in an unexpected way.
|
|
||||||
case unexpectedReply
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
@_exported import TunnelKitOpenVPNCore
|
||||||
|
@_exported import TunnelKitOpenVPNManager
|
|
@ -39,6 +39,7 @@ import NetworkExtension
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import TunnelKitAppExtension
|
import TunnelKitAppExtension
|
||||||
|
import TunnelKitOpenVPNManager
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ class ConnectionStrategy {
|
||||||
|
|
||||||
private let resolvedAddresses: [String]
|
private let resolvedAddresses: [String]
|
||||||
|
|
||||||
init(configuration: OpenVPNTunnelProvider.Configuration) {
|
init(configuration: OpenVPNProvider.Configuration) {
|
||||||
hostname = configuration.sessionConfiguration.hostname
|
hostname = configuration.sessionConfiguration.hostname
|
||||||
guard var endpointProtocols = configuration.sessionConfiguration.endpointProtocols else {
|
guard var endpointProtocols = configuration.sessionConfiguration.endpointProtocols else {
|
||||||
fatalError("No endpoints provided")
|
fatalError("No endpoints provided")
|
||||||
|
@ -170,7 +171,7 @@ class ConnectionStrategy {
|
||||||
|
|
||||||
guard let hostname = hostname else {
|
guard let hostname = hostname else {
|
||||||
log.error("DNS resolution unavailable: no hostname provided!")
|
log.error("DNS resolution unavailable: no hostname provided!")
|
||||||
completionHandler(nil, OpenVPNTunnelProvider.ProviderError.dnsFailure)
|
completionHandler(nil, OpenVPNProviderError.dnsFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.debug("DNS resolve hostname: \(hostname.maskedDescription)")
|
log.debug("DNS resolve hostname: \(hostname.maskedDescription)")
|
||||||
|
@ -187,7 +188,7 @@ class ConnectionStrategy {
|
||||||
|
|
||||||
guard self.hasEndpoint() else {
|
guard self.hasEndpoint() else {
|
||||||
log.error("No endpoints available")
|
log.error("No endpoints available")
|
||||||
completionHandler(nil, OpenVPNTunnelProvider.ProviderError.dnsFailure)
|
completionHandler(nil, OpenVPNProviderError.dnsFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import Foundation
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import TunnelKitAppExtension
|
import TunnelKitAppExtension
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class NETCPLink: LinkInterface {
|
class NETCPLink: LinkInterface {
|
||||||
private let impl: NWTCPConnection
|
private let impl: NWTCPConnection
|
|
@ -42,8 +42,12 @@ import SystemConfiguration.CaptiveNetwork
|
||||||
import CoreWLAN
|
import CoreWLAN
|
||||||
#endif
|
#endif
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
|
import TunnelKitManager
|
||||||
|
import TunnelKitOpenVPNManager
|
||||||
|
import TunnelKitOpenVPNProtocol
|
||||||
import TunnelKitAppExtension
|
import TunnelKitAppExtension
|
||||||
|
import CTunnelKitCore
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
|
@ -117,7 +121,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
|
|
||||||
private lazy var defaults = UserDefaults(suiteName: appGroup)
|
private lazy var defaults = UserDefaults(suiteName: appGroup)
|
||||||
|
|
||||||
private var cfg: Configuration!
|
private var cfg: OpenVPNProvider.Configuration!
|
||||||
|
|
||||||
private var strategy: ConnectionStrategy!
|
private var strategy: ConnectionStrategy!
|
||||||
|
|
||||||
|
@ -150,16 +154,16 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
// required configuration
|
// required configuration
|
||||||
do {
|
do {
|
||||||
guard let tunnelProtocol = protocolConfiguration as? NETunnelProviderProtocol else {
|
guard let tunnelProtocol = protocolConfiguration as? NETunnelProviderProtocol else {
|
||||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration")
|
throw OpenVPNProviderConfigurationError.parameter(name: "protocolConfiguration")
|
||||||
}
|
}
|
||||||
guard let serverAddress = tunnelProtocol.serverAddress else {
|
guard let serverAddress = tunnelProtocol.serverAddress else {
|
||||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.serverAddress")
|
throw OpenVPNProviderConfigurationError.parameter(name: "protocolConfiguration.serverAddress")
|
||||||
}
|
}
|
||||||
guard let providerConfiguration = tunnelProtocol.providerConfiguration else {
|
guard let providerConfiguration = tunnelProtocol.providerConfiguration else {
|
||||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration")
|
throw OpenVPNProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration")
|
||||||
}
|
}
|
||||||
try appGroup = Configuration.appGroup(from: providerConfiguration)
|
try appGroup = OpenVPNProvider.Configuration.appGroup(from: providerConfiguration)
|
||||||
try cfg = Configuration.parsed(from: providerConfiguration)
|
try cfg = OpenVPNProvider.Configuration.parsed(from: providerConfiguration)
|
||||||
|
|
||||||
// inject serverAddress into sessionConfiguration.hostname
|
// inject serverAddress into sessionConfiguration.hostname
|
||||||
if !serverAddress.isEmpty {
|
if !serverAddress.isEmpty {
|
||||||
|
@ -171,7 +175,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
}
|
}
|
||||||
} catch let e {
|
} catch let e {
|
||||||
var message: String?
|
var message: String?
|
||||||
if let te = e as? ProviderConfigurationError {
|
if let te = e as? OpenVPNProviderConfigurationError {
|
||||||
switch te {
|
switch te {
|
||||||
case .parameter(let name):
|
case .parameter(let name):
|
||||||
message = "Tunnel configuration incomplete: \(name)"
|
message = "Tunnel configuration incomplete: \(name)"
|
||||||
|
@ -217,7 +221,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
if let username = protocolConfiguration.username, let passwordReference = protocolConfiguration.passwordReference {
|
if let username = protocolConfiguration.username, let passwordReference = protocolConfiguration.passwordReference {
|
||||||
let keychain = Keychain(group: appGroup)
|
let keychain = Keychain(group: appGroup)
|
||||||
guard let password = try? keychain.password(for: username, reference: passwordReference) else {
|
guard let password = try? keychain.password(for: username, reference: passwordReference) else {
|
||||||
completionHandler(ProviderConfigurationError.credentials(details: "keychain.password(for:, reference:)"))
|
completionHandler(OpenVPNProviderConfigurationError.credentials(details: "keychain.password(for:, reference:)"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
credentials = OpenVPN.Credentials(username, password)
|
credentials = OpenVPN.Credentials(username, password)
|
||||||
|
@ -229,7 +233,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
cfg.clearLastError(in: appGroup)
|
cfg.clearLastError(in: appGroup)
|
||||||
|
|
||||||
guard OpenVPN.prepareRandomNumberGenerator(seedLength: prngSeedLength) else {
|
guard OpenVPN.prepareRandomNumberGenerator(seedLength: prngSeedLength) else {
|
||||||
completionHandler(ProviderConfigurationError.prngInitialization)
|
completionHandler(OpenVPNProviderConfigurationError.prngInitialization)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +296,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
/// :nodoc:
|
/// :nodoc:
|
||||||
open override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
|
open override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
|
||||||
var response: Data?
|
var response: Data?
|
||||||
switch Message(messageData) {
|
switch OpenVPNProvider.Message(messageData) {
|
||||||
case .requestLog:
|
case .requestLog:
|
||||||
response = memoryLog.description.data(using: .utf8)
|
response = memoryLog.description.data(using: .utf8)
|
||||||
|
|
||||||
|
@ -398,7 +402,7 @@ open class OpenVPNTunnelProvider: NEPacketTunnelProvider {
|
||||||
// from stopTunnel(), in which case we don't need to feed an error parameter to
|
// from stopTunnel(), in which case we don't need to feed an error parameter to
|
||||||
// the stop completion handler
|
// the stop completion handler
|
||||||
//
|
//
|
||||||
pendingStartHandler?(error ?? ProviderError.socketActivity)
|
pendingStartHandler?(error ?? OpenVPNProviderError.socketActivity)
|
||||||
pendingStartHandler = nil
|
pendingStartHandler = nil
|
||||||
}
|
}
|
||||||
// stopped intentionally
|
// stopped intentionally
|
||||||
|
@ -476,7 +480,7 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate {
|
||||||
// look for error causing shutdown
|
// look for error causing shutdown
|
||||||
shutdownError = session.stopError
|
shutdownError = session.stopError
|
||||||
if failure && (shutdownError == nil) {
|
if failure && (shutdownError == nil) {
|
||||||
shutdownError = ProviderError.linkError
|
shutdownError = OpenVPNProviderError.linkError
|
||||||
}
|
}
|
||||||
didTimeoutNegotiation = (shutdownError as? OpenVPNError == .negotiationTimeout)
|
didTimeoutNegotiation = (shutdownError as? OpenVPNError == .negotiationTimeout)
|
||||||
|
|
||||||
|
@ -522,7 +526,7 @@ extension OpenVPNTunnelProvider: GenericSocketDelegate {
|
||||||
public func socketHasBetterPath(_ socket: GenericSocket) {
|
public func socketHasBetterPath(_ socket: GenericSocket) {
|
||||||
log.debug("Stopping tunnel due to a new better path")
|
log.debug("Stopping tunnel due to a new better path")
|
||||||
logCurrentSSID()
|
logCurrentSSID()
|
||||||
session?.reconnect(error: ProviderError.networkChanged)
|
session?.reconnect(error: OpenVPNProviderError.networkChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,7 +687,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate {
|
||||||
hasGateway = true
|
hasGateway = true
|
||||||
}
|
}
|
||||||
guard !isGateway || hasGateway else {
|
guard !isGateway || hasGateway else {
|
||||||
session?.shutdown(error: ProviderError.gatewayUnattainable)
|
session?.shutdown(error: OpenVPNProviderError.gatewayUnattainable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +708,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate {
|
||||||
|
|
||||||
case .tls:
|
case .tls:
|
||||||
guard let dnsServers = cfg.sessionConfiguration.dnsServers else {
|
guard let dnsServers = cfg.sessionConfiguration.dnsServers else {
|
||||||
session?.shutdown(error: ProviderError.dnsFailure)
|
session?.shutdown(error: OpenVPNProviderError.dnsFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let serverName = cfg.sessionConfiguration.dnsTLSServerName else {
|
guard let serverName = cfg.sessionConfiguration.dnsTLSServerName else {
|
||||||
|
@ -848,7 +852,7 @@ extension OpenVPNTunnelProvider: OpenVPNSessionDelegate {
|
||||||
extension OpenVPNTunnelProvider {
|
extension OpenVPNTunnelProvider {
|
||||||
private func tryNextEndpoint() -> Bool {
|
private func tryNextEndpoint() -> Bool {
|
||||||
guard strategy.tryNextEndpoint() else {
|
guard strategy.tryNextEndpoint() else {
|
||||||
disposeTunnel(error: ProviderError.exhaustedProtocols)
|
disposeTunnel(error: OpenVPNProviderError.exhaustedProtocols)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -900,10 +904,10 @@ extension OpenVPNTunnelProvider {
|
||||||
// MARK: Errors
|
// MARK: Errors
|
||||||
|
|
||||||
private func setErrorStatus(with error: Error) {
|
private func setErrorStatus(with error: Error) {
|
||||||
defaults?.set(unifiedError(from: error).rawValue, forKey: Configuration.lastErrorKey)
|
defaults?.set(unifiedError(from: error).rawValue, forKey: OpenVPNProvider.Configuration.lastErrorKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unifiedError(from error: Error) -> ProviderError {
|
private func unifiedError(from error: Error) -> OpenVPNProviderError {
|
||||||
if let te = error.tunnelKitErrorCode() {
|
if let te = error.tunnelKitErrorCode() {
|
||||||
switch te {
|
switch te {
|
||||||
case .cryptoRandomGenerator, .cryptoAlgorithm:
|
case .cryptoRandomGenerator, .cryptoAlgorithm:
|
||||||
|
@ -957,7 +961,7 @@ extension OpenVPNTunnelProvider {
|
||||||
return .unexpectedReply
|
return .unexpectedReply
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error as? ProviderError ?? .linkError
|
return error as? OpenVPNProviderError ?? .linkError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNCore
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ extension OpenVPN {
|
||||||
/// Any other compression algorithm (unsupported).
|
/// Any other compression algorithm (unsupported).
|
||||||
case other
|
case other
|
||||||
|
|
||||||
var native: CompressionAlgorithmNative {
|
/// :nodoc:
|
||||||
|
public var native: CompressionAlgorithmNative {
|
||||||
guard let val = CompressionAlgorithmNative(rawValue: rawValue) else {
|
guard let val = CompressionAlgorithmNative(rawValue: rawValue) else {
|
||||||
fatalError("Unhandled CompressionAlgorithm bridging")
|
fatalError("Unhandled CompressionAlgorithm bridging")
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNCore
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ extension OpenVPN {
|
||||||
/// Framing compatible with 2.4 `compress` (version 2, e.g. stub-v2).
|
/// Framing compatible with 2.4 `compress` (version 2, e.g. stub-v2).
|
||||||
case compressV2
|
case compressV2
|
||||||
|
|
||||||
var native: CompressionFramingNative {
|
/// :nodoc:
|
||||||
|
public var native: CompressionFramingNative {
|
||||||
guard let val = CompressionFramingNative(rawValue: rawValue) else {
|
guard let val = CompressionFramingNative(rawValue: rawValue) else {
|
||||||
fatalError("Unhandled CompressionFraming bridging")
|
fatalError("Unhandled CompressionFraming bridging")
|
||||||
}
|
}
|
|
@ -561,7 +561,9 @@ extension OpenVPN.Configuration {
|
||||||
// MARK: Encoding
|
// MARK: Encoding
|
||||||
|
|
||||||
extension OpenVPN.Configuration {
|
extension OpenVPN.Configuration {
|
||||||
func print() {
|
|
||||||
|
/// :nodoc:
|
||||||
|
public func print() {
|
||||||
guard let endpointProtocols = endpointProtocols else {
|
guard let endpointProtocols = endpointProtocols else {
|
||||||
fatalError("No sessionConfiguration.endpointProtocols set")
|
fatalError("No sessionConfiguration.endpointProtocols set")
|
||||||
}
|
}
|
|
@ -26,8 +26,8 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import _TunnelKitUtils
|
import __TunnelKitUtils
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ extension OpenVPN {
|
||||||
|
|
||||||
// XXX: parsing is very optimistic
|
// XXX: parsing is very optimistic
|
||||||
|
|
||||||
struct Regex {
|
public struct Regex {
|
||||||
|
|
||||||
// MARK: General
|
// MARK: General
|
||||||
|
|
||||||
|
@ -84,7 +84,8 @@ extension OpenVPN {
|
||||||
|
|
||||||
// MARK: Server
|
// MARK: Server
|
||||||
|
|
||||||
static let authToken = NSRegularExpression("^auth-token +[a-zA-Z0-9/=+]+")
|
/// :nodoc:
|
||||||
|
public static let authToken = NSRegularExpression("^auth-token +[a-zA-Z0-9/=+]+")
|
||||||
|
|
||||||
static let peerId = NSRegularExpression("^peer-id +[0-9]+")
|
static let peerId = NSRegularExpression("^peer-id +[0-9]+")
|
||||||
|
|
||||||
|
@ -679,6 +680,7 @@ extension OpenVPN {
|
||||||
sessionBuilder.clientCertificate = optClientCertificate
|
sessionBuilder.clientCertificate = optClientCertificate
|
||||||
|
|
||||||
if let clientKey = optClientKey, clientKey.isEncrypted {
|
if let clientKey = optClientKey, clientKey.isEncrypted {
|
||||||
|
// FIXME: remove dependency on TLSBox
|
||||||
guard let passphrase = passphrase else {
|
guard let passphrase = passphrase else {
|
||||||
throw ConfigurationError.encryptionPassphrase
|
throw ConfigurationError.encryptionPassphrase
|
||||||
}
|
}
|
|
@ -35,7 +35,9 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import _TunnelKitOpenVPNObjC
|
|
||||||
|
// FIXME: remove dependency on TLSBox
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ extension OpenVPN {
|
||||||
try pem.write(to: url, atomically: true, encoding: .ascii)
|
try pem.write(to: url, atomically: true, encoding: .ascii)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: remove dependency on TLSBox
|
||||||
func decrypted(with passphrase: String) throws -> CryptoContainer {
|
func decrypted(with passphrase: String) throws -> CryptoContainer {
|
||||||
let decryptedPEM = try TLSBox.decryptedPrivateKey(fromPEM: pem, passphrase: passphrase)
|
let decryptedPEM = try TLSBox.decryptedPrivateKey(fromPEM: pem, passphrase: passphrase)
|
||||||
return CryptoContainer(pem: decryptedPEM)
|
return CryptoContainer(pem: decryptedPEM)
|
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// OpenVPN.swift
|
||||||
|
// TunnelKit
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 5/19/19.
|
||||||
|
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of TunnelKit.
|
||||||
|
//
|
||||||
|
// TunnelKit is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// TunnelKit is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Container for OpenVPN classes.
|
||||||
|
public class OpenVPN {
|
||||||
|
}
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
|
|
||||||
|
@ -61,7 +61,8 @@ extension OpenVPN {
|
||||||
|
|
||||||
private let secureData: ZeroingData
|
private let secureData: ZeroingData
|
||||||
|
|
||||||
let direction: Direction?
|
/// :nodoc:
|
||||||
|
public let direction: Direction?
|
||||||
|
|
||||||
/// Returns the encryption key.
|
/// Returns the encryption key.
|
||||||
///
|
///
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// OpenVPNTunnelProvider+Configuration.swift
|
// OpenVPNProvider+Configuration.swift
|
||||||
// TunnelKit
|
// TunnelKit
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 10/23/17.
|
// Created by Davide De Rosa on 10/23/17.
|
||||||
|
@ -38,20 +38,21 @@ import Foundation
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import TunnelKitAppExtension
|
import TunnelKitManager
|
||||||
import _TunnelKitUtils
|
import CTunnelKitCore
|
||||||
|
import __TunnelKitUtils
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
extension OpenVPNTunnelProvider {
|
extension OpenVPNProvider {
|
||||||
private struct ExtraKeys {
|
private struct ExtraKeys {
|
||||||
static let appGroup = "appGroup"
|
static let appGroup = "appGroup"
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Configuration
|
// MARK: Configuration
|
||||||
|
|
||||||
/// The way to create a `OpenVPNTunnelProvider.Configuration` object for the tunnel profile.
|
/// The way to create a `OpenVPNProvider.Configuration` object for the tunnel profile.
|
||||||
public struct ConfigurationBuilder {
|
public struct ConfigurationBuilder {
|
||||||
|
|
||||||
/// :nodoc:
|
/// :nodoc:
|
||||||
|
@ -108,9 +109,9 @@ extension OpenVPNTunnelProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Builds a `OpenVPNTunnelProvider.Configuration` object that will connect to the provided endpoint.
|
Builds a `OpenVPNProvider.Configuration` object that will connect to the provided endpoint.
|
||||||
|
|
||||||
- Returns: A `OpenVPNTunnelProvider.Configuration` object with this builder and the additional method parameters.
|
- Returns: A `OpenVPNProvider.Configuration` object with this builder and the additional method parameters.
|
||||||
*/
|
*/
|
||||||
public func build() -> Configuration {
|
public func build() -> Configuration {
|
||||||
return Configuration(
|
return Configuration(
|
||||||
|
@ -125,35 +126,36 @@ extension OpenVPNTunnelProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Offers a bridge between the abstract `OpenVPNTunnelProvider.ConfigurationBuilder` and a concrete `NETunnelProviderProtocol` profile.
|
/// Offers a bridge between the abstract `OpenVPNProvider.ConfigurationBuilder` and a concrete `NETunnelProviderProtocol` profile.
|
||||||
public struct Configuration: Codable {
|
public struct Configuration: Codable {
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.sessionConfiguration`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.sessionConfiguration`
|
||||||
public let sessionConfiguration: OpenVPN.Configuration
|
public let sessionConfiguration: OpenVPN.Configuration
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.prefersResolvedAddresses`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.prefersResolvedAddresses`
|
||||||
public let prefersResolvedAddresses: Bool
|
public let prefersResolvedAddresses: Bool
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.resolvedAddresses`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.resolvedAddresses`
|
||||||
public let resolvedAddresses: [String]?
|
public let resolvedAddresses: [String]?
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.shouldDebug`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.shouldDebug`
|
||||||
public let shouldDebug: Bool
|
public let shouldDebug: Bool
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.debugLogFormat`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.debugLogFormat`
|
||||||
public let debugLogFormat: String?
|
public let debugLogFormat: String?
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.masksPrivateData`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.masksPrivateData`
|
||||||
public let masksPrivateData: Bool?
|
public let masksPrivateData: Bool?
|
||||||
|
|
||||||
/// - Seealso: `OpenVPNTunnelProvider.ConfigurationBuilder.versionIdentifier`
|
/// - Seealso: `OpenVPNProvider.ConfigurationBuilder.versionIdentifier`
|
||||||
public let versionIdentifier: String?
|
public let versionIdentifier: String?
|
||||||
|
|
||||||
// MARK: Shortcuts
|
// MARK: Shortcuts
|
||||||
|
|
||||||
static let debugLogFilename = "debug.log"
|
static let debugLogFilename = "debug.log"
|
||||||
|
|
||||||
static let lastErrorKey = "TunnelKitLastError"
|
/// :nodoc:
|
||||||
|
public static let lastErrorKey = "TunnelKitLastError"
|
||||||
|
|
||||||
fileprivate static let dataCountKey = "TunnelKitDataCount"
|
fileprivate static let dataCountKey = "TunnelKitDataCount"
|
||||||
|
|
||||||
|
@ -192,11 +194,11 @@ extension OpenVPNTunnelProvider {
|
||||||
- Parameter in: The app group where to locate the error key.
|
- Parameter in: The app group where to locate the error key.
|
||||||
- Returns: The last tunnel error, if any.
|
- Returns: The last tunnel error, if any.
|
||||||
*/
|
*/
|
||||||
public func lastError(in appGroup: String) -> ProviderError? {
|
public func lastError(in appGroup: String) -> OpenVPNProviderError? {
|
||||||
guard let rawValue = UserDefaults(suiteName: appGroup)?.string(forKey: Configuration.lastErrorKey) else {
|
guard let rawValue = UserDefaults(suiteName: appGroup)?.string(forKey: Configuration.lastErrorKey) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ProviderError(rawValue: rawValue)
|
return OpenVPNProviderError(rawValue: rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,26 +233,26 @@ extension OpenVPNTunnelProvider {
|
||||||
|
|
||||||
- Parameter from: The map to parse.
|
- Parameter from: The map to parse.
|
||||||
- Returns: The parsed app group.
|
- Returns: The parsed app group.
|
||||||
- Throws: `ProviderError.configuration` if `providerConfiguration` does not contain an app group.
|
- Throws: `OpenVPNProviderError.configuration` if `providerConfiguration` does not contain an app group.
|
||||||
*/
|
*/
|
||||||
public static func appGroup(from providerConfiguration: [String: Any]) throws -> String {
|
public static func appGroup(from providerConfiguration: [String: Any]) throws -> String {
|
||||||
guard let appGroup = providerConfiguration[ExtraKeys.appGroup] as? String else {
|
guard let appGroup = providerConfiguration[ExtraKeys.appGroup] as? String else {
|
||||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(ExtraKeys.appGroup)]")
|
throw OpenVPNProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(ExtraKeys.appGroup)]")
|
||||||
}
|
}
|
||||||
return appGroup
|
return appGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Parses a new `OpenVPNTunnelProvider.Configuration` object from a provider configuration map.
|
Parses a new `OpenVPNProvider.Configuration` object from a provider configuration map.
|
||||||
|
|
||||||
- Parameter from: The map to parse.
|
- Parameter from: The map to parse.
|
||||||
- Returns: The parsed `OpenVPNTunnelProvider.Configuration` object.
|
- Returns: The parsed `OpenVPNProvider.Configuration` object.
|
||||||
- Throws: `ProviderError.configuration` if `providerConfiguration` is incomplete.
|
- Throws: `OpenVPNProviderError.configuration` if `providerConfiguration` is incomplete.
|
||||||
*/
|
*/
|
||||||
public static func parsed(from providerConfiguration: [String: Any]) throws -> Configuration {
|
public static func parsed(from providerConfiguration: [String: Any]) throws -> Configuration {
|
||||||
let cfg = try fromDictionary(OpenVPNTunnelProvider.Configuration.self, providerConfiguration)
|
let cfg = try fromDictionary(OpenVPNProvider.Configuration.self, providerConfiguration)
|
||||||
guard !cfg.prefersResolvedAddresses || !(cfg.resolvedAddresses?.isEmpty ?? true) else {
|
guard !cfg.prefersResolvedAddresses || !(cfg.resolvedAddresses?.isEmpty ?? true) else {
|
||||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[prefersResolvedAddresses] is true but no [resolvedAddresses]")
|
throw OpenVPNProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[prefersResolvedAddresses] is true but no [resolvedAddresses]")
|
||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
@ -280,7 +282,7 @@ extension OpenVPNTunnelProvider {
|
||||||
- Parameter context: The keychain context where to look for the password reference.
|
- Parameter context: The keychain context where to look for the password reference.
|
||||||
- Parameter username: The username to authenticate with.
|
- Parameter username: The username to authenticate with.
|
||||||
- Returns: The generated `NETunnelProviderProtocol` object.
|
- Returns: The generated `NETunnelProviderProtocol` object.
|
||||||
- Throws: `ProviderError.credentials` if unable to store `credentials.password` to the `appGroup` keychain.
|
- Throws: `OpenVPNProviderError.credentials` if unable to store `credentials.password` to the `appGroup` keychain.
|
||||||
*/
|
*/
|
||||||
public func generatedTunnelProtocol(
|
public func generatedTunnelProtocol(
|
||||||
withBundleIdentifier bundleIdentifier: String,
|
withBundleIdentifier bundleIdentifier: String,
|
||||||
|
@ -302,7 +304,8 @@ extension OpenVPNTunnelProvider {
|
||||||
return protocolConfiguration
|
return protocolConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
func print(appVersion: String?) {
|
/// :nodoc:
|
||||||
|
public func print(appVersion: String?) {
|
||||||
if let appVersion = appVersion {
|
if let appVersion = appVersion {
|
||||||
log.info("App version: \(appVersion)")
|
log.info("App version: \(appVersion)")
|
||||||
}
|
}
|
||||||
|
@ -315,15 +318,15 @@ extension OpenVPNTunnelProvider {
|
||||||
|
|
||||||
// MARK: Modification
|
// MARK: Modification
|
||||||
|
|
||||||
extension OpenVPNTunnelProvider.Configuration {
|
extension OpenVPNProvider.Configuration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a `OpenVPNTunnelProvider.ConfigurationBuilder` to use this configuration as a starting point for a new one.
|
Returns a `OpenVPNProvider.ConfigurationBuilder` to use this configuration as a starting point for a new one.
|
||||||
|
|
||||||
- Returns: An editable `OpenVPNTunnelProvider.ConfigurationBuilder` initialized with this configuration.
|
- Returns: An editable `OpenVPNProvider.ConfigurationBuilder` initialized with this configuration.
|
||||||
*/
|
*/
|
||||||
public func builder() -> OpenVPNTunnelProvider.ConfigurationBuilder {
|
public func builder() -> OpenVPNProvider.ConfigurationBuilder {
|
||||||
var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration)
|
var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration)
|
||||||
builder.prefersResolvedAddresses = prefersResolvedAddresses
|
builder.prefersResolvedAddresses = prefersResolvedAddresses
|
||||||
builder.resolvedAddresses = resolvedAddresses
|
builder.resolvedAddresses = resolvedAddresses
|
||||||
builder.shouldDebug = shouldDebug
|
builder.shouldDebug = shouldDebug
|
||||||
|
@ -338,14 +341,14 @@ extension OpenVPNTunnelProvider.Configuration {
|
||||||
public extension UserDefaults {
|
public extension UserDefaults {
|
||||||
@objc var dataCountArray: [Int]? {
|
@objc var dataCountArray: [Int]? {
|
||||||
get {
|
get {
|
||||||
return array(forKey: OpenVPNTunnelProvider.Configuration.dataCountKey) as? [Int]
|
return array(forKey: OpenVPNProvider.Configuration.dataCountKey) as? [Int]
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
set(newValue, forKey: OpenVPNTunnelProvider.Configuration.dataCountKey)
|
set(newValue, forKey: OpenVPNProvider.Configuration.dataCountKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeDataCountArray() {
|
func removeDataCountArray() {
|
||||||
removeObject(forKey: OpenVPNTunnelProvider.Configuration.dataCountKey)
|
removeObject(forKey: OpenVPNProvider.Configuration.dataCountKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
//
|
||||||
|
// OpenVPNProvider+Interaction.swift
|
||||||
|
// TunnelKit
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 9/24/17.
|
||||||
|
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of TunnelKit.
|
||||||
|
//
|
||||||
|
// TunnelKit is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// TunnelKit is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This file incorporates work covered by the following copyright and
|
||||||
|
// permission notice:
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension OpenVPNProvider {
|
||||||
|
|
||||||
|
/// The messages accepted by `OpenVPNProvider`.
|
||||||
|
public class Message: Equatable {
|
||||||
|
|
||||||
|
/// Requests a snapshot of the latest debug log. Returns the log data decoded from UTF-8.
|
||||||
|
public static let requestLog = Message(0xff)
|
||||||
|
|
||||||
|
/// Requests the current bytes count from data channel (if connected).
|
||||||
|
///
|
||||||
|
/// Data is 16 bytes: low 8 = received, high 8 = sent.
|
||||||
|
public static let dataCount = Message(0xfe)
|
||||||
|
|
||||||
|
/// Requests the configuration pulled from the server (if connected and available).
|
||||||
|
///
|
||||||
|
/// Data is JSON (Decodable).
|
||||||
|
public static let serverConfiguration = Message(0xfd)
|
||||||
|
|
||||||
|
/// The underlying raw message `Data` to forward to the tunnel via IPC.
|
||||||
|
public let data: Data
|
||||||
|
|
||||||
|
private init(_ byte: UInt8) {
|
||||||
|
data = Data([byte])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public init(_ data: Data) {
|
||||||
|
self.data = data
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Equatable
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
||||||
|
return (lhs.data == rhs.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
|
import TunnelKitOpenVPNCore
|
||||||
import TunnelKitManager
|
import TunnelKitManager
|
||||||
|
|
||||||
/// `VPNProvider` for OpenVPN protocol.
|
/// `VPNProvider` for OpenVPN protocol.
|
||||||
|
@ -105,7 +106,7 @@ public class OpenVPNProvider: VPNProvider, VPNProviderIPC {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try session.sendProviderMessage(OpenVPNTunnelProvider.Message.dataCount.data) { (data) in
|
try session.sendProviderMessage(Message.dataCount.data) { (data) in
|
||||||
guard let data = data, data.count == 16 else {
|
guard let data = data, data.count == 16 else {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
|
@ -135,7 +136,7 @@ public class OpenVPNProvider: VPNProvider, VPNProviderIPC {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try session.sendProviderMessage(OpenVPNTunnelProvider.Message.serverConfiguration.data) { (data) in
|
try session.sendProviderMessage(Message.serverConfiguration.data) { (data) in
|
||||||
guard let data = data, let cfg = try? JSONDecoder().decode(OpenVPN.Configuration.self, from: data) else {
|
guard let data = data, let cfg = try? JSONDecoder().decode(OpenVPN.Configuration.self, from: data) else {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
|
@ -168,7 +169,7 @@ public class OpenVPNProvider: VPNProvider, VPNProviderIPC {
|
||||||
|
|
||||||
private static func requestDebugLog(session: NETunnelProviderSession, completionHandler: @escaping (String?) -> Void) {
|
private static func requestDebugLog(session: NETunnelProviderSession, completionHandler: @escaping (String?) -> Void) {
|
||||||
do {
|
do {
|
||||||
try session.sendProviderMessage(OpenVPNTunnelProvider.Message.requestLog.data) { (data) in
|
try session.sendProviderMessage(Message.requestLog.data) { (data) in
|
||||||
guard let data = data, !data.isEmpty else {
|
guard let data = data, !data.isEmpty else {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
return
|
return
|
|
@ -0,0 +1,111 @@
|
||||||
|
//
|
||||||
|
// OpenVPNProviderError.swift
|
||||||
|
// TunnelKit
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 11/8/21.
|
||||||
|
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of TunnelKit.
|
||||||
|
//
|
||||||
|
// TunnelKit is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// TunnelKit is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// This file incorporates work covered by the following copyright and
|
||||||
|
// permission notice:
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018-Present Private Internet Access
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Mostly programming errors by host app.
|
||||||
|
public enum OpenVPNProviderConfigurationError: Error {
|
||||||
|
|
||||||
|
/// A field in the `OpenVPNProvider.Configuration` provided is incorrect or incomplete.
|
||||||
|
case parameter(name: String)
|
||||||
|
|
||||||
|
/// Credentials are missing or inaccessible.
|
||||||
|
case credentials(details: String)
|
||||||
|
|
||||||
|
/// The pseudo-random number generator could not be initialized.
|
||||||
|
case prngInitialization
|
||||||
|
|
||||||
|
/// The TLS certificate could not be serialized.
|
||||||
|
case certificateSerialization
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The errors causing a tunnel disconnection.
|
||||||
|
public enum OpenVPNProviderError: String, Error {
|
||||||
|
|
||||||
|
/// Socket endpoint could not be resolved.
|
||||||
|
case dnsFailure
|
||||||
|
|
||||||
|
/// No more protocols available to try.
|
||||||
|
case exhaustedProtocols
|
||||||
|
|
||||||
|
/// Socket failed to reach active state.
|
||||||
|
case socketActivity
|
||||||
|
|
||||||
|
/// Credentials authentication failed.
|
||||||
|
case authentication
|
||||||
|
|
||||||
|
/// TLS could not be initialized (e.g. malformed CA or client PEMs).
|
||||||
|
case tlsInitialization
|
||||||
|
|
||||||
|
/// TLS server verification failed.
|
||||||
|
case tlsServerVerification
|
||||||
|
|
||||||
|
/// TLS handshake failed.
|
||||||
|
case tlsHandshake
|
||||||
|
|
||||||
|
/// The encryption logic could not be initialized (e.g. PRNG, algorithms).
|
||||||
|
case encryptionInitialization
|
||||||
|
|
||||||
|
/// Data encryption/decryption failed.
|
||||||
|
case encryptionData
|
||||||
|
|
||||||
|
/// The LZO engine failed.
|
||||||
|
case lzo
|
||||||
|
|
||||||
|
/// Server uses an unsupported compression algorithm.
|
||||||
|
case serverCompression
|
||||||
|
|
||||||
|
/// Tunnel timed out.
|
||||||
|
case timeout
|
||||||
|
|
||||||
|
/// An error occurred at the link level.
|
||||||
|
case linkError
|
||||||
|
|
||||||
|
/// Network routing information is missing or incomplete.
|
||||||
|
case routing
|
||||||
|
|
||||||
|
/// The current network changed (e.g. switched from WiFi to data connection).
|
||||||
|
case networkChanged
|
||||||
|
|
||||||
|
/// Default gateway could not be attained.
|
||||||
|
case gatewayUnattainable
|
||||||
|
|
||||||
|
/// Remove server has shut down.
|
||||||
|
case serverShutdown
|
||||||
|
|
||||||
|
/// The server replied in an unexpected way.
|
||||||
|
case unexpectedReply
|
||||||
|
}
|
|
@ -37,8 +37,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
|
@ -26,8 +26,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
|
@ -26,8 +26,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
extension CoreConfiguration {
|
extension CoreConfiguration {
|
||||||
struct OpenVPN {
|
struct OpenVPN {
|
|
@ -36,8 +36,9 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
class EncryptionBridge {
|
class EncryptionBridge {
|
|
@ -1,8 +1,8 @@
|
||||||
//
|
//
|
||||||
// OpenVPN.swift
|
// OpenVPN+PRNG.swift
|
||||||
// TunnelKit
|
// TunnelKit
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 5/19/19.
|
// Created by Davide De Rosa on 11/8/21.
|
||||||
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
|
||||||
//
|
//
|
||||||
// https://github.com/passepartoutvpn
|
// https://github.com/passepartoutvpn
|
||||||
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
/// Container for OpenVPN classes.
|
extension OpenVPN {
|
||||||
public class OpenVPN {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes the PRNG. Must be issued before using `OpenVPNSession`.
|
Initializes the PRNG. Must be issued before using `OpenVPNSession`.
|
||||||
|
@ -45,5 +45,4 @@ public class OpenVPN {
|
||||||
}
|
}
|
||||||
return CryptoBox.preparePRNG(withSeed: seed.bytes, length: seed.count)
|
return CryptoBox.preparePRNG(withSeed: seed.bytes, length: seed.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
|
import TunnelKitOpenVPNCore
|
||||||
|
|
||||||
extension OpenVPNSession {
|
extension OpenVPNSession {
|
||||||
struct PIAHardReset {
|
struct PIAHardReset {
|
|
@ -37,8 +37,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
/// :nodoc:
|
/// :nodoc:
|
||||||
extension ControlPacket {
|
extension ControlPacket {
|
|
@ -35,6 +35,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import TunnelKitOpenVPNCore
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
class ProtocolMacros {
|
class ProtocolMacros {
|
|
@ -35,6 +35,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import TunnelKitOpenVPNCore
|
||||||
|
|
||||||
extension OpenVPN {
|
extension OpenVPN {
|
||||||
struct PushReply: CustomStringConvertible {
|
struct PushReply: CustomStringConvertible {
|
|
@ -37,8 +37,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftyBeaver
|
import SwiftyBeaver
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
private let log = SwiftyBeaver.self
|
private let log = SwiftyBeaver.self
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
|
|
||||||
class RoutingTests: XCTestCase {
|
class RoutingTests: XCTestCase {
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import TunnelKitLZO
|
import TunnelKitLZO
|
||||||
|
|
||||||
class CompressionTests: XCTestCase {
|
class CompressionTests: XCTestCase {
|
||||||
|
|
|
@ -36,9 +36,12 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
@testable import TunnelKitCore
|
import TunnelKitCore
|
||||||
@testable import TunnelKitOpenVPN
|
import TunnelKitOpenVPNCore
|
||||||
@testable import TunnelKitAppExtension
|
import TunnelKitAppExtension
|
||||||
|
@testable import TunnelKitOpenVPNAppExtension
|
||||||
|
import TunnelKitManager
|
||||||
|
import TunnelKitOpenVPNManager
|
||||||
|
|
||||||
class AppExtensionTests: XCTestCase {
|
class AppExtensionTests: XCTestCase {
|
||||||
|
|
||||||
|
@ -53,8 +56,8 @@ class AppExtensionTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testConfiguration() {
|
func testConfiguration() {
|
||||||
var builder: OpenVPNTunnelProvider.ConfigurationBuilder!
|
var builder: OpenVPNProvider.ConfigurationBuilder!
|
||||||
var cfg: OpenVPNTunnelProvider.Configuration!
|
var cfg: OpenVPNProvider.Configuration!
|
||||||
|
|
||||||
let identifier = "com.example.Provider"
|
let identifier = "com.example.Provider"
|
||||||
let appGroup = "group.com.algoritmico.TunnelKit"
|
let appGroup = "group.com.algoritmico.TunnelKit"
|
||||||
|
@ -69,7 +72,7 @@ class AppExtensionTests: XCTestCase {
|
||||||
sessionBuilder.hostname = hostname
|
sessionBuilder.hostname = hostname
|
||||||
sessionBuilder.endpointProtocols = []
|
sessionBuilder.endpointProtocols = []
|
||||||
sessionBuilder.mtu = 1230
|
sessionBuilder.mtu = 1230
|
||||||
builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||||
XCTAssertNotNil(builder)
|
XCTAssertNotNil(builder)
|
||||||
|
|
||||||
cfg = builder.build()
|
cfg = builder.build()
|
||||||
|
@ -147,7 +150,7 @@ class AppExtensionTests: XCTestCase {
|
||||||
EndpointProtocol(.udp, 1111),
|
EndpointProtocol(.udp, 1111),
|
||||||
EndpointProtocol(.udp4, 3333)
|
EndpointProtocol(.udp4, 3333)
|
||||||
]
|
]
|
||||||
var builder2 = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: builder1.build())
|
var builder2 = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: builder1.build())
|
||||||
builder2.prefersResolvedAddresses = true
|
builder2.prefersResolvedAddresses = true
|
||||||
builder2.resolvedAddresses = [
|
builder2.resolvedAddresses = [
|
||||||
"82.102.21.218",
|
"82.102.21.218",
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
import TunnelKitCore
|
import TunnelKitCore
|
||||||
import TunnelKitOpenVPN
|
import TunnelKitOpenVPNCore
|
||||||
|
|
||||||
class ConfigurationParserTests: XCTestCase {
|
class ConfigurationParserTests: XCTestCase {
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
@testable import TunnelKitOpenVPNCore
|
||||||
@testable import TunnelKitOpenVPN
|
@testable import TunnelKitOpenVPNProtocol
|
||||||
import _TunnelKitOpenVPNObjC
|
@testable import TunnelKitOpenVPNAppExtension
|
||||||
|
import CTunnelKitCore
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class ControlChannelTests: XCTestCase {
|
class ControlChannelTests: XCTestCase {
|
||||||
private let hex = "634a4d2d459d606c8e6abbec168fdcd1871462eaa2eaed84c8f403bdf8c7da737d81b5774cc35fe0a42b38aa053f1335fd4a22d721880433bbb20ae1f2d88315b2d186b3b377685506fa39d85d38da16c2ecc0d631bda64f9d8f5a8d073f18aab97ade23e49ea9e7de86784d1ed5fa356df5f7fa1d163e5537efa8d4ba61239dc301a9aa55de0e06e33a7545f7d0cc153405576464ba92942dafa5fb79c7a60663ff1e7da3122ae09d4561653bef3eeb312ad68b191e2f94cbcf4e21caff0b59f8be86567bd21787070c2dc10a8baf7e87ce2e07d7d7de25ead11bd6d6e6ec030c0a3fd50d2d0ca3c0378022bb642e954868d7b93e18a131ecbb12b0bbedb1ce"
|
private let hex = "634a4d2d459d606c8e6abbec168fdcd1871462eaa2eaed84c8f403bdf8c7da737d81b5774cc35fe0a42b38aa053f1335fd4a22d721880433bbb20ae1f2d88315b2d186b3b377685506fa39d85d38da16c2ecc0d631bda64f9d8f5a8d073f18aab97ade23e49ea9e7de86784d1ed5fa356df5f7fa1d163e5537efa8d4ba61239dc301a9aa55de0e06e33a7545f7d0cc153405576464ba92942dafa5fb79c7a60663ff1e7da3122ae09d4561653bef3eeb312ad68b191e2f94cbcf4e21caff0b59f8be86567bd21787070c2dc10a8baf7e87ce2e07d7d7de25ead11bd6d6e6ec030c0a3fd50d2d0ca3c0378022bb642e954868d7b93e18a131ecbb12b0bbedb1ce"
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class DataPathEncryptionTests: XCTestCase {
|
class DataPathEncryptionTests: XCTestCase {
|
||||||
private let cipherKey = try! SecureRandom.safeData(length: 32)
|
private let cipherKey = try! SecureRandom.safeData(length: 32)
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
@testable import TunnelKitOpenVPN
|
@testable import TunnelKitOpenVPNCore
|
||||||
import _TunnelKitOpenVPNObjC
|
@testable import TunnelKitOpenVPNProtocol
|
||||||
|
@testable import TunnelKitOpenVPNAppExtension
|
||||||
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class DataPathPerformanceTests: XCTestCase {
|
class DataPathPerformanceTests: XCTestCase {
|
||||||
private var dataPath: DataPath!
|
private var dataPath: DataPath!
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
import CTunnelKitCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class EncryptionPerformanceTests: XCTestCase {
|
class EncryptionPerformanceTests: XCTestCase {
|
||||||
private var cbcEncrypter: Encrypter!
|
private var cbcEncrypter: Encrypter!
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitCoreObjC
|
@testable import TunnelKitOpenVPNCore
|
||||||
import TunnelKitOpenVPN
|
import CTunnelKitCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class EncryptionTests: XCTestCase {
|
class EncryptionTests: XCTestCase {
|
||||||
private var cipherEncKey: ZeroingData!
|
private var cipherEncKey: ZeroingData!
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
@testable import _TunnelKitCoreObjC
|
@testable import CTunnelKitCore
|
||||||
|
|
||||||
class LinkTests: XCTestCase {
|
class LinkTests: XCTestCase {
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import _TunnelKitOpenVPNObjC
|
import CTunnelKitOpenVPNProtocol
|
||||||
|
|
||||||
class PacketTests: XCTestCase {
|
class PacketTests: XCTestCase {
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
@testable import TunnelKitOpenVPN
|
@testable import TunnelKitOpenVPNCore
|
||||||
|
@testable import TunnelKitOpenVPNProtocol
|
||||||
|
@testable import TunnelKitOpenVPNAppExtension
|
||||||
|
|
||||||
private extension OpenVPN.PushReply {
|
private extension OpenVPN.PushReply {
|
||||||
func debug() {
|
func debug() {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import TunnelKitCore
|
@testable import TunnelKitCore
|
||||||
import TunnelKitOpenVPN
|
import TunnelKitOpenVPNCore
|
||||||
|
|
||||||
class StaticKeyTests: XCTestCase {
|
class StaticKeyTests: XCTestCase {
|
||||||
private let content = """
|
private let content = """
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue