NEVPNManager Connect to VPN in Swift

后端 未结 1 1270
耶瑟儿~
耶瑟儿~ 2021-02-03 15:07

I can\'t find a clear answer on how to do this, so that\'s why I created this thread.
I\'m developing a Swift application (Swift 2), where I want to connect with an VPN Ser

1条回答
  •  说谎
    说谎 (楼主)
    2021-02-03 15:47

    It's a little confusing but you setup a configuration with the desired parameters and then save that configuration to the NEVPNManager. After that start VPN tunneling.

    So you would have something like:

        NEVPNManager.sharedManager().loadFromPreferencesWithCompletionHandler { error in
            // setup the config:
            let password = vpnAccount!.vpnPassword          
            let vpnhost = vpnAccount!.vpnHost
            let p = NEVPNProtocolIKEv2()
            p.username = username
            p.localIdentifier = username
            p.serverAddress = vpnhost
            p.remoteIdentifier = vpnhost
            p.authenticationMethod = .None
            p.passwordReference = passwordRef
            p.useExtendedAuthentication = true
            p.serverCertificateIssuerCommonName = vpnhost
            p.disconnectOnSleep = false
    
    
            var rules = [NEOnDemandRule]()
            let rule = NEOnDemandRuleConnect()
            rule.interfaceTypeMatch = .Any
            rules.append(rule)
    
            NEVPNManager.sharedManager().localizedDescription = "My VPN"
            NEVPNManager.sharedManager().protocolConfiguration = p
            NEVPNManager.sharedManager().onDemandRules = rules
            NEVPNManager.sharedManager().onDemandEnabled = true
            NEVPNManager.sharedManager().enabled = true
            NEVPNManager.sharedManager().saveToPreferencesWithCompletionHandler { error in
                guard error == nil else {
                    print("NEVPNManager.saveToPreferencesWithCompletionHandler failed: \(error!.localizedDescription)")
                    return
                }
                VPNManager.sharedManager.startVPNTunnel()
            }
         }
    

    It is also nonobvious but important that you nest the completion handlers properly:

        loadFromPreferencesWithCompletionHandler{ 
            ...
            saveToPreferencesWithCompletionHandler{ 
                startVPNTunnel 
            }
        }
    

    passwordRef is:

                    let password = vpnAccount!.vpnPassword
                    vpnAccount!.setPersistenRef(username, password: password!)
                    let passwordRef = vpnAccount!.persistentRef
    

    and vpnAccount.persistentRef is:

    class func persistentRef(_ key: String) -> Data? {
        let query: [AnyHashable: Any] = [
            kSecClass as AnyHashable: kSecClassGenericPassword,
            kSecAttrGeneric as AnyHashable: key,
            kSecAttrAccount as AnyHashable: key,
            kSecAttrAccessible as AnyHashable: kSecAttrAccessibleAlways,
            kSecMatchLimit as AnyHashable: kSecMatchLimitOne,
            kSecAttrService as AnyHashable: Bundle.main.bundleIdentifier!,
            kSecReturnPersistentRef as AnyHashable: kCFBooleanTrue
        ]
    
        var secItem: AnyObject?
        let result = SecItemCopyMatching(query as CFDictionary, &secItem)
        if result != errSecSuccess {
            return nil
        }
    
        return secItem as? Data
    }
    

    I don't recall the details but seem to remember that the above was pretty important regarding creating the ref that NEVPNManager is looking for.

    0 讨论(0)
提交回复
热议问题