So, I'm trying to use the iOS 8 Network Extension Framework to set up a VPN connection when users click on UIButton. I used the following tutorial: http://ramezanpour.net/post/2014/08/03/configure-and-manage-vpn-connections-programmatically-in-ios-8/
But for some reason, it keeps asking for a vpn password and a shared secret. Even if I set the passwordReference and sharedSecretReference. And if I enter this data when installing the profile, it still will not work. It just does nothing when starting a connection using the framework. When trying to connect using the settings application, it gives the error "there not sharedSecret".
This is the code that I use to configure the connection.
func toggleConnection(sender: UIButton) {
if(!self.connected){
self.manager.loadFromPreferencesWithCompletionHandler { (error) -> Void in
if((error) != nil) {
println("VPN Preferences error: 1")
}
else {
var p = NEVPNProtocolIPSec()
p.username = "$username"
p.serverAddress = "$vpn"
p.passwordReference = KeychainService.dataForKey("vpnPassword")!
println(p.passwordReference)
p.authenticationMethod = NEVPNIKEAuthenticationMethod.SharedSecret
p.sharedSecretReference = KeychainService.dataForKey("sharedSecret")!
println(p.sharedSecretReference)
p.localIdentifier = "vpn"
p.remoteIdentifier = "vpn"
p.disconnectOnSleep = false
self.manager.`protocol` = p
self.manager.onDemandEnabled = true
self.manager.localizedDescription = "VPN"
self.manager.saveToPreferencesWithCompletionHandler({ (error) -> Void in
if((error) != nil) {
println("VPN Preferences error: 2")
println(error)
}
else {
var startError: NSError?
self.manager.connection.startVPNTunnelAndReturnError(&startError)
if((startError) != nil) {
println("VPN Preferences error: 3")
println(startError)
}
else {
println("Start VPN")
}
}
})
}
}
}
}
These are the functions that I use as a link to a link chain.
class func save(service: NSString, key: String, data: NSString) {
var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, key, dataFromString], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData])
SecItemDelete(keychainQuery as CFDictionaryRef)
if data == "" { return }
var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
println(status)
}
class func load(service: NSString, key: String) -> NSData? {
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, key, kCFBooleanTrue, kSecMatchLimitOne, kCFBooleanTrue], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit, kSecReturnPersistentRef])
var dataTypeRef :Unmanaged<AnyObject>?
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
println(status)
if (status != errSecSuccess) {
return nil
}
let opaque = dataTypeRef?.toOpaque()
var contentsOfKeychain: NSData? = nil
if let op = opaque {
let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
contentsOfKeychain = retrievedData
}
println(contentsOfKeychain)
return contentsOfKeychain
}
Any help is appreciated!