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 Server using a function. So I want to create a
func connect() {
//Handle the connection to the VPN
}
I received this https://gist.github.com/matthijsotterloo/cedf256f7f1c2a9a8f624481b7083afd file from the developer who made the VPN (of course I replaced certs,keys,url's and login's. Now my question is how can I connect to this VPN server in the function? I already found out I have to use the NEVPNManager but I can't really find out how to build this.
Hopefully someone can help me.
Thanks!
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.