├── Sources ├── TunnelKitLZO │ ├── include │ │ ├── lzo │ │ │ ├── lzoconf.h │ │ │ └── lzodefs.h │ │ ├── Errors.h │ │ └── StandardLZO.h │ └── lib │ │ ├── Makefile │ │ └── minilzo.h ├── TunnelKit │ └── Exports.swift ├── TunnelKitOpenVPN │ └── Exports.swift ├── TunnelKitOpenVPNCore │ ├── OpenVPN.swift │ ├── Errors.swift │ ├── ConfigurationError.swift │ ├── TLSWrap.swift │ ├── CompressionAlgorithm.swift │ ├── CompressionFraming.swift │ └── OpenVPNError.swift ├── TunnelKitManager │ ├── VPNConfiguration.swift │ ├── VPNStatus.swift │ ├── VPN.swift │ ├── NetworkExtensionVPNConfiguration.swift │ ├── VPNProviderIPC.swift │ ├── VPNProvider.swift │ ├── NetworkExtensionLocator.swift │ └── MockVPNProvider.swift ├── CTunnelKitOpenVPNCore │ ├── include │ │ ├── CompressionAlgorithmNative.h │ │ ├── CompressionFramingNative.h │ │ └── Errors.h │ └── Errors.m ├── CTunnelKitCore │ ├── include │ │ ├── LZOFactory.h │ │ ├── CompressionProvider.h │ │ ├── RoutingTable.h │ │ ├── RoutingTableEntry.h │ │ ├── Allocation.h │ │ └── ZeroingData.h │ ├── LZOFactory.m │ └── Allocation.m ├── TunnelKitAppExtension │ ├── LinkProducer.swift │ └── Transport │ │ ├── NWUDPSessionState+Description.swift │ │ └── NWTCPConnectionState+Description.swift ├── CTunnelKitOpenVPNProtocol │ ├── include │ │ ├── CryptoCTR.h │ │ ├── PacketStream.h │ │ ├── MSS.h │ │ ├── ReplayProtector.h │ │ ├── CryptoMacros.h │ │ ├── CryptoAEAD.h │ │ ├── CryptoCBC.h │ │ ├── ControlPacket.h │ │ └── DataPath.h │ ├── PacketMacros.m │ └── PacketStream.m ├── TunnelKitCore │ ├── DNSProtocol.swift │ ├── SocketType.swift │ ├── Proxy.swift │ ├── BidirectionalState.swift │ ├── IPHeader.swift │ ├── TunnelInterface.swift │ ├── LinkInterface.swift │ ├── IPv4Settings.swift │ ├── IPv6Settings.swift │ ├── EndpointProtocol.swift │ ├── ZeroingData.swift │ └── IOInterface.swift ├── TunnelKitOpenVPNProtocol │ ├── OpenVPN+PRNG.swift │ ├── ProtocolMacros.swift │ └── PushReply.swift ├── __TunnelKitUtils │ ├── NSRegularExpression+Shortcuts.swift │ └── Utils.swift ├── TunnelKitOpenVPNManager │ └── OpenVPNProvider+Interaction.swift └── TunnelKitIKE │ └── NativeProvider.swift ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE.md ├── Demo ├── Demo │ ├── iOS │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Demo.entitlements │ │ ├── DemoTunnel.entitlements │ │ ├── Demo.plist │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ └── AppDelegate.swift │ ├── macOS │ │ ├── Demo.entitlements │ │ ├── DemoTunnel.entitlements │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Demo.plist │ │ └── AppDelegate.swift │ ├── PacketTunnelProvider.swift │ └── DemoTunnel.plist ├── Host │ ├── Host.entitlements │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── ViewController.swift └── TunnelKit.xcodeproj │ └── xcshareddata │ └── xcschemes │ ├── TunnelKitDemo-iOS.xcscheme │ ├── TunnelKitDemo-macOS.xcscheme │ └── TunnelKitHost.xcscheme ├── .gitignore ├── CONTRIBUTING.md ├── .travis.yml ├── Package.resolved ├── CLA.rst └── Tests ├── TunnelKitOpenVPNTests ├── Resources │ ├── pia-2048.pem │ ├── tunnelbear.key │ ├── tunnelbear.enc.1.key │ ├── pia-hungary.ovpn │ └── tunnelbear.enc.8.key ├── PacketTests.swift └── StaticKeyTests.swift ├── TunnelKitLZOTests └── CompressionTests.swift └── TunnelKitCoreTests ├── TestUtils.swift └── RandomTests.swift /Sources/TunnelKitLZO/include/lzo/lzoconf.h: -------------------------------------------------------------------------------- 1 | ../../lib/lzoconf.h -------------------------------------------------------------------------------- /Sources/TunnelKitLZO/include/lzo/lzodefs.h: -------------------------------------------------------------------------------- 1 | ../../lib/lzodefs.h -------------------------------------------------------------------------------- /Sources/TunnelKit/Exports.swift: -------------------------------------------------------------------------------- 1 | @_exported import TunnelKitManager 2 | -------------------------------------------------------------------------------- /Sources/TunnelKitLZO/include/Errors.h: -------------------------------------------------------------------------------- 1 | ../../_TunnelKitCoreObjC/include/Errors.h -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: passepartoutvpn 2 | custom: [ 3 | "https://passepartoutvpn.app/donate/" 4 | ] 5 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sources/TunnelKitLZO/include/StandardLZO.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | extern NSString *const TunnelKitLZOErrorDomain; 4 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPN/Exports.swift: -------------------------------------------------------------------------------- 1 | @_exported import TunnelKitCore 2 | @_exported import TunnelKitOpenVPNCore 3 | @_exported import TunnelKitOpenVPNManager 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *.pbxuser 4 | **/*.xcworkspace/xcuserdata 5 | **/*.xcodeproj/project.xcworkspace 6 | **/*.xcodeproj/xcuserdata 7 | Pods 8 | docs 9 | build 10 | .swiftpm 11 | .build 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | ### Steps to reproduce 4 | 5 | ### What is the current bug behavior? 6 | 7 | ### What is the expected correct behavior? 8 | 9 | ### Relevant logs and/or screenshots 10 | 11 | ### Possible fixes suggested remediation 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | - Use imperative commit messages. 4 | - GOOD: "Add new feature" 5 | - BAD: "Added new feature" 6 | - Rebase your branch to `master` and possibly squash unrelevant commits. 7 | - Make sure to pass the unit tests, as long as CI doesn't automate them yet. 8 | - Submit the PR. 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode12.2 3 | xcode_workspace: TunnelKit.xcworkspace 4 | xcode_scheme: TunnelKit-iOS 5 | xcode_destination: platform=iOS Simulator,OS=14.2,name=iPhone 11 Pro Max 6 | cache: 7 | bundler: true 8 | cocoapods: true 9 | branches: 10 | only: 11 | - master 12 | install: 13 | - bundle install --jobs=3 --deployment --path=${BUNDLE_PATH:-vendor/bundle} 14 | - bundle exec pod repo update 15 | - travis_wait 40 bundle exec pod install 16 | -------------------------------------------------------------------------------- /Demo/Host/Host.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.algoritmico.TunnelKit 8 | 9 | keychain-access-groups 10 | 11 | $(AppIdentifierPrefix)group.com.algoritmico.TunnelKit 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/Demo.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | packet-tunnel-provider 8 | 9 | com.apple.security.application-groups 10 | 11 | group.com.algoritmico.TunnelKit.Demo 12 | 13 | keychain-access-groups 14 | 15 | $(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/DemoTunnel.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | packet-tunnel-provider 8 | 9 | com.apple.security.application-groups 10 | 11 | group.com.algoritmico.TunnelKit.Demo 12 | 13 | keychain-access-groups 14 | 15 | $(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "openssl-apple", 6 | "repositoryURL": "git@github.com:pia-foss/ios-openssl.git", 7 | "state": { 8 | "branch": "main", 9 | "revision": "8895baef87867f2a2b8a33578d6c634a14b12a9a", 10 | "version": null 11 | } 12 | }, 13 | { 14 | "package": "SwiftyBeaver", 15 | "repositoryURL": "https://github.com/SwiftyBeaver/SwiftyBeaver", 16 | "state": { 17 | "branch": null, 18 | "revision": "2c039501d6eeb4d4cd4aec4a8d884ad28862e044", 19 | "version": "1.9.5" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /Demo/Demo/macOS/Demo.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | packet-tunnel-provider 8 | 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | $(TeamIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 14 | 15 | com.apple.security.network.client 16 | 17 | keychain-access-groups 18 | 19 | $(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/Demo/macOS/DemoTunnel.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | packet-tunnel-provider 8 | 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | $(TeamIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 14 | 15 | com.apple.security.network.client 16 | 17 | keychain-access-groups 18 | 19 | $(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /CLA.rst: -------------------------------------------------------------------------------- 1 | By making a contribution to this project, I certify that: 2 | 3 | (a) The contribution was created in whole or in part by me and I have the right to submit it under the MIT license; or 4 | 5 | (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the MIT license; or 6 | 7 | (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. 8 | 9 | (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. 10 | -------------------------------------------------------------------------------- /Demo/Demo/PacketTunnelProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PacketTunnelProvider.swift 3 | // Demo 4 | // 5 | // Created by Davide De Rosa on 9/15/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/keeshux 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import TunnelKitOpenVPNAppExtension 27 | 28 | class PacketTunnelProvider: OpenVPNTunnelProvider { 29 | } 30 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/OpenVPN.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OpenVPN.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Container for OpenVPN classes. 29 | public class OpenVPN { 30 | } 31 | -------------------------------------------------------------------------------- /Demo/Demo/macOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Sources/TunnelKitManager/VPNConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPNConfiguration.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/18/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Generic marker for objects able to configure a `VPNProvider`. 29 | public protocol VPNConfiguration { 30 | 31 | /// The profile title in device settings. 32 | var title: String { get } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNCore/include/CompressionAlgorithmNative.h: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionFramingNative.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | typedef NS_ENUM(NSInteger, CompressionAlgorithmNative) { 29 | CompressionAlgorithmNativeDisabled, 30 | CompressionAlgorithmNativeLZO, 31 | CompressionAlgorithmNativeOther 32 | }; 33 | -------------------------------------------------------------------------------- /Demo/Demo/macOS/Demo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 4.0.0 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | public.app-category.productivity 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright (c) 2021 Davide De Rosa. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/LZOFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // LZOFactory.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/18/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | #import "CompressionProvider.h" 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | @interface LZOFactory : NSObject 32 | 33 | //+ (NSString *)versionString; 34 | + (BOOL)isSupported; 35 | + (id)create; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNCore/include/CompressionFramingNative.h: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionFramingNative.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/30/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | typedef NS_ENUM(NSInteger, CompressionFramingNative) { 29 | CompressionFramingNativeDisabled, 30 | CompressionFramingNativeCompLZO, 31 | CompressionFramingNativeCompress, 32 | CompressionFramingNativeCompressV2 33 | }; 34 | -------------------------------------------------------------------------------- /Sources/TunnelKitAppExtension/LinkProducer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LinkProducer.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/23/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import TunnelKitCore 28 | 29 | /// Entity able to produce a `LinkInterface`. 30 | public protocol LinkProducer { 31 | 32 | /** 33 | Returns a `LinkInterface`. 34 | 35 | - Parameter xorMask: The XOR mask. 36 | **/ 37 | func link(xorMask: UInt8?) -> LinkInterface 38 | } 39 | -------------------------------------------------------------------------------- /Demo/Demo/DemoTunnel.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | BasicTunnelExtension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 4.0.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSExtension 26 | 27 | NSExtensionPointIdentifier 28 | com.apple.networkextension.packet-tunnel 29 | NSExtensionPrincipalClass 30 | $(PRODUCT_MODULE_NAME).PacketTunnelProvider 31 | 32 | NSHumanReadableCopyright 33 | Copyright (c) 2021 Davide De Rosa. All rights reserved. 34 | 35 | 36 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/CryptoCTR.h: -------------------------------------------------------------------------------- 1 | // 2 | // CryptoCTR.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/18/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | #import "Crypto.h" 29 | #import "DataPathCrypto.h" 30 | 31 | NS_ASSUME_NONNULL_BEGIN 32 | 33 | @interface CryptoCTR : NSObject 34 | 35 | - (instancetype)initWithCipherName:(nullable NSString *)cipherName digestName:(NSString *)digestName; 36 | 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/VPNStatus.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPNStatus.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/18/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Status of a `VPNProvider`. 29 | public enum VPNStatus: String { 30 | 31 | /// VPN is connected. 32 | case connected 33 | 34 | /// VPN is attempting a connection. 35 | case connecting 36 | 37 | /// VPN is disconnected. 38 | case disconnected 39 | 40 | /// VPN is completing a disconnection. 41 | case disconnecting 42 | } 43 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/DNSProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DNSProtocol.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 1/22/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// The protocol used in DNS servers. 29 | public enum DNSProtocol: String, Codable { 30 | 31 | /// The value to fall back to when unset. 32 | public static let fallback: DNSProtocol = .plain 33 | 34 | /// Standard plaintext DNS (port 53). 35 | case plain 36 | 37 | /// DNS over HTTPS. 38 | case https 39 | 40 | /// DNS over TLS (port 853). 41 | case tls 42 | } 43 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/PacketStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // PacketStream.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/25/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | @interface PacketStream : NSObject 31 | 32 | + (NSArray *)packetsFromStream:(NSData *)stream until:(NSInteger *)until xorMask:(uint8_t)xorMask; 33 | + (NSData *)streamFromPacket:(NSData *)packet xorMask:(uint8_t)xorMask; 34 | + (NSData *)streamFromPackets:(NSArray *)packets xorMask:(uint8_t)xorMask; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/CompressionProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionProvider.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/18/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | @protocol CompressionProvider 31 | 32 | - (nullable NSData *)compressedDataWithData:(NSData *)data error:(NSError **)error; 33 | - (nullable NSData *)decompressedDataWithData:(NSData *)data error:(NSError **)error; 34 | - (nullable NSData *)decompressedDataWithBytes:(const uint8_t *)bytes length:(NSInteger)length error:(NSError **)error; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/VPN.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPN.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 6/12/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Wrapper for shared access to VPN-related objects. 29 | public class VPN { 30 | 31 | /// The VPN became ready to use. 32 | public static let didPrepare = Notification.Name("VPNDidPrepare") 33 | 34 | /// The VPN did change status. 35 | public static let didChangeStatus = Notification.Name("VPNDidChangeStatus") 36 | 37 | /// The VPN profile did (re)install. 38 | public static let didReinstall = Notification.Name("VPNDidReinstall") 39 | } 40 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/Errors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Errors.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import CTunnelKitOpenVPNCore 28 | 29 | extension Error { 30 | public func isOpenVPNError() -> Bool { 31 | let te = self as NSError 32 | return te.domain == OpenVPNErrorDomain 33 | } 34 | 35 | public func openVPNErrorCode() -> OpenVPNErrorCode? { 36 | let te = self as NSError 37 | guard te.domain == OpenVPNErrorDomain else { 38 | return nil 39 | } 40 | return OpenVPNErrorCode(rawValue: te.code) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/LZOFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // LZOFactory.m 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/18/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import "LZOFactory.h" 27 | #import "ZeroingData.h" 28 | 29 | static NSString *const LZOClassName = @"StandardLZO"; 30 | 31 | static Class LZOClass() 32 | { 33 | NSBundle *bundle = [NSBundle bundleForClass:[ZeroingData class]]; 34 | return [bundle classNamed:LZOClassName]; 35 | } 36 | 37 | @implementation LZOFactory 38 | 39 | + (BOOL)isSupported 40 | { 41 | return LZOClass() != nil; 42 | } 43 | 44 | + (id)create 45 | { 46 | return [[LZOClass() alloc] init]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/SocketType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SockeType.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 11/10/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// A socket type between UDP (recommended) and TCP. 29 | public enum SocketType: String { 30 | 31 | /// UDP socket type. 32 | case udp = "UDP" 33 | 34 | /// TCP socket type. 35 | case tcp = "TCP" 36 | 37 | /// UDP socket type (IPv4). 38 | case udp4 = "UDP4" 39 | 40 | /// TCP socket type (IPv4). 41 | case tcp4 = "TCP4" 42 | 43 | /// UDP socket type (IPv6). 44 | case udp6 = "UDP6" 45 | 46 | /// TCP socket type (IPv6). 47 | case tcp6 = "TCP6" 48 | } 49 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/RoutingTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // RoutingTable.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/30/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | #import "RoutingTableEntry.h" 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | @interface RoutingTable : NSObject 33 | 34 | - (NSArray *)ipv4; 35 | - (NSArray *)ipv6; 36 | - (nullable RoutingTableEntry *)defaultGateway4; 37 | - (nullable RoutingTableEntry *)defaultGateway6; 38 | - (nullable RoutingTableEntry *)broadestRoute4MatchingDestination:(NSString *)destination; 39 | - (nullable RoutingTableEntry *)broadestRoute6MatchingDestination:(NSString *)destination; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /Demo/Host/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 4.0.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/Demo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 4.0.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/ConfigurationError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigurationError.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/3/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Error raised by the configuration parser, with details about the line that triggered it. 29 | public enum ConfigurationError: Error { 30 | 31 | /// Option syntax is incorrect. 32 | case malformed(option: String) 33 | 34 | /// A required option is missing. 35 | case missingConfiguration(option: String) 36 | 37 | /// An option is unsupported. 38 | case unsupportedConfiguration(option: String) 39 | 40 | /// Passphrase required to decrypt private keys. 41 | case encryptionPassphrase 42 | 43 | /// Encryption passphrase is incorrect or key is corrupt. 44 | case unableToDecrypt(error: Error) 45 | } 46 | -------------------------------------------------------------------------------- /Demo/Demo/macOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by Davide De Rosa on 10/15/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/keeshux 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Cocoa 27 | import SwiftyBeaver 28 | 29 | private let log = SwiftyBeaver.self 30 | 31 | @NSApplicationMain 32 | class AppDelegate: NSObject, NSApplicationDelegate { 33 | 34 | 35 | 36 | func applicationDidFinishLaunching(_ aNotification: Notification) { 37 | let logDestination = ConsoleDestination() 38 | logDestination.minLevel = .debug 39 | logDestination.format = "$DHH:mm:ss$d $L $N.$F:$l - $M" 40 | log.addDestination(logDestination) 41 | 42 | // Insert code here to initialize your application 43 | } 44 | 45 | func applicationWillTerminate(_ aNotification: Notification) { 46 | // Insert code here to tear down your application 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Demo/Host/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNProtocol/OpenVPN+PRNG.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OpenVPN+PRNG.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 11/8/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import TunnelKitCore 28 | import TunnelKitOpenVPNCore 29 | import CTunnelKitCore 30 | import CTunnelKitOpenVPNProtocol 31 | 32 | extension OpenVPN { 33 | 34 | /** 35 | Initializes the PRNG. Must be issued before using `OpenVPNSession`. 36 | 37 | - Parameter seedLength: The length in bytes of the pseudorandom seed that will feed the PRNG. 38 | */ 39 | public static func prepareRandomNumberGenerator(seedLength: Int) -> Bool { 40 | let seed: ZeroingData 41 | do { 42 | seed = try SecureRandom.safeData(length: seedLength) 43 | } catch { 44 | return false 45 | } 46 | return CryptoBox.preparePRNG(withSeed: seed.bytes, length: seed.count) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Demo/Host/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/NetworkExtensionVPNConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkExtensionVPNConfiguration.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/25/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import NetworkExtension 28 | 29 | /// A `VPNConfiguration` built on top of NetworkExtension entities. 30 | public struct NetworkExtensionVPNConfiguration: VPNConfiguration { 31 | 32 | public var title: String 33 | 34 | /// The `NEVPNProtocol` object embedding tunnel configuration. 35 | public let protocolConfiguration: NEVPNProtocol 36 | 37 | /// The on-demand rules to establish. 38 | public let onDemandRules: [NEOnDemandRule] 39 | 40 | public init(title: String, protocolConfiguration: NEVPNProtocol, onDemandRules: [NEOnDemandRule]) { 41 | self.title = title 42 | self.protocolConfiguration = protocolConfiguration 43 | self.onDemandRules = onDemandRules 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/RoutingTableEntry.h: -------------------------------------------------------------------------------- 1 | // 2 | // RoutingTableEntry.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/30/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | @interface RoutingTableEntry : NSObject 31 | 32 | - (instancetype)initWithIPv4Network:(NSString *)network gateway:(nullable NSString *)gateway networkInterface:(NSString *)networkInterface; 33 | - (instancetype)initWithIPv6Network:(NSString *)network gateway:(nullable NSString *)gateway networkInterface:(NSString *)networkInterface; 34 | 35 | - (BOOL)isIPv6; 36 | - (NSString *)network; 37 | - (NSInteger)prefix; 38 | - (nullable NSString *)networkMask; // nil if IPv6 39 | - (nullable NSString *)gateway; 40 | - (NSString *)networkInterface; 41 | 42 | - (BOOL)isDefault; 43 | - (BOOL)matchesDestination:(NSString *)destination; 44 | - (nullable NSArray *)partitioned; 45 | 46 | @end 47 | 48 | NS_ASSUME_NONNULL_END 49 | -------------------------------------------------------------------------------- /Demo/Host/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Sources/TunnelKitCore/Proxy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Proxy.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Encapsulates a proxy setting. 29 | public struct Proxy: Codable, RawRepresentable, CustomStringConvertible { 30 | 31 | /// The proxy address. 32 | public let address: String 33 | 34 | /// The proxy port. 35 | public let port: UInt16 36 | 37 | public init(_ address: String, _ port: UInt16) { 38 | self.address = address 39 | self.port = port 40 | } 41 | 42 | // MARK: RawRepresentable 43 | 44 | public var rawValue: String { 45 | return "\(address):\(port)" 46 | } 47 | 48 | public init?(rawValue: String) { 49 | let comps = rawValue.components(separatedBy: ":") 50 | guard comps.count == 2, let port = UInt16(comps[1]) else { 51 | return nil 52 | } 53 | self.init(comps[0], port) 54 | } 55 | 56 | // MARK: CustomStringConvertible 57 | 58 | public var description: String { 59 | return rawValue 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Sources/__TunnelKitUtils/NSRegularExpression+Shortcuts.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSRegularExpression+Shortcuts.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/9/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// :nodoc: 29 | extension NSRegularExpression { 30 | public convenience init(_ pattern: String) { 31 | try! self.init(pattern: pattern, options: []) 32 | } 33 | 34 | public func enumerateComponents(in string: String, using block: ([String]) -> Void) { 35 | enumerateMatches(in: string, options: [], range: NSMakeRange(0, string.count)) { (result, flags, stop) in 36 | guard let range = result?.range else { 37 | return 38 | } 39 | let match = (string as NSString).substring(with: range) 40 | let tokens = match.components(separatedBy: " ").filter { !$0.isEmpty } 41 | block(tokens) 42 | } 43 | } 44 | 45 | public func enumerateArguments(in string: String, using block: ([String]) -> Void) { 46 | enumerateComponents(in: string) { (tokens) in 47 | var args = tokens 48 | args.removeFirst() 49 | block(args) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Sources/TunnelKitManager/VPNProviderIPC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPNProviderIPC.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/25/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Common IPC functions supported by interactive VPN providers. 29 | public protocol VPNProviderIPC { 30 | 31 | /** 32 | Request a debug log from the VPN. 33 | 34 | - Parameter fallback: The block resolving to a fallback `String` if no debug log is available. 35 | - Parameter completionHandler: The completion handler with the debug log. 36 | */ 37 | func requestDebugLog(fallback: (() -> String)?, completionHandler: @escaping (String) -> Void) 38 | 39 | /** 40 | Requests the current received/sent bytes count from the VPN. 41 | 42 | - Parameter completionHandler: The completion handler with an optional received/sent bytes count. 43 | */ 44 | func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void) 45 | 46 | /** 47 | Requests the server configuration from the VPN. 48 | 49 | - Parameter completionHandler: The completion handler with an optional configuration object. 50 | */ 51 | func requestServerConfiguration(completionHandler: @escaping (Any?) -> Void) 52 | } 53 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/TLSWrap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLSWrap.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/11/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | extension OpenVPN { 29 | 30 | /// Holds parameters for TLS wrapping. 31 | public class TLSWrap: Codable { 32 | 33 | /// The wrapping strategy. 34 | public enum Strategy: String, Codable { 35 | 36 | /// Authenticates payload (--tls-auth). 37 | case auth 38 | 39 | /// Encrypts payload (--tls-crypt). 40 | case crypt 41 | } 42 | 43 | /// The wrapping strategy. 44 | public let strategy: Strategy 45 | 46 | /// The static encryption key. 47 | public let key: StaticKey 48 | 49 | public init(strategy: Strategy, key: StaticKey) { 50 | self.strategy = strategy 51 | self.key = key 52 | } 53 | 54 | public static func deserialized(_ data: Data) throws -> TLSWrap { 55 | return try JSONDecoder().decode(TLSWrap.self, from: data) 56 | } 57 | 58 | public func serialized() -> Data? { 59 | return try? JSONEncoder().encode(self) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/BidirectionalState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BidirectionalState.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/9/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// A generic structure holding a pair of inbound/outbound states. 29 | public class BidirectionalState { 30 | private let resetValue: T 31 | 32 | /// The inbound state. 33 | public var inbound: T 34 | 35 | /// The outbound state. 36 | public var outbound: T 37 | 38 | /** 39 | Returns current state as a pair. 40 | 41 | - Returns: Current state as a pair, inbound first. 42 | */ 43 | public var pair: (T, T) { 44 | return (inbound, outbound) 45 | } 46 | 47 | /** 48 | Inits state with a value that will later be reused by `reset()`. 49 | 50 | - Parameter value: The value to initialize with and reset to. 51 | */ 52 | public init(withResetValue value: T) { 53 | inbound = value 54 | outbound = value 55 | resetValue = value 56 | } 57 | 58 | /** 59 | Resets state to the value provided with `init(withResetValue:)`. 60 | */ 61 | public func reset() { 62 | inbound = resetValue 63 | outbound = resetValue 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/IPHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IPHeader.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/12/20. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | 25 | import Foundation 26 | 27 | /// Helper for handling IP headers. 28 | public struct IPHeader { 29 | private static let ipV4: UInt8 = 4 30 | 31 | private static let ipV6: UInt8 = 6 32 | 33 | private static let ipV4ProtocolNumber = AF_INET as NSNumber 34 | 35 | private static let ipV6ProtocolNumber = AF_INET6 as NSNumber 36 | 37 | private static let fallbackProtocolNumber = ipV4ProtocolNumber 38 | 39 | /** 40 | Returns the protocol number from the IP header of a data packet. 41 | 42 | - Parameter packet: The data to inspect. 43 | - Returns: A protocol number between `AF_INET` and `AF_INET6`. 44 | */ 45 | public static func protocolNumber(inPacket packet: Data) -> NSNumber { 46 | guard !packet.isEmpty else { 47 | return fallbackProtocolNumber 48 | } 49 | 50 | // 'packet' contains the decrypted incoming IP packet data 51 | 52 | // The first 4 bits identify the IP version 53 | let ipVersion = (packet[0] & 0xf0) >> 4 54 | assert(ipVersion == ipV4 || ipVersion == ipV6) 55 | return (ipVersion == ipV6) ? ipV6ProtocolNumber : ipV4ProtocolNumber 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/Resources/pia-2048.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD 3 | VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV 4 | BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu 5 | dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx 6 | IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB 7 | FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1 8 | MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex 9 | EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg 10 | QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE 11 | AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 12 | ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy 13 | bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD 14 | L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX 15 | lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp 16 | cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/ 17 | 8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB 18 | /5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC 19 | OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL 20 | y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO 21 | sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM 22 | b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G 23 | A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg 24 | SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz 25 | czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j 26 | b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn 27 | a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU 28 | ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3 29 | 7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC 30 | GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz 31 | 1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt 32 | YDQ8z9v+DMO6iwyIDRiU 33 | -----END CERTIFICATE----- 34 | 35 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/CompressionAlgorithm.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionAlgorithm.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import CTunnelKitOpenVPNCore 28 | 29 | extension OpenVPN { 30 | 31 | /// Defines the type of compression algorithm. 32 | public enum CompressionAlgorithm: Int, Codable, CustomStringConvertible { 33 | 34 | /// No compression. 35 | case disabled 36 | 37 | /// LZO compression. 38 | case LZO 39 | 40 | /// Any other compression algorithm (unsupported). 41 | case other 42 | 43 | public var native: CompressionAlgorithmNative { 44 | guard let val = CompressionAlgorithmNative(rawValue: rawValue) else { 45 | fatalError("Unhandled CompressionAlgorithm bridging") 46 | } 47 | return val 48 | } 49 | 50 | // MARK: CustomStringConvertible 51 | 52 | public var description: String { 53 | switch self { 54 | case .disabled: 55 | return "disabled" 56 | 57 | case .LZO: 58 | return "lzo" 59 | 60 | case .other: 61 | return "other" 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Tests/TunnelKitLZOTests/CompressionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionTests.swift 3 | // TunnelKitLZOTests 4 | // 5 | // Created by Davide De Rosa on 3/18/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import XCTest 27 | @testable import TunnelKitCore 28 | import CTunnelKitCore 29 | import TunnelKitLZO 30 | 31 | class CompressionTests: XCTestCase { 32 | 33 | override func setUp() { 34 | // Put setup code here. This method is called before the invocation of each test method in the class. 35 | // print("LZO version: \(LZO.versionString())") 36 | } 37 | 38 | override func tearDown() { 39 | // Put teardown code here. This method is called after the invocation of each test method in the class. 40 | } 41 | 42 | func testSymmetric() { 43 | XCTAssertTrue(LZOFactory.isSupported()); 44 | let lzo = LZOFactory.create() 45 | let src = Data([UInt8](repeating: 6, count: 100)) 46 | guard let dst = try? lzo.compressedData(with: src) else { 47 | XCTFail("Uncompressible data") 48 | return 49 | } 50 | guard let dstDecompressed = try? lzo.decompressedData(with: dst) else { 51 | XCTFail("Unable to decompress data") 52 | return 53 | } 54 | print("BEFORE: \(src)") 55 | print("AFTER : \(dstDecompressed)") 56 | XCTAssertEqual(src, dstDecompressed) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/MSS.h: -------------------------------------------------------------------------------- 1 | // 2 | // MSS.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 2/7/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | #import 39 | 40 | void MSSFix(uint8_t *data, NSInteger data_len); 41 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/Allocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // Allocation.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/5/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | void *allocate_safely(size_t size); 40 | 41 | size_t safe_crypto_capacity(size_t size, size_t overhead); 42 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNCore/Errors.m: -------------------------------------------------------------------------------- 1 | // 2 | // Errors.m 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 10/10/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import "Errors.h" 38 | 39 | NSString *const OpenVPNErrorDomain = @"TunnelKitOpenVPN"; 40 | NSString *const OpenVPNErrorKey = @"TunnelKitErrorKey"; 41 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/ReplayProtector.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReplayProtector.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 2/17/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | @interface ReplayProtector : NSObject 40 | 41 | - (BOOL)isReplayedPacketId:(uint32_t)packetId; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/PacketMacros.m: -------------------------------------------------------------------------------- 1 | // 2 | // PacketMacros.m 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 7/11/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import "PacketMacros.h" 38 | 39 | const uint8_t DataPacketPingData[] = { 0x2a, 0x18, 0x7b, 0xf3, 0x64, 0x1e, 0xb4, 0xcb, 0x07, 0xed, 0x2d, 0x0a, 0x98, 0x1f, 0xc7, 0x48 }; 40 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/CompressionFraming.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CompressionFraming.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/30/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import CTunnelKitOpenVPNCore 28 | 29 | extension OpenVPN { 30 | 31 | /// Defines the type of compression framing. 32 | public enum CompressionFraming: Int, Codable, CustomStringConvertible { 33 | 34 | /// No compression framing. 35 | case disabled 36 | 37 | /// Framing compatible with `comp-lzo` (deprecated in 2.4). 38 | case compLZO 39 | 40 | /// Framing compatible with 2.4 `compress`. 41 | case compress 42 | 43 | /// Framing compatible with 2.4 `compress` (version 2, e.g. stub-v2). 44 | case compressV2 45 | 46 | public var native: CompressionFramingNative { 47 | guard let val = CompressionFramingNative(rawValue: rawValue) else { 48 | fatalError("Unhandled CompressionFraming bridging") 49 | } 50 | return val 51 | } 52 | 53 | // MARK: CustomStringConvertible 54 | 55 | public var description: String { 56 | switch self { 57 | case .disabled: 58 | return "disabled" 59 | 60 | case .compress: 61 | return "compress" 62 | 63 | case .compressV2: 64 | return "compress" 65 | 66 | case .compLZO: 67 | return "comp-lzo" 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNManager/OpenVPNProvider+Interaction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OpenVPNProvider+Interaction.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/24/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | 29 | import Foundation 30 | 31 | extension OpenVPNProvider { 32 | 33 | /// The messages accepted by `OpenVPNProvider`. 34 | public class Message: Equatable { 35 | 36 | /// Requests a snapshot of the latest debug log. Returns the log data decoded from UTF-8. 37 | public static let requestLog = Message(0xff) 38 | 39 | /// Requests the current bytes count from data channel (if connected). 40 | /// 41 | /// Data is 16 bytes: low 8 = received, high 8 = sent. 42 | public static let dataCount = Message(0xfe) 43 | 44 | /// Requests the configuration pulled from the server (if connected and available). 45 | /// 46 | /// Data is JSON (Decodable). 47 | public static let serverConfiguration = Message(0xfd) 48 | 49 | /// The underlying raw message `Data` to forward to the tunnel via IPC. 50 | public let data: Data 51 | 52 | private init(_ byte: UInt8) { 53 | data = Data([byte]) 54 | } 55 | 56 | public init(_ data: Data) { 57 | self.data = data 58 | } 59 | 60 | // MARK: Equatable 61 | 62 | public static func ==(lhs: Message, rhs: Message) -> Bool { 63 | return (lhs.data == rhs.data) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/TunnelInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TunnelInterface.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/27/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | 39 | /// Represents a specific I/O interface meant to work at the tunnel layer (e.g. VPN). 40 | public protocol TunnelInterface: IOInterface { 41 | 42 | /// When `true`, interface survives sessions. 43 | var isPersistent: Bool { get } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNProtocol/ProtocolMacros.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProtocolMacros.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 2/8/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | import TunnelKitOpenVPNCore 39 | 40 | extension OpenVPN { 41 | class ProtocolMacros { 42 | 43 | // UInt32(0) + UInt8(KeyMethod = 2) 44 | static let tlsPrefix = Data(hex: "0000000002") 45 | 46 | static let numberOfKeys = UInt8(8) // 3-bit 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/TunnelKitLZO/lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # a very simple Makefile for miniLZO 3 | # 4 | # Copyright (C) 1996-2017 Markus F.X.J. Oberhumer 5 | # 6 | 7 | PROGRAM = testmini 8 | SOURCES = testmini.c minilzo.c 9 | 10 | default: 11 | @echo "" 12 | @echo "Welcome to miniLZO. Please choose one of the following 'make' targets:" 13 | @echo "" 14 | @echo " gcc: gcc" 15 | @echo " unix: hpux hpux9" 16 | @echo " win32: win32-bc win32-cygwin win32-dm win32-lccwin32" 17 | @echo " win32-intelc win32-mingw win32-vc win32-watcomc" 18 | @echo " dos32: dos32-djgpp2 dos32-wc" 19 | @echo "" 20 | 21 | 22 | # Make sure that minilzo.h, lzoconf.h and lzodefs.h are in the 23 | # current dircectory. Otherwise you may want to adjust CPPFLAGS. 24 | CPPFLAGS = -I. -I../include/lzo 25 | 26 | GCC_CFLAGS = -s -Wall -O2 -fomit-frame-pointer 27 | 28 | 29 | # 30 | # gcc (generic) 31 | # 32 | 33 | gcc: 34 | gcc $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM) $(SOURCES) 35 | 36 | cc: 37 | cc $(CPPFLAGS) -o $(PROGRAM) $(SOURCES) 38 | 39 | 40 | # 41 | # UNIX 42 | # 43 | 44 | hpux: 45 | cc -Ae $(CPPFLAGS) -o $(PROGRAM) $(SOURCES) 46 | 47 | hpux9: 48 | cc -Aa -D_HPUX_SOURCE $(CPPFLAGS) -o $(PROGRAM) $(SOURCES) 49 | 50 | 51 | # 52 | # Windows (32-bit) 53 | # 54 | 55 | win32-borlandc win32-bc: 56 | bcc32 -O2 -d -w -w-aus $(CPPFLAGS) $(SOURCES) 57 | 58 | win32-cygwin32 win32-cygwin: 59 | gcc -mcygwin $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES) 60 | 61 | win32-digitalmars win32-dm: 62 | dmc -mn -o -w- $(CPPFLAGS) $(SOURCES) 63 | 64 | win32-intelc win32-ic: 65 | icl -nologo -MT -W3 -O2 -GF $(CPPFLAGS) $(SOURCES) 66 | 67 | win32-lccwin32: 68 | @echo "NOTE: need lcc 2002-07-25 or newer, older versions have bugs" 69 | lc -A -unused -O $(CPPFLAGS) $(SOURCES) 70 | 71 | win32-mingw32 win32-mingw: 72 | gcc -mno-cygwin $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES) 73 | 74 | win32-visualc win32-vc: 75 | cl -nologo -MT -W3 -O2 -GF $(CPPFLAGS) $(SOURCES) 76 | 77 | win32-watcomc win32-wc: 78 | wcl386 -bt=nt -zq -mf -5r -zc -w5 -oneatx $(CPPFLAGS) $(SOURCES) 79 | 80 | 81 | # 82 | # DOS (32-bit) 83 | # 84 | 85 | dos32-djgpp2 dos32-dj2: 86 | gcc $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES) 87 | 88 | dos32-watcomc dos32-wc: 89 | wcl386 -zq -mf -bt=dos -l=dos4g -5r -ox -zc $(CPPFLAGS) $(SOURCES) 90 | 91 | 92 | # 93 | # other targets 94 | # 95 | 96 | clean: 97 | rm -f $(PROGRAM) $(PROGRAM).exe $(PROGRAM).map $(PROGRAM).tds 98 | rm -f *.err *.o *.obj 99 | 100 | .PHONY: default clean 101 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/CryptoMacros.h: -------------------------------------------------------------------------------- 1 | // 2 | // CryptoMacros.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 7/6/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | #define TUNNEL_CRYPTO_SUCCESS(ret) (ret > 0) 40 | #define TUNNEL_CRYPTO_TRACK_STATUS(ret) if (ret > 0) ret = 41 | #define TUNNEL_CRYPTO_RETURN_STATUS(ret)\ 42 | if (ret <= 0) {\ 43 | if (error) {\ 44 | *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoEncryption);\ 45 | }\ 46 | return NO;\ 47 | }\ 48 | return YES; 49 | -------------------------------------------------------------------------------- /Tests/TunnelKitCoreTests/TestUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestUtils.swift 3 | // TunnelKitCoreTests 4 | // 5 | // Created by Davide De Rosa on 7/7/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | @testable import TunnelKitCore 39 | 40 | public class TestUtils { 41 | public static func generateDataSuite(_ size: Int, _ count: Int) -> [Data] { 42 | var suite = [Data]() 43 | for _ in 0... 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import UIKit 38 | 39 | class ViewController: UIViewController { 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | // Do any additional setup after loading the view, typically from a nib. 44 | } 45 | 46 | override func didReceiveMemoryWarning() { 47 | super.didReceiveMemoryWarning() 48 | // Dispose of any resources that can be recreated. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/CryptoAEAD.h: -------------------------------------------------------------------------------- 1 | // 2 | // CryptoAEAD.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 7/6/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | #import "Crypto.h" 40 | #import "DataPathCrypto.h" 41 | 42 | NS_ASSUME_NONNULL_BEGIN 43 | 44 | @interface CryptoAEAD : NSObject 45 | 46 | - (instancetype)initWithCipherName:(NSString *)cipherName; 47 | 48 | @end 49 | 50 | @interface DataPathCryptoAEAD : NSObject 51 | 52 | @property (nonatomic, assign) uint32_t peerId; 53 | 54 | - (instancetype)initWithCrypto:(CryptoAEAD *)crypto; 55 | 56 | @end 57 | 58 | NS_ASSUME_NONNULL_END 59 | -------------------------------------------------------------------------------- /Sources/TunnelKitIKE/NativeProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NativeProvider.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/11/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import TunnelKitManager 28 | 29 | /// `VPNProvider` for native IPSec/IKEv2 configurations. 30 | public class NativeProvider: VPNProvider { 31 | private let provider: NetworkExtensionVPNProvider 32 | 33 | public init() { 34 | provider = NetworkExtensionVPNProvider(locator: NetworkExtensionNativeLocator()) 35 | } 36 | 37 | // MARK: VPNProvider 38 | 39 | public var isPrepared: Bool { 40 | return provider.isPrepared 41 | } 42 | 43 | public var isEnabled: Bool { 44 | return provider.isEnabled 45 | } 46 | 47 | public var status: VPNStatus { 48 | return provider.status 49 | } 50 | 51 | public func prepare(completionHandler: (() -> Void)?) { 52 | provider.prepare(completionHandler: completionHandler) 53 | } 54 | 55 | public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) { 56 | provider.install(configuration: configuration, completionHandler: completionHandler) 57 | } 58 | 59 | public func connect(completionHandler: ((Error?) -> Void)?) { 60 | provider.connect(completionHandler: completionHandler) 61 | } 62 | 63 | public func disconnect(completionHandler: ((Error?) -> Void)?) { 64 | provider.disconnect(completionHandler: completionHandler) 65 | } 66 | 67 | public func reconnect(configuration: VPNConfiguration, delay: Double? = nil, completionHandler: ((Error?) -> Void)?) { 68 | provider.reconnect(configuration: configuration, delay: delay, completionHandler: completionHandler) 69 | } 70 | 71 | public func uninstall(completionHandler: (() -> Void)?) { 72 | provider.uninstall(completionHandler: completionHandler) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Sources/TunnelKitAppExtension/Transport/NWUDPSessionState+Description.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NWUDPSessionState+Description.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/24/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | import NetworkExtension 39 | 40 | extension NWUDPSessionState: CustomStringConvertible { 41 | public var description: String { 42 | switch self { 43 | case .cancelled: return "cancelled" 44 | case .failed: return "failed" 45 | case .invalid: return "invalid" 46 | case .preparing: return "preparing" 47 | case .ready: return "ready" 48 | case .waiting: return "waiting" 49 | @unknown default: return "???" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/CryptoCBC.h: -------------------------------------------------------------------------------- 1 | // 2 | // CryptoCBC.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 7/6/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | #import "Crypto.h" 40 | #import "DataPathCrypto.h" 41 | 42 | NS_ASSUME_NONNULL_BEGIN 43 | 44 | @interface CryptoCBC : NSObject 45 | 46 | - (instancetype)initWithCipherName:(nullable NSString *)cipherName digestName:(NSString *)digestName; 47 | 48 | @end 49 | 50 | @interface DataPathCryptoCBC : NSObject 51 | 52 | @property (nonatomic, assign) uint32_t peerId; 53 | 54 | - (instancetype)initWithCrypto:(CryptoCBC *)crypto; 55 | 56 | @end 57 | 58 | NS_ASSUME_NONNULL_END 59 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/Allocation.m: -------------------------------------------------------------------------------- 1 | // 2 | // Allocation.m 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/5/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | #import 39 | 40 | #import "Allocation.h" 41 | 42 | #define MAX_BLOCK_SIZE 16 // AES only, block is 128-bit 43 | 44 | void *allocate_safely(size_t size) { 45 | void *memory = malloc(size); 46 | if (!memory) { 47 | NSLog(@"malloc() call failed"); 48 | abort(); 49 | return NULL; 50 | } 51 | return memory; 52 | } 53 | 54 | size_t safe_crypto_capacity(size_t size, size_t overhead) { 55 | 56 | // encryption, byte-alignment, overhead (e.g. IV, digest) 57 | return 2 * size + MAX_BLOCK_SIZE + overhead; 58 | } 59 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/LinkInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LinkInterface.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/27/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | 39 | /// Represents a specific I/O interface meant to work at the link layer (e.g. TCP/IP). 40 | public protocol LinkInterface: IOInterface { 41 | 42 | /// When `true`, packets delivery is guaranteed. 43 | var isReliable: Bool { get } 44 | 45 | /// The literal address of the remote host. 46 | var remoteAddress: String? { get } 47 | 48 | /// The number of packets that this interface is able to bufferize. 49 | var packetBufferSize: Int { get } 50 | 51 | /// A byte to xor all packet payloads with. 52 | var xorMask: UInt8 { get } 53 | } 54 | -------------------------------------------------------------------------------- /Sources/TunnelKitAppExtension/Transport/NWTCPConnectionState+Description.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NWTCPConnectionState+Description.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/16/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | import NetworkExtension 39 | 40 | extension NWTCPConnectionState: CustomStringConvertible { 41 | public var description: String { 42 | switch self { 43 | case .cancelled: return "cancelled" 44 | case .connected: return "connected" 45 | case .connecting: return "connecting" 46 | case .disconnected: return "disconnected" 47 | case .invalid: return "invalid" 48 | case .waiting: return "waiting" 49 | @unknown default: return "???" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/PacketTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PacketTests.swift 3 | // TunnelKitOpenVPNTests 4 | // 5 | // Created by Davide De Rosa on 9/9/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import XCTest 27 | @testable import TunnelKitCore 28 | import CTunnelKitOpenVPNProtocol 29 | 30 | class PacketTests: XCTestCase { 31 | 32 | override func setUp() { 33 | super.setUp() 34 | // Put setup code here. This method is called before the invocation of each test method in the class. 35 | } 36 | 37 | override func tearDown() { 38 | // Put teardown code here. This method is called after the invocation of each test method in the class. 39 | super.tearDown() 40 | } 41 | 42 | func testControlPacket() { 43 | let id: UInt32 = 0x1456 44 | let code: PacketCode = .controlV1 45 | let key: UInt8 = 3 46 | let sessionId = Data(hex: "1122334455667788") 47 | let payload = Data(hex: "932748238742397591704891") 48 | 49 | let serialized = ControlPacket(code: code, key: key, sessionId: sessionId, packetId: id, payload: payload).serialized() 50 | let expected = Data(hex: "2311223344556677880000001456932748238742397591704891") 51 | print("Serialized: \(serialized.toHex())") 52 | print("Expected : \(expected.toHex())") 53 | 54 | XCTAssertEqual(serialized, expected) 55 | } 56 | 57 | func testAckPacket() { 58 | let acks: [UInt32] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee] 59 | let key: UInt8 = 3 60 | let sessionId = Data(hex: "1122334455667788") 61 | let remoteSessionId = Data(hex: "a639328cbf03490e") 62 | 63 | let serialized = ControlPacket(key: key, sessionId: sessionId, ackIds: acks as [NSNumber], ackRemoteSessionId: remoteSessionId).serialized() 64 | let expected = Data(hex: "2b112233445566778805000000aa000000bb000000cc000000dd000000eea639328cbf03490e") 65 | print("Serialized: \(serialized.toHex())") 66 | print("Expected : \(expected.toHex())") 67 | 68 | XCTAssertEqual(serialized, expected) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/ControlPacket.h: -------------------------------------------------------------------------------- 1 | // 2 | // ControlPacket.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/14/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import 27 | 28 | #import "PacketMacros.h" 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | @protocol Encrypter; 33 | 34 | @interface ControlPacket : NSObject 35 | 36 | - (instancetype)initWithCode:(PacketCode)code 37 | key:(uint8_t)key 38 | sessionId:(NSData *)sessionId 39 | packetId:(uint32_t)packetId 40 | payload:(nullable NSData *)payload; 41 | 42 | - (instancetype)initWithKey:(uint8_t)key 43 | sessionId:(NSData *)sessionId 44 | ackIds:(NSArray *)ackIds 45 | ackRemoteSessionId:(NSData *)ackRemoteSessionId; 46 | 47 | @property (nonatomic, assign, readonly) PacketCode code; 48 | @property (nonatomic, readonly) BOOL isAck; 49 | @property (nonatomic, assign, readonly) uint8_t key; 50 | @property (nonatomic, strong, readonly) NSData *sessionId; 51 | @property (nonatomic, strong) NSArray *_Nullable ackIds; // uint32_t 52 | @property (nonatomic, strong) NSData *_Nullable ackRemoteSessionId; 53 | @property (nonatomic, assign, readonly) uint32_t packetId; 54 | @property (nonatomic, strong, readonly) NSData *_Nullable payload; 55 | @property (nonatomic, strong) NSDate *_Nullable sentDate; 56 | 57 | //- (NSInteger)capacity; 58 | //- (NSInteger)serializeTo:(uint8_t *)to; 59 | - (NSData *)serialized; 60 | 61 | @end 62 | 63 | @interface ControlPacket (Authentication) 64 | 65 | - (nullable NSData *)serializedWithAuthenticator:(id)auth replayId:(uint32_t)replayId timestamp:(uint32_t)timestamp error:(NSError * _Nullable __autoreleasing *)error; 66 | 67 | @end 68 | 69 | @interface ControlPacket (Encryption) 70 | 71 | - (nullable NSData *)serializedWithEncrypter:(id)encrypter replayId:(uint32_t)replayId timestamp:(uint32_t)timestamp adLength:(NSInteger)adLength error:(NSError * _Nullable __autoreleasing *)error; 72 | 73 | @end 74 | 75 | NS_ASSUME_NONNULL_END 76 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/IPv4Settings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IPv4Settings.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Encapsulates the IPv4 settings for the tunnel. 29 | public struct IPv4Settings: Codable, CustomStringConvertible { 30 | 31 | /// Represents an IPv4 route in the routing table. 32 | public struct Route: Codable, CustomStringConvertible { 33 | 34 | /// The destination host or subnet. 35 | public let destination: String 36 | 37 | /// The address mask. 38 | public let mask: String 39 | 40 | /// The address of the gateway (uses default gateway if not set). 41 | public let gateway: String 42 | 43 | public init(_ destination: String, _ mask: String?, _ gateway: String) { 44 | self.destination = destination 45 | self.mask = mask ?? "255.255.255.255" 46 | self.gateway = gateway 47 | } 48 | 49 | // MARK: CustomStringConvertible 50 | 51 | public var description: String { 52 | return "{\(destination.maskedDescription)/\(mask) \(gateway.maskedDescription)}" 53 | } 54 | } 55 | 56 | /// The address. 57 | public let address: String 58 | 59 | /// The address mask. 60 | public let addressMask: String 61 | 62 | /// The address of the default gateway. 63 | public let defaultGateway: String 64 | 65 | /// The additional routes. 66 | public let routes: [Route] 67 | 68 | public init(address: String, addressMask: String, defaultGateway: String, routes: [Route]) { 69 | self.address = address 70 | self.addressMask = addressMask 71 | self.defaultGateway = defaultGateway 72 | self.routes = routes 73 | } 74 | 75 | // MARK: CustomStringConvertible 76 | 77 | public var description: String { 78 | return "addr \(address.maskedDescription) netmask \(addressMask) gw \(defaultGateway.maskedDescription) routes \(routes.map { $0.maskedDescription })" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/IPv6Settings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IPv6Settings.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/19/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Encapsulates the IPv6 settings for the tunnel. 29 | public struct IPv6Settings: Codable, CustomStringConvertible { 30 | 31 | /// Represents an IPv6 route in the routing table. 32 | public struct Route: Codable, CustomStringConvertible { 33 | 34 | /// The destination host or subnet. 35 | public let destination: String 36 | 37 | /// The address prefix length. 38 | public let prefixLength: UInt8 39 | 40 | /// The address of the gateway (uses default gateway if not set). 41 | public let gateway: String 42 | 43 | public init(_ destination: String, _ prefixLength: UInt8?, _ gateway: String) { 44 | self.destination = destination 45 | self.prefixLength = prefixLength ?? 3 46 | self.gateway = gateway 47 | } 48 | 49 | // MARK: CustomStringConvertible 50 | 51 | public var description: String { 52 | return "{\(destination.maskedDescription)/\(prefixLength) \(gateway.maskedDescription)}" 53 | } 54 | } 55 | 56 | /// The address. 57 | public let address: String 58 | 59 | /// The address prefix length. 60 | public let addressPrefixLength: UInt8 61 | 62 | /// The address of the default gateway. 63 | public let defaultGateway: String 64 | 65 | /// The additional routes. 66 | public let routes: [Route] 67 | 68 | public init(address: String, addressPrefixLength: UInt8, defaultGateway: String, routes: [Route]) { 69 | self.address = address 70 | self.addressPrefixLength = addressPrefixLength 71 | self.defaultGateway = defaultGateway 72 | self.routes = routes 73 | } 74 | 75 | // MARK: CustomStringConvertible 76 | 77 | public var description: String { 78 | return "addr \(address.maskedDescription)/\(addressPrefixLength) gw \(defaultGateway.maskedDescription) routes \(routes.map { $0.maskedDescription })" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/EndpointProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EndpointProtocol.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 11/10/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Defines the communication protocol of an endpoint. 29 | public struct EndpointProtocol: RawRepresentable, Equatable, CustomStringConvertible { 30 | 31 | /// The socket type. 32 | public let socketType: SocketType 33 | 34 | /// The remote port. 35 | public let port: UInt16 36 | 37 | public init(_ socketType: SocketType, _ port: UInt16) { 38 | self.socketType = socketType 39 | self.port = port 40 | } 41 | 42 | // MARK: RawRepresentable 43 | 44 | public init?(rawValue: String) { 45 | let components = rawValue.components(separatedBy: ":") 46 | guard components.count == 2 else { 47 | return nil 48 | } 49 | guard let socketType = SocketType(rawValue: components[0]) else { 50 | return nil 51 | } 52 | guard let port = UInt16(components[1]) else { 53 | return nil 54 | } 55 | self.init(socketType, port) 56 | } 57 | 58 | public var rawValue: String { 59 | return "\(socketType.rawValue):\(port)" 60 | } 61 | 62 | // MARK: Equatable 63 | 64 | public static func ==(lhs: EndpointProtocol, rhs: EndpointProtocol) -> Bool { 65 | return (lhs.socketType == rhs.socketType) && (lhs.port == rhs.port) 66 | } 67 | 68 | // MARK: CustomStringConvertible 69 | 70 | public var description: String { 71 | return rawValue 72 | } 73 | } 74 | 75 | extension EndpointProtocol: Codable { 76 | public init(from decoder: Decoder) throws { 77 | let container = try decoder.singleValueContainer() 78 | let rawValue = try container.decode(String.self) 79 | let proto = EndpointProtocol(rawValue: rawValue) ?? EndpointProtocol(.udp, 1198) 80 | self.init(proto.socketType, proto.port) 81 | } 82 | 83 | public func encode(to encoder: Encoder) throws { 84 | var container = encoder.singleValueContainer() 85 | try container.encode(rawValue) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/VPNProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPNProvider.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 9/6/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Helps controlling a VPN without messing with underlying implementations. 29 | public protocol VPNProvider: AnyObject { 30 | 31 | /// `true` if the VPN is ready for use. 32 | var isPrepared: Bool { get } 33 | 34 | /// `true` if the associated VPN profile is enabled. 35 | var isEnabled: Bool { get } 36 | 37 | /// The status of the VPN. 38 | var status: VPNStatus { get } 39 | 40 | /** 41 | Prepares the VPN for use. 42 | 43 | - Postcondition: The VPN is ready to use and `isPrepared` becomes `true`. 44 | - Parameter completionHandler: The completion handler. 45 | - Seealso: `isPrepared` 46 | */ 47 | func prepare(completionHandler: (() -> Void)?) 48 | 49 | /** 50 | Installs the VPN profile. 51 | 52 | - Parameter configuration: The `VPNConfiguration` to install. 53 | - Parameter completionHandler: The completion handler with an optional error. 54 | */ 55 | func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) 56 | 57 | /** 58 | Connects to the VPN. 59 | 60 | - Parameter completionHandler: The completion handler with an optional error. 61 | */ 62 | func connect(completionHandler: ((Error?) -> Void)?) 63 | 64 | /** 65 | Disconnects from the VPN. 66 | 67 | - Parameter completionHandler: The completion handler with an optional error. 68 | */ 69 | func disconnect(completionHandler: ((Error?) -> Void)?) 70 | 71 | /** 72 | Reconnects to the VPN. 73 | 74 | - Parameter configuration: The `VPNConfiguration` to install. 75 | - Parameter delay: The reconnection delay in seconds. 76 | - Parameter completionHandler: The completion handler with an optional error. 77 | */ 78 | func reconnect(configuration: VPNConfiguration, delay: Double?, completionHandler: ((Error?) -> Void)?) 79 | 80 | /** 81 | Uninstalls the VPN profile. 82 | 83 | - Parameter completionHandler: The completion handler. 84 | */ 85 | func uninstall(completionHandler: (() -> Void)?) 86 | } 87 | -------------------------------------------------------------------------------- /Tests/TunnelKitCoreTests/RandomTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomTests.swift 3 | // TunnelKitCoreTests 4 | // 5 | // Created by Davide De Rosa on 7/7/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import XCTest 38 | @testable import TunnelKitCore 39 | 40 | class RandomTests: XCTestCase { 41 | 42 | override func setUp() { 43 | // Put setup code here. This method is called before the invocation of each test method in the class. 44 | } 45 | 46 | override func tearDown() { 47 | // Put teardown code here. This method is called after the invocation of each test method in the class. 48 | } 49 | 50 | func testRandom1() { 51 | print(try! SecureRandom.uint32()) 52 | print(try! SecureRandom.uint32()) 53 | print(try! SecureRandom.uint32()) 54 | print(try! SecureRandom.uint32()) 55 | print(try! SecureRandom.uint32()) 56 | } 57 | 58 | func testRandom2() { 59 | print("random UInt32: \(try! SecureRandom.uint32())") 60 | print("random bytes: \(try! SecureRandom.data(length: 12).toHex())") 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/ZeroingData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZeroingData.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/27/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | import CTunnelKitCore 39 | 40 | public func Z() -> ZeroingData { 41 | return ZeroingData() 42 | } 43 | 44 | public func Z(count: Int) -> ZeroingData { 45 | return ZeroingData(count: count) 46 | } 47 | 48 | public func Z(bytes: UnsafePointer, count: Int) -> ZeroingData { 49 | return ZeroingData(bytes: bytes, count: count) 50 | } 51 | 52 | public func Z(_ uint8: UInt8) -> ZeroingData { 53 | return ZeroingData(uInt8: uint8) 54 | } 55 | 56 | public func Z(_ uint16: UInt16) -> ZeroingData { 57 | return ZeroingData(uInt16: uint16) 58 | } 59 | 60 | public func Z(_ data: Data) -> ZeroingData { 61 | return ZeroingData(data: data) 62 | } 63 | 64 | //public func Z(_ data: Data, _ offset: Int, _ count: Int) -> ZeroingData { 65 | // return ZeroingData(data: data, offset: offset, count: count) 66 | //} 67 | 68 | public func Z(_ string: String, nullTerminated: Bool) -> ZeroingData { 69 | return ZeroingData(string: string, nullTerminated: nullTerminated) 70 | } 71 | -------------------------------------------------------------------------------- /Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemo-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitDemo-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/NetworkExtensionLocator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkExtensionLocator.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/25/21. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | import NetworkExtension 28 | 29 | /// Entity able to look up a `NEVPNManager`. 30 | public protocol NetworkExtensionLocator { 31 | 32 | /** 33 | Looks up the VPN manager. 34 | 35 | - Parameter completionHandler: The completion handler with a `NEVPNManager` or an error (if not found). 36 | */ 37 | func lookup(completionHandler: @escaping (NEVPNManager?, Error?) -> Void) 38 | } 39 | 40 | /// Locator for native VPN protocols. 41 | public class NetworkExtensionNativeLocator: NetworkExtensionLocator { 42 | 43 | public init() { 44 | } 45 | 46 | // MARK: NetworkExtensionLocator 47 | 48 | public func lookup(completionHandler: @escaping (NEVPNManager?, Error?) -> Void) { 49 | let manager = NEVPNManager.shared() 50 | manager.loadFromPreferences { (error) in 51 | guard error == nil else { 52 | completionHandler(nil, error) 53 | return 54 | } 55 | completionHandler(manager, nil) 56 | } 57 | } 58 | } 59 | 60 | /// Locator for tunnel VPN protocols. 61 | public class NetworkExtensionTunnelLocator: NetworkExtensionLocator { 62 | private let bundleIdentifier: String 63 | 64 | /** 65 | Initializes the locator with the bundle identifier of the tunnel provider. 66 | 67 | - Parameter bundleIdentifier: The bundle identifier of the tunnel provider. 68 | */ 69 | public init(bundleIdentifier: String) { 70 | self.bundleIdentifier = bundleIdentifier 71 | } 72 | 73 | // MARK: NetworkExtensionLocator 74 | 75 | public func lookup(completionHandler: @escaping (NEVPNManager?, Error?) -> Void) { 76 | NETunnelProviderManager.loadAllFromPreferences { (managers, error) in 77 | guard error == nil else { 78 | completionHandler(nil, error) 79 | return 80 | } 81 | let manager = managers?.first { 82 | guard let ptm = $0.protocolConfiguration as? NETunnelProviderProtocol else { 83 | return false 84 | } 85 | return (ptm.providerBundleIdentifier == self.bundleIdentifier) 86 | } 87 | completionHandler(manager ?? NETunnelProviderManager(), nil) 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/StaticKeyTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaticKeyTests.swift 3 | // TunnelKitOpenVPNTests 4 | // 5 | // Created by Davide De Rosa on 9/11/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import XCTest 27 | @testable import TunnelKitCore 28 | import TunnelKitOpenVPNCore 29 | 30 | class StaticKeyTests: XCTestCase { 31 | private let content = """ 32 | # 33 | # 2048 bit OpenVPN static key 34 | # 35 | -----BEGIN OpenVPN Static key V1----- 36 | 48d9999bd71095b10649c7cb471c1051 37 | b1afdece597cea06909b99303a18c674 38 | 01597b12c04a787e98cdb619ee960d90 39 | a0165529dc650f3a5c6fbe77c91c137d 40 | cf55d863fcbe314df5f0b45dbe974d9b 41 | de33ef5b4803c3985531c6c23ca6906d 42 | 6cd028efc8585d1b9e71003566bd7891 43 | b9cc9212bcba510109922eed87f5c8e6 44 | 6d8e59cbd82575261f02777372b2cd4c 45 | a5214c4a6513ff26dd568f574fd40d6c 46 | d450fc788160ff68434ce2bf6afb00e7 47 | 10a3198538f14c4d45d84ab42637872e 48 | 778a6b35a124e700920879f1d003ba93 49 | dccdb953cdf32bea03f365760b0ed800 50 | 2098d4ce20d045b45a83a8432cc73767 51 | 7aed27125592a7148d25c87fdbe0a3f6 52 | -----END OpenVPN Static key V1----- 53 | """ 54 | 55 | override func setUp() { 56 | super.setUp() 57 | // Put setup code here. This method is called before the invocation of each test method in the class. 58 | } 59 | 60 | override func tearDown() { 61 | // Put teardown code here. This method is called after the invocation of each test method in the class. 62 | super.tearDown() 63 | } 64 | 65 | func testFileBidirectional() { 66 | let expected = Data(hex: "cf55d863fcbe314df5f0b45dbe974d9bde33ef5b4803c3985531c6c23ca6906d6cd028efc8585d1b9e71003566bd7891b9cc9212bcba510109922eed87f5c8e6") 67 | let key = OpenVPN.StaticKey(file: content, direction: nil) 68 | XCTAssertNotNil(key) 69 | 70 | XCTAssertEqual(key?.hmacSendKey.toData(), expected) 71 | XCTAssertEqual(key?.hmacReceiveKey.toData(), expected) 72 | } 73 | 74 | func testFileDirection() { 75 | let send = Data(hex: "778a6b35a124e700920879f1d003ba93dccdb953cdf32bea03f365760b0ed8002098d4ce20d045b45a83a8432cc737677aed27125592a7148d25c87fdbe0a3f6") 76 | let receive = Data(hex: "cf55d863fcbe314df5f0b45dbe974d9bde33ef5b4803c3985531c6c23ca6906d6cd028efc8585d1b9e71003566bd7891b9cc9212bcba510109922eed87f5c8e6") 77 | let key = OpenVPN.StaticKey(file: content, direction: .client) 78 | XCTAssertNotNil(key) 79 | 80 | XCTAssertEqual(key?.hmacSendKey.toData(), send) 81 | XCTAssertEqual(key?.hmacReceiveKey.toData(), receive) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/include/DataPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataPath.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 3/2/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | @import CTunnelKitOpenVPNCore; 40 | 41 | NS_ASSUME_NONNULL_BEGIN 42 | 43 | @protocol DataPathEncrypter; 44 | @protocol DataPathDecrypter; 45 | 46 | // send/receive should be mutually thread-safe 47 | 48 | @interface DataPath : NSObject 49 | 50 | @property (nonatomic, assign) uint32_t maxPacketId; 51 | 52 | - (instancetype)initWithEncrypter:(id)encrypter 53 | decrypter:(id)decrypter 54 | peerId:(uint32_t)peerId // 24-bit, discard most significant byte 55 | compressionFraming:(CompressionFramingNative)compressionFraming 56 | compressionAlgorithm:(CompressionAlgorithmNative)compressionAlgorithm 57 | maxPackets:(NSInteger)maxPackets 58 | usesReplayProtection:(BOOL)usesReplayProtection; 59 | 60 | - (nullable NSArray *)encryptPackets:(NSArray *)packets key:(uint8_t)key error:(NSError **)error; 61 | - (nullable NSArray *)decryptPackets:(NSArray *)packets keepAlive:(nullable bool *)keepAlive error:(NSError **)error; 62 | 63 | @end 64 | 65 | NS_ASSUME_NONNULL_END 66 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/Resources/tunnelbear.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | 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 51 | 1LXZrtjAB4U+/F7um6YyAavpHYq9hg== 52 | -----END PRIVATE KEY----- 53 | -------------------------------------------------------------------------------- /Demo/Demo/iOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by Davide De Rosa on 2/11/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/keeshux 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import UIKit 27 | import NetworkExtension 28 | import SwiftyBeaver 29 | 30 | private let log = SwiftyBeaver.self 31 | 32 | @UIApplicationMain 33 | class AppDelegate: UIResponder, UIApplicationDelegate { 34 | 35 | var window: UIWindow? 36 | 37 | 38 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 39 | let logDestination = ConsoleDestination() 40 | logDestination.minLevel = .debug 41 | logDestination.format = "$DHH:mm:ss$d $L $N.$F:$l - $M" 42 | log.addDestination(logDestination) 43 | 44 | // Override point for customization after application launch. 45 | return true 46 | } 47 | 48 | func applicationWillResignActive(_ application: UIApplication) { 49 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 50 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 51 | } 52 | 53 | func applicationDidEnterBackground(_ application: UIApplication) { 54 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 55 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 56 | } 57 | 58 | func applicationWillEnterForeground(_ application: UIApplication) { 59 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 60 | } 61 | 62 | func applicationDidBecomeActive(_ application: UIApplication) { 63 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 64 | } 65 | 66 | func applicationWillTerminate(_ application: UIApplication) { 67 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Sources/TunnelKitManager/MockVPNProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockVPNProvider.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 6/15/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | import Foundation 27 | 28 | /// Simulates a VPN provider. 29 | public class MockVPNProvider: VPNProvider, VPNProviderIPC { 30 | 31 | public init() { 32 | } 33 | 34 | // MARK: VPNProvider 35 | 36 | public let isPrepared: Bool = true 37 | 38 | public private(set) var isEnabled: Bool = false 39 | 40 | public private(set) var status: VPNStatus = .disconnected 41 | 42 | public func prepare(completionHandler: (() -> Void)?) { 43 | NotificationCenter.default.post(name: VPN.didPrepare, object: nil) 44 | completionHandler?() 45 | } 46 | 47 | public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) { 48 | isEnabled = true 49 | completionHandler?(nil) 50 | } 51 | 52 | public func connect(completionHandler: ((Error?) -> Void)?) { 53 | isEnabled = true 54 | status = .connected 55 | NotificationCenter.default.post(name: VPN.didChangeStatus, object: self) 56 | completionHandler?(nil) 57 | } 58 | 59 | public func disconnect(completionHandler: ((Error?) -> Void)?) { 60 | isEnabled = false 61 | status = .disconnected 62 | NotificationCenter.default.post(name: VPN.didChangeStatus, object: self) 63 | completionHandler?(nil) 64 | } 65 | 66 | public func reconnect(configuration: VPNConfiguration, delay: Double?, completionHandler: ((Error?) -> Void)?) { 67 | isEnabled = true 68 | status = .connected 69 | NotificationCenter.default.post(name: VPN.didChangeStatus, object: self) 70 | completionHandler?(nil) 71 | } 72 | 73 | public func uninstall(completionHandler: (() -> Void)?) { 74 | isEnabled = false 75 | status = .disconnected 76 | NotificationCenter.default.post(name: VPN.didChangeStatus, object: self) 77 | completionHandler?() 78 | } 79 | 80 | // MARK: VPNProviderIPC 81 | 82 | public func requestDebugLog(fallback: (() -> String)?, completionHandler: @escaping (String) -> Void) { 83 | let log = [String](repeating: "lorem ipsum", count: 1000).joined(separator: " ") 84 | completionHandler(log) 85 | } 86 | 87 | public func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void) { 88 | completionHandler((0, 0)) 89 | } 90 | 91 | public func requestServerConfiguration(completionHandler: @escaping (Any?) -> Void) { 92 | completionHandler(nil) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Sources/TunnelKitCore/IOInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IOInterface.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/27/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | 39 | /// Represents an I/O interface able to read and write data. 40 | public protocol IOInterface: AnyObject { 41 | 42 | /** 43 | Sets the handler for incoming packets. This only needs to be set once. 44 | 45 | - Parameter queue: The queue where to invoke the handler on. 46 | - Parameter handler: The handler invoked whenever an array of `Data` packets is received, with an optional `Error` in case a network failure occurs. 47 | */ 48 | func setReadHandler(queue: DispatchQueue, _ handler: @escaping ([Data]?, Error?) -> Void) 49 | 50 | /** 51 | Writes a packet to the interface. 52 | 53 | - Parameter packet: The `Data` packet to write. 54 | - Parameter completionHandler: Invoked on write completion, with an optional `Error` in case a network failure occurs. 55 | */ 56 | func writePacket(_ packet: Data, completionHandler: ((Error?) -> Void)?) 57 | 58 | /** 59 | Writes some packets to the interface. 60 | 61 | - Parameter packets: The array of `Data` packets to write. 62 | - Parameter completionHandler: Invoked on write completion, with an optional `Error` in case a network failure occurs. 63 | */ 64 | func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) 65 | } 66 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/Resources/tunnelbear.enc.1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: AES-128-CBC,1C7216F89C74E56260FE71A9C1BAB35E 4 | 5 | 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 54 | -----END RSA PRIVATE KEY----- 55 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/Resources/pia-hungary.ovpn: -------------------------------------------------------------------------------- 1 | client 2 | dev tun 3 | remote hungary.privateinternetaccess.com 1198 udp 4 | remote hungary.privateinternetaccess.com 502 tcp 5 | resolv-retry infinite 6 | nobind 7 | persist-key 8 | persist-tun 9 | setenv CLIENT_CERT 0 10 | 11 | 12 | -----BEGIN CERTIFICATE----- 13 | MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD 14 | VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV 15 | BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu 16 | dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx 17 | IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB 18 | FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1 19 | MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex 20 | EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg 21 | QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE 22 | AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 23 | ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy 24 | bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD 25 | L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX 26 | lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp 27 | cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/ 28 | 8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB 29 | /5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC 30 | OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL 31 | y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO 32 | sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM 33 | b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G 34 | A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg 35 | SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz 36 | czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j 37 | b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn 38 | a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU 39 | ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3 40 | 7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC 41 | GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz 42 | 1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt 43 | YDQ8z9v+DMO6iwyIDRiU 44 | -----END CERTIFICATE----- 45 | 46 | 47 | cipher aes-128-cbc 48 | auth sha1 49 | tls-client 50 | remote-cert-tls server 51 | auth-user-pass 52 | comp-lzo no 53 | verb 1 54 | reneg-sec 0 55 | 56 | 57 | -----BEGIN X509 CRL----- 58 | MIICWDCCAUAwDQYJKoZIhvcNAQENBQAwgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI 59 | EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl 60 | cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw 61 | HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 62 | ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl 63 | aW50ZXJuZXRhY2Nlc3MuY29tFw0xNjA3MDgxOTAwNDZaFw0zNjA3MDMxOTAwNDZa 64 | MCYwEQIBARcMMTYwNzA4MTkwMDQ2MBECAQYXDDE2MDcwODE5MDA0NjANBgkqhkiG 65 | 9w0BAQ0FAAOCAQEAQZo9X97ci8EcPYu/uK2HB152OZbeZCINmYyluLDOdcSvg6B5 66 | jI+ffKN3laDvczsG6CxmY3jNyc79XVpEYUnq4rT3FfveW1+Ralf+Vf38HdpwB8EW 67 | B4hZlQ205+21CALLvZvR8HcPxC9KEnev1mU46wkTiov0EKc+EdRxkj5yMgv0V2Re 68 | ze7AP+NQ9ykvDScH4eYCsmufNpIjBLhpLE2cuZZXBLcPhuRzVoU3l7A9lvzG9mjA 69 | 5YijHJGHNjlWFqyrn1CfYS6koa4TGEPngBoAziWRbDGdhEgJABHrpoaFYaL61zqy 70 | MR6jC0K2ps9qyZAN74LEBedEfK7tBOzWMwr58A== 71 | -----END X509 CRL----- 72 | 73 | -------------------------------------------------------------------------------- /Sources/__TunnelKitUtils/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 5/23/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | 39 | public extension DispatchQueue { 40 | func schedule(after: DispatchTimeInterval, block: @escaping () -> Void) { 41 | asyncAfter(deadline: .now() + after, execute: block) 42 | } 43 | } 44 | 45 | public func fromDictionary(_ type: T.Type, _ dictionary: [String: Any]) throws -> T { 46 | let data = try JSONSerialization.data(withJSONObject: dictionary, options: .fragmentsAllowed) 47 | return try JSONDecoder().decode(T.self, from: data) 48 | } 49 | 50 | public extension Encodable { 51 | func asDictionary() throws -> [String: Any] { 52 | let data = try JSONEncoder().encode(self) 53 | guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed) as? [String: Any] else { 54 | fatalError("JSONSerialization failed to encode") 55 | } 56 | return dictionary 57 | } 58 | } 59 | 60 | extension TimeInterval { 61 | public var asTimeString: String { 62 | var ticks = Int(self) 63 | let hours = ticks / 3600 64 | ticks %= 3600 65 | let minutes = ticks / 60 66 | let seconds = ticks % 60 67 | 68 | return [(hours, "h"), (minutes, "m"), (seconds, "s")] 69 | .filter { $0.0 > 0 } 70 | .map { "\($0.0)\($0.1)" } 71 | .joined() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNProtocol/PushReply.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PushReply.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 7/25/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | import TunnelKitOpenVPNCore 39 | 40 | extension OpenVPN { 41 | struct PushReply: CustomStringConvertible { 42 | private static let prefix = "PUSH_REPLY," 43 | 44 | private let original: String 45 | 46 | let options: Configuration 47 | 48 | init?(message: String) throws { 49 | guard message.hasPrefix(PushReply.prefix) else { 50 | return nil 51 | } 52 | guard let prefixIndex = message.range(of: PushReply.prefix)?.lowerBound else { 53 | return nil 54 | } 55 | original = String(message[prefixIndex...]) 56 | 57 | let lines = original.components(separatedBy: ",") 58 | options = try ConfigurationParser.parsed(fromLines: lines).configuration 59 | } 60 | 61 | // MARK: CustomStringConvertible 62 | 63 | var description: String { 64 | let stripped = NSMutableString(string: original) 65 | ConfigurationParser.Regex.authToken.replaceMatches( 66 | in: stripped, 67 | options: [], 68 | range: NSMakeRange(0, stripped.length), 69 | withTemplate: "auth-token" 70 | ) 71 | return stripped as String 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Tests/TunnelKitOpenVPNTests/Resources/tunnelbear.enc.8.key: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | 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 53 | kNk= 54 | -----END ENCRYPTED PRIVATE KEY----- 55 | -------------------------------------------------------------------------------- /Demo/TunnelKit.xcodeproj/xcshareddata/xcschemes/TunnelKitHost.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Sources/TunnelKitLZO/lib/minilzo.h: -------------------------------------------------------------------------------- 1 | /* minilzo.h -- mini subset of the LZO real-time data compression library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | The LZO library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | The LZO library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with the LZO library; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | http://www.oberhumer.com/opensource/lzo/ 26 | */ 27 | 28 | /* 29 | * NOTE: 30 | * the full LZO package can be found at 31 | * http://www.oberhumer.com/opensource/lzo/ 32 | */ 33 | 34 | 35 | #ifndef __MINILZO_H_INCLUDED 36 | #define __MINILZO_H_INCLUDED 1 37 | 38 | #define MINILZO_VERSION 0x20a0 /* 2.10 */ 39 | 40 | #if defined(__LZOCONF_H_INCLUDED) 41 | # error "you cannot use both LZO and miniLZO" 42 | #endif 43 | 44 | /* internal Autoconf configuration file - only used when building miniLZO */ 45 | #ifdef MINILZO_HAVE_CONFIG_H 46 | # include 47 | #endif 48 | #include 49 | #include 50 | 51 | #ifndef __LZODEFS_H_INCLUDED 52 | #include "lzodefs.h" 53 | #endif 54 | #undef LZO_HAVE_CONFIG_H 55 | #include "lzoconf.h" 56 | 57 | #if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) 58 | # error "version mismatch in header files" 59 | #endif 60 | 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | 67 | /*********************************************************************** 68 | // 69 | ************************************************************************/ 70 | 71 | /* Memory required for the wrkmem parameter. 72 | * When the required size is 0, you can also pass a NULL pointer. 73 | */ 74 | 75 | #define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS 76 | #define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) 77 | #define LZO1X_MEM_DECOMPRESS (0) 78 | 79 | 80 | /* compression */ 81 | LZO_EXTERN(int) 82 | lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, 83 | lzo_bytep dst, lzo_uintp dst_len, 84 | lzo_voidp wrkmem ); 85 | 86 | /* decompression */ 87 | LZO_EXTERN(int) 88 | lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, 89 | lzo_bytep dst, lzo_uintp dst_len, 90 | lzo_voidp wrkmem /* NOT USED */ ); 91 | 92 | /* safe decompression with overrun testing */ 93 | LZO_EXTERN(int) 94 | lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, 95 | lzo_bytep dst, lzo_uintp dst_len, 96 | lzo_voidp wrkmem /* NOT USED */ ); 97 | 98 | 99 | #ifdef __cplusplus 100 | } /* extern "C" */ 101 | #endif 102 | 103 | #endif /* already included */ 104 | 105 | 106 | /* vim:set ts=4 sw=4 et: */ 107 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNCore/include/Errors.h: -------------------------------------------------------------------------------- 1 | // 2 | // Errors.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 10/10/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | extern NSString *const OpenVPNErrorDomain; 40 | extern NSString *const OpenVPNErrorKey; 41 | 42 | typedef NS_ENUM(NSInteger, OpenVPNErrorCode) { 43 | OpenVPNErrorCodeCryptoRandomGenerator = 101, 44 | OpenVPNErrorCodeCryptoHMAC = 102, 45 | OpenVPNErrorCodeCryptoEncryption = 103, 46 | OpenVPNErrorCodeCryptoAlgorithm = 104, 47 | OpenVPNErrorCodeTLSCARead = 201, 48 | OpenVPNErrorCodeTLSCAUse = 202, 49 | OpenVPNErrorCodeTLSCAPeerVerification = 203, 50 | OpenVPNErrorCodeTLSClientCertificateRead = 204, 51 | OpenVPNErrorCodeTLSClientCertificateUse = 205, 52 | OpenVPNErrorCodeTLSClientKeyRead = 206, 53 | OpenVPNErrorCodeTLSClientKeyUse = 207, 54 | OpenVPNErrorCodeTLSHandshake = 210, 55 | OpenVPNErrorCodeTLSServerCertificate = 211, 56 | OpenVPNErrorCodeTLSServerEKU = 212, 57 | OpenVPNErrorCodeTLSServerHost = 213, 58 | OpenVPNErrorCodeDataPathOverflow = 301, 59 | OpenVPNErrorCodeDataPathPeerIdMismatch = 302, 60 | OpenVPNErrorCodeDataPathCompression = 303 61 | }; 62 | 63 | static inline NSError *OpenVPNErrorWithCode(OpenVPNErrorCode code) { 64 | return [NSError errorWithDomain:OpenVPNErrorDomain code:code userInfo:nil]; 65 | } 66 | -------------------------------------------------------------------------------- /Sources/CTunnelKitCore/include/ZeroingData.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZeroingData.h 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/28/17. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | #import 38 | 39 | NS_ASSUME_NONNULL_BEGIN 40 | 41 | @interface ZeroingData : NSObject 42 | 43 | @property (nonatomic, readonly) const uint8_t *bytes; 44 | @property (nonatomic, readonly) uint8_t *mutableBytes; 45 | @property (nonatomic, readonly) NSInteger count; 46 | 47 | - (instancetype)initWithCount:(NSInteger)count; 48 | - (instancetype)initWithBytes:(nullable const uint8_t *)bytes count:(NSInteger)count; 49 | - (instancetype)initWithUInt8:(uint8_t)uint8; 50 | - (instancetype)initWithUInt16:(uint16_t)uint16; 51 | 52 | - (instancetype)initWithData:(NSData *)data; 53 | - (instancetype)initWithData:(NSData *)data offset:(NSInteger)offset count:(NSInteger)count; 54 | - (instancetype)initWithString:(NSString *)string nullTerminated:(BOOL)nullTerminated; 55 | 56 | - (void)appendData:(ZeroingData *)other; 57 | //- (void)truncateToSize:(NSInteger)size; 58 | - (void)removeUntilOffset:(NSInteger)until; 59 | - (void)zero; 60 | 61 | - (ZeroingData *)appendingData:(ZeroingData *)other; 62 | - (ZeroingData *)withOffset:(NSInteger)offset count:(NSInteger)count; 63 | - (uint16_t)UInt16ValueFromOffset:(NSInteger)from; 64 | - (uint16_t)networkUInt16ValueFromOffset:(NSInteger)from; 65 | - (nullable NSString *)nullTerminatedStringFromOffset:(NSInteger)from; 66 | 67 | - (BOOL)isEqualToData:(NSData *)data; 68 | - (NSData *)toData; // XXX: unsafe 69 | - (NSString *)toHex; 70 | 71 | @end 72 | 73 | NS_ASSUME_NONNULL_END 74 | -------------------------------------------------------------------------------- /Sources/TunnelKitOpenVPNCore/OpenVPNError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OpenVPNError.swift 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 8/23/18. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | // This file incorporates work covered by the following copyright and 26 | // permission notice: 27 | // 28 | // Copyright (c) 2018-Present Private Internet Access 29 | // 30 | // 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: 31 | // 32 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 33 | // 34 | // 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. 35 | // 36 | 37 | import Foundation 38 | 39 | /// The possible errors raised/thrown during `OpenVPNSession` operation. 40 | public enum OpenVPNError: String, Error { 41 | 42 | /// The negotiation timed out. 43 | case negotiationTimeout 44 | 45 | /// The VPN session id is missing. 46 | case missingSessionId 47 | 48 | /// The VPN session id doesn't match. 49 | case sessionMismatch 50 | 51 | /// The connection key is wrong or wasn't expected. 52 | case badKey 53 | 54 | /// The control packet has an incorrect prefix payload. 55 | case wrongControlDataPrefix 56 | 57 | /// The provided credentials failed authentication. 58 | case badCredentials 59 | 60 | /// The PUSH_REPLY is multipart. 61 | case continuationPushReply 62 | 63 | /// The reply to PUSH_REQUEST is malformed. 64 | case malformedPushReply 65 | 66 | /// A write operation failed at the link layer (e.g. network unreachable). 67 | case failedLinkWrite 68 | 69 | /// The server couldn't ping back before timeout. 70 | case pingTimeout 71 | 72 | /// The session reached a stale state and can't be recovered. 73 | case staleSession 74 | 75 | /// Server uses compression. 76 | case serverCompression 77 | 78 | /// Missing routing information. 79 | case noRouting 80 | 81 | /// Remote server shut down (--explicit-exit-notify). 82 | case serverShutdown 83 | } 84 | -------------------------------------------------------------------------------- /Sources/CTunnelKitOpenVPNProtocol/PacketStream.m: -------------------------------------------------------------------------------- 1 | // 2 | // PacketStream.m 3 | // TunnelKit 4 | // 5 | // Created by Davide De Rosa on 4/25/19. 6 | // Copyright (c) 2021 Davide De Rosa. All rights reserved. 7 | // 8 | // https://github.com/passepartoutvpn 9 | // 10 | // This file is part of TunnelKit. 11 | // 12 | // TunnelKit is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // TunnelKit is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with TunnelKit. If not, see . 24 | // 25 | 26 | #import "PacketStream.h" 27 | 28 | static const NSInteger PacketStreamHeaderLength = sizeof(uint16_t); 29 | 30 | @implementation PacketStream 31 | 32 | + (void)memcpyXor:(uint8_t *)dst src:(NSData *)src xorMask:(uint8_t)xorMask 33 | { 34 | if (xorMask != 0) { 35 | for (int i = 0; i < src.length; ++i) { 36 | dst[i] = ((uint8_t *)(src.bytes))[i] ^ xorMask; 37 | } 38 | return; 39 | } 40 | memcpy(dst, src.bytes, src.length); 41 | } 42 | 43 | + (NSArray *)packetsFromStream:(NSData *)stream until:(NSInteger *)until xorMask:(uint8_t)xorMask 44 | { 45 | NSInteger ni = 0; 46 | NSMutableArray *parsed = [[NSMutableArray alloc] init]; 47 | 48 | while (ni + PacketStreamHeaderLength <= stream.length) { 49 | const NSInteger packlen = CFSwapInt16BigToHost(*(uint16_t *)(stream.bytes + ni)); 50 | const NSInteger start = ni + PacketStreamHeaderLength; 51 | const NSInteger end = start + packlen; 52 | if (end > stream.length) { 53 | break; 54 | } 55 | NSData *packet = [stream subdataWithRange:NSMakeRange(start, packlen)]; 56 | uint8_t* packetBytes = (uint8_t*) packet.bytes; 57 | if (xorMask != 0) { 58 | for (int i = 0; i < packet.length; i++) { 59 | packetBytes[i] ^= xorMask; 60 | } 61 | } 62 | [parsed addObject:packet]; 63 | ni = end; 64 | } 65 | if (until) { 66 | *until = ni; 67 | } 68 | return parsed; 69 | } 70 | 71 | + (NSData *)streamFromPacket:(NSData *)packet xorMask:(uint8_t)xorMask 72 | { 73 | NSMutableData *raw = [[NSMutableData alloc] initWithLength:(PacketStreamHeaderLength + packet.length)]; 74 | 75 | uint8_t *ptr = raw.mutableBytes; 76 | *(uint16_t *)ptr = CFSwapInt16HostToBig(packet.length); 77 | ptr += PacketStreamHeaderLength; 78 | [PacketStream memcpyXor:ptr src:packet xorMask:xorMask]; 79 | 80 | return raw; 81 | } 82 | 83 | + (NSData *)streamFromPackets:(NSArray *)packets xorMask:(uint8_t)xorMask 84 | { 85 | NSInteger streamLength = 0; 86 | for (NSData *p in packets) { 87 | streamLength += PacketStreamHeaderLength + p.length; 88 | } 89 | 90 | NSMutableData *raw = [[NSMutableData alloc] initWithLength:streamLength]; 91 | uint8_t *ptr = raw.mutableBytes; 92 | for (NSData *packet in packets) { 93 | *(uint16_t *)ptr = CFSwapInt16HostToBig(packet.length); 94 | ptr += PacketStreamHeaderLength; 95 | [PacketStream memcpyXor:ptr src:packet xorMask:xorMask]; 96 | ptr += packet.length; 97 | } 98 | return raw; 99 | } 100 | 101 | @end 102 | --------------------------------------------------------------------------------