macOS network extension - activate vpn provider failed on startVPNTunnel - swift

I'm trying to start the vpn provider from a container application
After I successfully activated the extension, and started the process by sending xpc request to the network extension, I've tried to load the provider and start getting notifications about handleNewFlow
I use the following callback to signal process has started, in order to start the configuration phase.
extension NetworkExtensionManager: OSSystemExtensionRequestDelegate {
...
func request(_ request: OSSystemExtensionRequest,
didFinishWithResult result: OSSystemExtensionRequest.Result) {
...
After loadAllPreferences, I've set the manager from which I'd like to load the provider:
NEAppProxyProviderManager.loadAllFromPreferences { [self] (managers, error) in
assert(Thread.isMainThread)
if let error = error {
print(error.localizedDescription)
} else {
let manager = managers?.first ?? NEAppProxyProviderManager()
let proto = (manager.protocolConfiguration as? NETunnelProviderProtocol) ?? NETunnelProviderProtocol()
proto.serverAddress = "myHost"
proto.providerBundleIdentifier = "myExtensionBundle"
proto.providerConfiguration = ["key": "val"]
manager.localizedDescription = "myApp"
manager.protocolConfiguration = proto
manager.isEnabled = true
Then I extract the connection out of the manager and use it to start the tunnel provider (hopefully this operation will create a new item under System Preferences --> Network)
let session = manager.connection as! NETunnelProviderSession
do {
os_log(" manager.connection status: \(session.status.rawValue)")
try session.startVPNTunnel(options: nil)
}
catch {
os_log("failed to initProviderManager app proxy provider, \(error.localizedDescription)")
print(error)
}
However, I've got the following error message from the exception thrown out of this line session.startVPNTunnel :
failed to initProviderManager app proxy provider, The operation couldn’t be completed. (NEVPNErrorDomain error 1.)
Looking for the error name I found this NEVPNErrorConfigurationInvalid
Perhaps you can help me figure out where I go wrong in my attempt to start the tunnel provider ?
Thanks !

Related

Not retrieving .notConnectedToInternet URLSession

So I'm trying to get URLSession URLError.code .notConnectedToInternet but all I'm getting is Code(rawValue: -1020) when using URLSession when disconnecting from the internet.
URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
print("error.code \((error as! URLError).code)")
//prints - error.code Code(rawValue: -1020)
if (error as! URLError).code == .notConnectedToInternet {
print("no internet")
//doesn't print
return
}
}
error code -1020 means dataNotAllowed. It means the connection failed because data use isn’t currently allowed on the device.
What you are trying to catch notConnectedToInternet error code -1009 means connection failed because the device isn’t connected to the internet.
So notConnectedToInternet is not same as dataNotAllowed. In this case check your device settings.

Failed to connect HydraSDK

I'm using HydraSDK to create VPN app. I logged in successfully, get country (servers) list and when try to connect to closest server I receive error
Restart VPN error: Error Domain=com.anchorfree.hydra.manager Code=4
"failed_to_connect"
UserInfo={NSLocalizedDescription=failed_to_connect}
I'm using this code to start VPN
private func startVPN() {
self.hydraClient.start(location: nil) { (e, _) in
if let ex = e {
print("Restart VPN error: \(ex)")
} else {
print("Restart VPN success, country: \(self.country?.code ?? "unknown")")
}
}
}
Problem was in extension info.plist

CloudKit was Working but Getting a Permission Error All of a Sudden

I had CloudKit working for the last couple weeks and this morning when I was trying to save a record, something I had done a number of times before, I started getting a Permission Error
Error saving to CloudKit: <CKError 0x600001f48ed0: "Permission Failure"
(10/2007); server message = "Operation not permitted"; uuid = 78FA3DD1-
EA44-4701-9A7E-8291F076DD8F; container ID = "[CloudKit Container Name]"> - Error fetching auth tokens from server:
Operation not permitted'
So I have triple checked that it's requesting to the right container, which it is (I only have two containers setup on my CloudKit so it's an easy check.
I have turned off and turned CloudKit on again in XCode as an attempt to force reset it (not sure if that did anything helpful but figured I would give it a shot)
In case this is needed, this is how I am saving to CloudKit (had no problem with this bit of code in the past.
func createRecord(title: String, type: String, comment: String) {
let audioRecord = CKRecord(recordType: "Audio")
audioRecord["title"] = title as CKRecordValue
audioRecord["type"] = type as CKRecordValue
audioRecord["comment"] = comment as CKRecordValue
let audioURL = audioRecorder.getAudioURL()
let audioAsset = CKAsset(fileURL: audioURL)
audioRecord["audio"] = audioAsset
DispatchQueue.main.async {
CKContainer.default().publicCloudDatabase.save(audioRecord) { [self] record, error in
//print(CKContainer.default())
if let error = error {
print("Error saving to CloudKit: \(error.self) - \(error.localizedDescription)")
} else {
print("Record has been successfully saved to CloudKit")
}
}
}
}

Swift: Proper Firebase error-handling

I'm not able to understand why neither print lines are executed when running the following code:
ref.child("schools/\(schoolTextField.text!)/settings/pin").observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot.value)
}, withCancel: { (error) in
print(error.localizedDescription)
})
It used to work, until I made some changes regarding firebase authentication, but I don't see why the withCancel block is not executed!
How do I catch whatever error is occuring here? No error-message is printed in the log.
EDIT:
I found a similar question here which suggests that the problem might be related to the authentication after all. In appDelegate's didFinishLaunchingWithOptions I check if the user auth-token exists in Firebase Auth:
Auth.auth().currentUser?.getIDTokenForcingRefresh(true, completion: { (response, error) in
guard error == nil, let uid = response else {
print(error)
return
}
...
})
In current case there is an error, which is printed:
Error Domain=FIRAuthErrorDomain Code=17011 "There is no user record corresponding to this identifier. The user may have been deleted."
I'm now also getting these errors printed in the log:
[Common] _BSMachError: port b43b; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
[Common] _BSMachError: port b43b; (os/kern) invalid name (0xf) "Unable to deallocate send right"
Try this way:
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshots {
print("SNAP: \(snap)")
}
Also The error code 17011 is a user not found error see FIRAuthErrorCode for more info also it's better you create a Dataservice class to handle your interaction with firebase see Creating A Reusable Firebase Data Service for more info.

Connecting to VPN with Swift 3

I'm trying to connect to a VPN in an iOS app. What I already know is the VPN type (L2TP over IPSec), account name, password and shared secret. The connection works through Mac's Network settings. Although, it seems a little more complicated, when you have to use this info in code.
First, I have imported the necessary library.
import NetworkExtension
Then, I'm trying to load preferences and in case of error, I'm using my own and save them. Looks like this:
NEVPNManager.shared().loadFromPreferences { error in
// config
NEVPNManager.shared().saveToPreferences { error in
if (error == nil) {
do {
try NEVPNManager.shared().connection.startVPNTunnel()
} catch {
print("Couldn't connect")
}
} else {
print("NEVPNManager.saveToPreferencesWithCompletionHandler failed: \(error!.localizedDescription)")
}
}
}
Where you can see the "// config", my data should be passed. I'm not 100% sure, if I'm doing it right.
There's a constant let p = NEVPNProtocolIPSec() where I'm placing my data. It's like p.username = "smth".
The question is: which fields of p should be filled? Where do I put the shared secret?
--- UPDATE ---
I'm always getting the error:
NEVPNManager.saveToPreferencesWithCompletionHandler failed: The operation couldn’t be completed. (NEVPNErrorDomain error 4.)
I can't find anything specific about that.
During the config, fields .sharedSecretReference and .passwordReference require the Data? object. I'm getting it by using keychain.get("passref")?.data(using: .utf8, allowLossyConversion: true) preceded by
let keychain: KeychainSwift! = KeychainSwift()
keychain.set("<my_password>", forKey: "passref")
(class KeychainSwift comes from here)
Where am I making a mistake?