Hello! Thank you very much for your response! We greatly appreciate the chance to discuss Apple's technologies with their engineers!
[quote='798218022, DTS Engineer, /thread/760964?answerId=798218022#798218022']
If you run a tool from Terminal, then Terminal is considered the responsible code and, as a system app, it’s not subject to local network privacy.
[/quote]
I have conducted more experiments and have attached the new results to FB14581221 (bundled_as_cli_term). If you run the bundled application for the first time through the terminal, a prompt will appear for the Terminal.app. This is not the case for me, but the results of the experiment don't match your expectations:
[quote='798218022, DTS Engineer, /thread/760964?answerId=798218022#798218022']
If you run an executable as a launchd daemon, it runs as root and local network privacy does not apply to code running as root.
[/quote]
Here my experiments also show different results - if the bundled application is launched as a launchd daemon, the prompt will appear, even though the app runs with root privileges (see "bundled_as_daemon" in the attachments for FB14581221):
The latter scenario has an impact on the user experience of my application and I would like to prepare carefully for changes in the macOS. It would be helpful if you could provide information about the expected outcomes of the scenarios mentioned.
Post
Replies
Boosts
Views
Activity
There's a new SCSIPeripheralsDriverKit framework in macOS Ventura. But I can't mach my simple dext with any attached device. There's no info about required entitlements and values of IOKitPersonalities in the docs.
As a matter of workflow I always recommend to first open the remote side of the connection with an API like NWConnection, or nw_connection_t. Then, after the remote side has gone into the ready state, open the local flow via [NEAppProxyFlow openWithLocalEndpoint:completionHandler:].
Yes, I do it as you've described in my network extension. But the problem is that the dart interpreter doesn't wait for the connection establishment and tries to get the local port (via getsockname) right after connect call on the non-blocking socket. So, the sequence of events is the following: Dart calls connect() on a non-blocking socket.
Network extension intercepts dart's flow and calls my [NETransparentProxyProvider handleNewFlow:] handler.
My network extension starts nw_coneection_t and returns from [NETransparentProxyProvider handleNewFlow:] handler. As an alternate scenario, it can just return false to return intercepted flow to the system.
Dart's control flow returns from connect() with EINPROGRESS errno.
Right after connect() returns, dart calls getsockname() to get the local port of TCP connections and gets 0, which isn't the expected value. So dart throws an exception and fails TCP connection (closing its socket).
After nw_connection_t becomes ready network extension calls [NEAppProxyFlow openWithLocalEndpoint:completionHandler:] with localEndpoint corresponding to nw_connection_t one. But the dart have closed connection already and completion handler of [NEAppProxyFlow openWithLocalEndpoint:completionHandler:] returns error (flow is not connected, or something like that).
So, should I start the new issue in the dart GitHub project or expect the new API in NetworkExtension.framework?
Regards,
Denis Verevkin
If the Dart side waits for the remote side of the connection to setup first and then calls:
[NEAppProxyFlow openWithLocalEndpoint:completionHandler:]
Does this work out better then with a localEndpoint?
I've changed the dart SDK code to get local port only after the connection is established, and it seems all works fine. I'm not sure about the right solution: should dart developers fix their code or NE API should be changed to be able to set localEndpoint before [NEAppProxyFlow openWithLocalEndpoint:completionHandler:] call.
The Flutter package manager uses dart lang to do its stuff, and NETransparentProxyManager breaks all TCP connections made from the dart interpreter. The problem is that dart opens the connection asynchronously (with a socket in non-blocking mode) and tries to get the local port without waiting for the connection end. But if NETransparentProxyManager is enabled, the local port isn't available yet (it will be available only after [NEAppProxyFlow openWithLocalEndpoint:completionHandler:] call), so dart script throws an exception, which ends up with connection fail. I've filed feedback about it - FB8999915.