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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With