Update: It appears that this Keychain bug no longer exists on Big Sur Beta 5. The original post was reported from Catalina 10.15.6. It would still be helpful to know if there is a solution for Catalina. Thanks!
Post
Replies
Boosts
Views
Activity
Okay, the iOS-style keychain being per-user is what I thought might be happening. Good to know, so I don't keep trying to make that work. I was able to get my Network Extension to get the key from Keychain through the XPC service instead. Thanks!
Note to anyone else: To allow a Network Extension, or any sandboxed app, to access a privileged XPC service, it needs the com.apple.security.temporary-exception.mach-lookup.global-name temporary - https://developer.apple.com/forums/thread/112427?answerId=345920022#345920022 entitlement. Documentation for this entitlement here - https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html#//apple_ref/doc/uid/TP40011195-CH5-SW6. This entitlement may make it "tricky - https://developer.apple.com/forums/thread/99602?answerId=303367022#303367022" to get an app into the Mac App Store, but for self-published ("Developer ID") apps its okay. (Oh also, since its somewhat relevant, info on securing a privileged XPC service here - https://github.com/securing/SimpleXPCApp.)
I also encountered this bug while creating a transparent proxy (NEAppProxyProvider in extension, NETransparentProxyManager in host app). Although the solution provided by zx2c4 works to stop the proxy from crashing 15-20 seconds after it starts, it leads to another problem: when the proxy is disconnected gracefully (e.g. user clicks "Disconnect" in System Preferences), the proxy will hang on "Disconnecting" for about 5 seconds before finally exiting.
I don't know what exactly causes this "Disconnecting" problem, but my guess is that calling exit(0) immediately after completionHandler() in stopProxy does not give sufficient time for the proxy to communicate its successful close to the remote network service manager before the proxy exits. Therefore, the network service manager just waits a certain amount of time before assuming the proxy crashed and moving it to the "Not Connected" state.
My solution is to call exit(0) as suggested by zx2c4, but immediately before that, sleep for half a second with Darwin.usleep(500000). Of course, that adds a ~0.5 second delay on exit, but it's much better than ~5 seconds. I'm aware this is even more filthy than the already self-described "filthy hack" by zx2c4, but... it seems to work.
So the final code should look something like:
override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
/* ... shutdown work... */
completionHandler()
#if os(macOS)
/* Workaround for apple bug 32073323. */
Darwin.usleep(500000)
exit(0)
#endif
}