-
-
Save IhorYachmenov/fb63fd19f30541780950b6670e8a2865 to your computer and use it in GitHub Desktop.
| import Foundation | |
| import NetworkExtension | |
| class VPNIKEv2Setup { | |
| static let shared = VPNIKEv2Setup() | |
| let vpnManager = NEVPNManager.shared() | |
| func initVPNTunnelProviderManager() { | |
| print("CALL LOAD TO PREFERENCES...") | |
| self.vpnManager.loadFromPreferences { [self] (error) -> Void in | |
| if((error) != nil) { | |
| print("VPN Preferences error: 1 - \(String(describing: error))") | |
| } else { | |
| let IKEv2Protocol = NEVPNProtocolIKEv2() | |
| IKEv2Protocol.authenticationMethod = .certificate | |
| IKEv2Protocol.serverAddress = VPNServerSettings.shared.vpnServerAddress | |
| IKEv2Protocol.remoteIdentifier = VPNServerSettings.shared.vpnRemoteIdentifier | |
| IKEv2Protocol.localIdentifier = VPNServerSettings.shared.vpnLocalIdentifier | |
| IKEv2Protocol.useExtendedAuthentication = false | |
| IKEv2Protocol.ikeSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256GCM | |
| IKEv2Protocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group20 | |
| IKEv2Protocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA512 | |
| IKEv2Protocol.ikeSecurityAssociationParameters.lifetimeMinutes = 1440 | |
| IKEv2Protocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256GCM | |
| IKEv2Protocol.childSecurityAssociationParameters.diffieHellmanGroup = .group20 | |
| IKEv2Protocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA512 | |
| IKEv2Protocol.childSecurityAssociationParameters.lifetimeMinutes = 1440 | |
| IKEv2Protocol.deadPeerDetectionRate = .medium | |
| IKEv2Protocol.disableRedirect = true | |
| IKEv2Protocol.disableMOBIKE = false | |
| IKEv2Protocol.enableRevocationCheck = false | |
| IKEv2Protocol.enablePFS = true | |
| IKEv2Protocol.useConfigurationAttributeInternalIPSubnet = false | |
| IKEv2Protocol.serverCertificateIssuerCommonName = VPNServerSettings.shared.vpnServerCertificateIssuerCommonName | |
| IKEv2Protocol.disconnectOnSleep = false | |
| IKEv2Protocol.certificateType = .ECDSA384 | |
| IKEv2Protocol.identityDataPassword = VPNServerSettings.shared.p12Password | |
| IKEv2Protocol.identityData = self.dataFromFile() | |
| self.vpnManager.protocolConfiguration = IKEv2Protocol | |
| self.vpnManager.localizedDescription = "Venom VPN" | |
| self.vpnManager.isEnabled = true | |
| self.vpnManager.isOnDemandEnabled = false | |
| //Set rules | |
| var rules = [NEOnDemandRule]() | |
| let rule = NEOnDemandRuleConnect() | |
| rule.interfaceTypeMatch = .any | |
| rules.append(rule) | |
| // self.vpnManager.onDemandRules = rules | |
| print("SAVE TO PREFERENCES...") | |
| //SAVE TO PREFERENCES... | |
| self.vpnManager.saveToPreferences(completionHandler: { (error) -> Void in | |
| if((error) != nil) { | |
| print("VPN Preferences error: 2 - \(String(describing: error))") | |
| } else { | |
| print("CALL LOAD TO PREFERENCES AGAIN...") | |
| //CALL LOAD TO PREFERENCES AGAIN... | |
| self.vpnManager.loadFromPreferences(completionHandler: { (error) in | |
| if ((error) != nil) { | |
| print("VPN Preferences error: 2 - \(String(describing: error))") | |
| } else { | |
| var startError: NSError? | |
| do { | |
| //START THE CONNECTION... | |
| try self.vpnManager.connection.startVPNTunnel() | |
| } catch let error as NSError { | |
| startError = error | |
| print(startError.debugDescription) | |
| } catch { | |
| print("Fatal Error") | |
| fatalError() | |
| } | |
| if ((startError) != nil) { | |
| print("VPN Preferences error: 3 - \(String(describing: error))") | |
| //Show alert here | |
| print("title: Oops.., message: Something went wrong while connecting to the VPN. Please try again.") | |
| print(startError.debugDescription) | |
| } else { | |
| print("Starting VPN...") | |
| } | |
| } | |
| }) | |
| } | |
| }) | |
| } | |
| } | |
| } | |
| //MARK:- Connect VPN | |
| static func connectVPN() { | |
| VPNIKEv2Setup().initVPNTunnelProviderManager() | |
| } | |
| //MARK:- Disconnect VPN | |
| static func disconnectVPN() { | |
| VPNIKEv2Setup().vpnManager.connection.stopVPNTunnel() | |
| } | |
| //MARK:- Disconnect VPN | |
| static func testConnect() { | |
| do { | |
| try VPNIKEv2Setup().vpnManager.connection.startVPNTunnel() | |
| } catch let error { | |
| print(error) | |
| } | |
| } | |
| //MARK:- check connection staatus | |
| static func checkStatus() { | |
| let status = VPNIKEv2Setup().vpnManager.connection.status | |
| print("VPN connection status = \(status.rawValue)") | |
| switch status { | |
| case NEVPNStatus.connected: | |
| print("Connected") | |
| case NEVPNStatus.invalid, NEVPNStatus.disconnected : | |
| print("Disconnected") | |
| case NEVPNStatus.connecting , NEVPNStatus.reasserting: | |
| print("Connecting") | |
| case NEVPNStatus.disconnecting: | |
| print("Disconnecting") | |
| default: | |
| print("Unknown VPN connection status") | |
| } | |
| } | |
| func dataFromFile() -> Data? { | |
| let rootCertPath = Bundle.main.url(forResource: "phone", withExtension: "p12") | |
| print(rootCertPath?.absoluteURL as Any) | |
| return try? Data(contentsOf: rootCertPath!.absoluteURL) | |
| } | |
| } | |
| class VPNServerSettings: NSObject { | |
| static let shared = VPNServerSettings() | |
| let p12Password = "*****" // password from file certificate "****.p12" | |
| let vpnServerAddress = "******" | |
| let vpnRemoteIdentifier = "*******" // In my case same like vpn server address | |
| let vpnLocalIdentifier = "phone@caf1e9*******.algo" | |
| let vpnServerCertificateIssuerCommonName = "*******" // In my case same like vpn server address | |
| } | |
How do I use it in content view? Can you give me an example?
@Rayan25062011 Hi, in this realization VPNIKEv2Setup is Singelton because you can call any non-static function such as VPNIKEv2Setup.initVPNTunnelProviderManager.initVPNTunnelProviderManager(), and after that in any comfortable place use VPNIKEv2Setup. connectVPN() and disconnectVPN() etc., or rewrite realization for your requirements
@Rayan25062011 Hi, in this realization VPNIKEv2Setup is Singelton because you can call any non-static function such as VPNIKEv2Setup.initVPNTunnelProviderManager.initVPNTunnelProviderManager(), and after that in any comfortable place use VPNIKEv2Setup. connectVPN() and disconnectVPN() etc., or rewrite realization for your requirements
Thank you very much @IhorYachmenov
@Dearimranullah select your Target than tab "Signing & Capabilities" and you should enable capability "Network Extension -> and check Packet Tunnel" and add another one capability "Personal VPN", and in your entitlements file add "Outgoing Network Connections" - > YES, maybe last step will added automatically can't recall that. Then when you will call loadFromPreferences you should see alert with permission access