Network Extension

RSS for tag

Customize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.

Posts under Network Extension tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

NEHotspotNetwork BSSID missing first character?
please consider this code: [NEHotspotNetwork fetchCurrentWithCompletionHandler:^(NEHotspotNetwork *network) { if (network) { DebugLog(@"Network ssid: %@, bssid: %@", network.SSID, network.BSSID); } else { DebugLog(@"No available network"); } }]; For me, I have a strange situation - say that the BSSID of my network is "01:34:56:78:90" the string in the property is missing the first character! what is contains (and is printed) is "1:34:56:78:90" - the leading "0" is missing. So, I was wondering if this is a know thing, or if perhaps it's only Asus (my router)? Or, am I doing something wrong? Pointers would be much appreciated.
2
0
419
Oct ’23
inconsistent connection to an IoT device's access point error -3936 and failed forced association
We have an app that connects to an IoT device to configure it; we're connecting to an access point and we have inconsistent results with the iOS solution (we're using MAUI for both iOS and Android); the Android experience is consistently successful. We've narrowed the error in the logs to the following section - and the question is what do the error values mean? We can't quite figure out what is happening or why. Our guess is the SSID of the target network is getting set to null at some point, but that is only a guess. We've found only a couple of other similar issues at these posts, but no solution that is apparent https://developer.apple.com/forums/thread/690602 https://developer.apple.com/forums/thread/665011 https://developer.apple.com/forums/thread/665324 Can you see what we're missing? Here is the log section we believe is the critical point and is what shows an error when there is a failure to connect: 09/25/2023 15:32:03.403 __WiFiDeviceManagerEvaluateAPEnvironment: no known BSS for this network. Learning environment. 09/25/2023 15:32:03.405 WiFiNetworkSetProperty: null network 09/25/2023 15:32:03.405 __WiFiDeviceManagerReleaseWakeAssertionForAutoJoin: PM assertion not held. 09/25/2023 15:32:03.405 __WiFiDeviceManagerUserForcedAssociationCallback: error -3936 reqInfo (null) 09/25/2023 15:32:03.406 __WiFiDeviceManagerUserForcedAssociationCallback: enabling device manager 09/25/2023 15:32:03.406 WiFiBatteryMgmt : -[WiFiBatteryManager requestPowerResource::]: Power resource request for AutoJoin added. Pending=1. 09/25/2023 15:32:03.406 -[WiFiBatteryManager isPowerResourceAvailable:]: WiFiBatteryMgmt : resource is unavailable for type AutoJoin. claimedResource is 0 09/25/2023 15:32:03.407 __WiFiDeviceManagerUserForcedAssociationCallback: failed forced association 09/25/2023 15:32:03.407 __WiFiDeviceManagerDispatchUserForcedAssociationCallback: result 2 09/25/2023 15:32:03.410 __WiFiDeviceManagerForcedAssociationCallback: failed to association error 2 09/25/2023 15:32:03.410 __GetNetworkWithSameSsid: network (null) not found 09/25/2023 15:32:03.410 __WiFiDeviceManagerForcedAssociationCallback: removing password for (null) 09/25/2023 15:32:03.410 WiFiSecurityRemovePassword: Removing password for (null) 09/25/2023 15:32:03.411 __WiFiSecurityRemovePassword: null account 09/25/2023 15:32:03.411 WiFiLocalizationGetLocalizedString: lang='English' key='WIFI_JOIN_NETWORK_FAILURE_TITLE' value='Unable to join the network “%@”' 09/25/2023 15:32:03.412 WiFiLocalizationGetLocalizedString: lang='English' key='WIFI_FAILURE_OK' value='OK'
3
0
323
Sep ’23
MacOS Sonoma: Wi-Fi says disconnected when running VPN
Hi, We run a PacketTunnelProvider VPN on our macbooks. When we updated the Mac to MacOS Sonoma, we see strange behavior with regards to the Wi-Fi menu in system settings. After we connect a VPN, the Wi-Fi switch gets blanked out, and it doesn't detect any other networks. This is in contrast to the wifi task-bar, where we can see it functioning normally. Wi-Fi and the VPN also function normally. Switching Wi-Fi networks does not work, and after, the Mac will not connect to any Wi-Fi networks until it restarts. After disconnecting the VPN, this problem remains. The only way to fix this is to restart the Mac. I've filed FB13205010. I'm wondering if anyone has seen anything like this, because it makes having a VPN unusable on this version of macOS. All of the following screenshots were taken at the same time.
1
0
1.1k
Sep ’23
Excluding a single application from full tunnel packet tunnel.
We have a Developer Id signed VPN application using both NEPacketTunnelProvider and NEAppProxyProvider packaged as a single system extension. The requirement is for the application to implement a full tunnel VPN (has default route 0.0.0.0 on the utun interface) with the exception of another specific Developer Id signed application which needs its connections to bypass the tunnel. Originally, we attempted to use NETransparentProxyProvider to bypass the tunnel (for the single application) with the idea being to intercept the flows for the desired application in the transparent proxy and proxy these flows via a new NWConnection forced via the direct interface to bypass the tunnel. The problem we ran into was that the NEPacketTunnelProvider always get the packets before the NETranparentProxyProvider even though the proxy is started before the packet tunnel. So next attempt was to use NEAppProxyProvider with an NEAppRule set to capture flows for the specific application of interest. The good news is we get the application flows prior to the packet tunnel but the problem is the NEAppRule only seems to work for App Store signed applications, for example Safari. For Developer Id signed applications (for example Chrome) flows are actually blocked when an NEAppRule is added to the proxy configuration. This seems like a bug to me. The system log will show some messages about the http flow being blocked by policy. For the Safari case, when the NEAppRule is added we can see socket redirect policies added (system log). In the Developer Id signed apps there appears to be an error when OS is checking the apps certificate. What is the recommended way to implement our apps requirement? We have a full packet tunnel with the exception of a single, Developer Id signed, application.
6
0
595
Oct ’23
NEFilterPacketProvider, NEFilterManager, and permission denied
As I mentioned elsewhere, I am trying to add a packet filter to our app. I can load load the extension, but I am getting permission denied when I try to save the preferences with it. I am building for release, using a Developer ID Application certificate (macOS, if that wasn't clear). I am starting to worry that I can't do this except on an MDM-managed system.
6
0
654
Nov ’23
Different behaviour for IP packets when establishing connections from different targets.
We have a PacketTunnelProvider in a SystemExtension with split tunneling. We are configuring a private IP address range of 240.0.0.1/10 as included routes and specifying a few matching domains using NEPacketTunnelNetworkSettings. Once TunnelNetworkSettings has been applied successfully, a new utunx interface is created, and it includes routes for the 240.0.0.1/10 IP range. In our case, the interface name is utun3, where 'x' represents an integer value. According to our business logic, we need to establish connections with some IPs from this range. To achieve this, we are utilizing the NWConnection class API to create connections with IP addresses Like this func establishConnection() { // Specify the destination host and port let host = "240.0.0.19" let port = 80 // Create an NWHostEndpoint let endpoint = NWHostEndpoint(hostname: host, port: "\(port)") // Create an NWConnection let connection = NWConnection(to: endpoint, using: .tcp) connection.start(queue: .global()) } For the above code, we have observed different behaviour for IP packets when creating connections from different targets. In the first case, when we create a connection to the IP address 240.0.0.19 from the Main app target using the provided code, the IP packets correctly go through the utun3 interface because this address falls within the 240.0.0/10 range, which is part of the included routes. However, in the second case, when we use the same code to create a connection to 240.0.0.19 from the Extension target, the IP packets go through the primary interface en0 rather than the utun3 interface. **Question : ** Why do we have different behaviour for the same code? How can we achieve the same behaviour as the Main app target in the System Extension target? -- Thanks
9
0
738
Oct ’23
Audit token provided by NEFilterDataProvider sometimes fails to provide code object with SecCodeCopyGuestWithAttributes
I'm using this code to get the path of an executable from the audit token provided in NEFilterDataProvider.handleNewFlow(_:), forwarded from the Network Extension to the main app via IPC: private func securePathFromAuditToken(_ auditToken: Data) throws -> String { let secFlags = SecCSFlags() var secCode: SecCode? var status = SecCodeCopyGuestWithAttributes(nil, [kSecGuestAttributeAudit: auditToken] as CFDictionary, secFlags, &secCode) guard let secCode = secCode else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status)) } var secStaticCode: SecStaticCode? status = SecCodeCopyStaticCode(secCode, secFlags, &secStaticCode) guard let secStaticCode = secStaticCode else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status)) } var url: CFURL? status = SecCodeCopyPath(secStaticCode, secFlags, &url) guard let url = url as URL? else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status)) } return url.path } This code sometimes returns paths like /System/Library/PrivateFrameworks/HelpData.framework/Versions/A/Resources/helpd or /Library/Developer/CoreSimulator/Volumes/iOS_21A328/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.0.simruntime/Contents/Resources/RuntimeRoot/usr/libexec/mobileassetd. But sometimes the SecCodeCopyGuestWithAttributes fails with status 100001 which is defined in MacErrors.h as kPOSIXErrorEPERM = 100001, /* Operation not permitted */. In these cases I resort to this code, which I have read is not as secure: private func insecurePathFromAuditToken(_ auditToken: Data) throws -> String? { if auditToken.count == MemoryLayout<audit_token_t>.size { let pid = auditToken.withUnsafeBytes { buffer in audit_token_to_pid(buffer.baseAddress!.assumingMemoryBound(to: audit_token_t.self).pointee) } let pathbuf = UnsafeMutablePointer<Int8>.allocate(capacity: Int(PROC_PIDPATHINFO_SIZE)) defer { pathbuf.deallocate() } let ret = proc_pidpath(pid, pathbuf, UInt32(PROC_PIDPATHINFO_SIZE)) if ret <= 0 { throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno)) } return String(cString: pathbuf) } return nil } This insecure code then returns paths like /usr/libexec/trustd, /usr/libexec/rapportd, /usr/libexec/nsurlsessiond and /usr/libexec/timed. From what I can see, SecCodeCopyGuestWithAttributes fails for all processes in /usr/libexec. Some of these processes have executables with the same name placed in another directory, like /Library/Developer/CoreSimulator/Volumes/iOS_21A328/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.0.simruntime/Contents/Resources/RuntimeRoot/usr/libexec/mobileassetd for which it succeeds, while for /usr/libexec/mobileassetd it fails. Occasionally, both the secure and the insecure methods fail and in these cases the secure one returns status code 100003, which is defined as kPOSIXErrorESRCH = 100003, /* No such process */. When can this happen? This seems to happen with both NEFilterFlow.sourceAppAuditToken and sourceProcessAuditToken. What is the problem?
10
0
884
Oct ’23
New "Relay" entitlement doesn't exist in distribution provisioning profile in Enterprise account
We have an Enterprise Apple developer account “Cisco System, Inc. “STBU” - JBF29L28EJ”. We use it to make in-house distribution for QE testing. I found that development provisioning profile in this account includes new “relay” capability in the entitlement, but in-house distribution provisioning profile doesn’t have it. Below is the entitlement list in in-house distribution provisioning profile that doesn't include "relay": Entitlements &amp;lt;dict&amp;gt; &amp;lt;key&amp;gt;com.apple.developer.networking.networkextension&amp;lt;/key&amp;gt; &amp;lt;array&amp;gt; &amp;lt;string&amp;gt;app-proxy-provider&amp;lt;/string&amp;gt; &amp;lt;string&amp;gt;content-filter-provider&amp;lt;/string&amp;gt; &amp;lt;string&amp;gt;packet-tunnel-provider&amp;lt;/string&amp;gt; &amp;lt;string&amp;gt;dns-proxy&amp;lt;/string&amp;gt; &amp;lt;string&amp;gt;dns-settings&amp;lt;/string&amp;gt; &amp;lt;/array&amp;gt; &amp;lt;key&amp;gt;aps-environment&amp;lt;/key&amp;gt; &amp;lt;string&amp;gt;production&amp;lt;/string&amp;gt; We now cannot make in-house distribution build without this entitlement.
1
0
414
Oct ’23
Permission denied when installing Content Filter for individual-use Screen Time app
I'm using a Distribution-ready Family Controls Entitlement and it seems like I'm unable to save Content Filter configurations in my individual-use Screen Time app when I download a production build from TestFlight. For development builds, everything works fine. From nehelper: slowdown trying to create a content filter configuration through an app. Creating a content filter configuration is only allowed through profile in production version of slowdown. From the app: Failed to save configuration Slowdown: Error Domain=NEConfigurationErrorDomain Code=10 "permission denied" UserInfo={NSLocalizedDescription=permission denied} -[NEFilterManager saveToPreferencesWithCompletionHandler:]_block_invoke_3: failed to save the new configuration: Error Domain=NEFilterErrorDomain Code=5 "permission denied" UserInfo={NSLocalizedDescription=permission denied} TN3134 seems to suggest that Content Filters are allowed for Screen Time apps Platform: iOS, Packaged as: app extension, Minimum OS: 15.0, Restrictions: Screen Time apps TN3120 suggest the same: There are two ways to deploy a content filter on iOS. In a managed environment, use MDM to deploy a content filter to supervised devices. In an unmanaged environment, deploy your content filter as part of a Screen Time app. These technotes lead me to assume that this should be a supported use case. Any idea how to progress from here?
3
0
605
Oct ’23
What's the advantage of applying settings with NEFilterDataProvider.apply(_:) over manually checking incoming network flows?
I cannot find in the documentation if using NEFilterDataProvider.apply(_:) has any advantage over manually inspecting incoming flows in handleNewFlow(_:) other than being a shortcut. Or are those rules guaranteed to be applied even if the network extension crashes or similar? If it has no practical advantages, then manually inspecting each flow allows to set up more flexible dynamic rules.
7
0
439
Oct ’23
Switch between known Wi-Fi networks in unattended mode using Apple Enterprise/MDM
We are currently testing the idea of using an iPhone instead of a Raspberry Pi for our IoT project. We are part of the Apple Enterprise program, and the app is intended for internal use within the company. The only challenge we've encountered while porting the software to iOS is that there isn't an obvious way to switch between WiFi networks in unattended mode. Is there a way to switch between WiFi networks without requiring manual confirmation from the user? Does MDM or the Apple Enterprise program enable this feature? Our desired outcome is: To be able to scan nearby WiFi networks and connect to any of them programmatically using the SSID and password. Thank you.
1
0
264
Oct ’23
nesessionmanager sometimes not deallocating tunnel on VPN disconnect
We're seeing nessionmanager problems caused by having a configuration present on the system which. Has includeAllNetworks set in the protocol Was previously connected &amp; then disconnected After VPN disconnection we sometimes see that DNS and other things are not working. The VPN extension is no longer running, so I'd expect that settings would have been cleaned up, but they aren't in some cases. The system won't recover on its own, and when we delete the VPN configuration we see a set of messages from VPN session manager. There are two I've seen, on different systems. One shows the utun interface being cleaned up, and various network settings being removed. The other refers to deregistering an Enterprise VPN Session, [NESMVPNSession unsetDefaultDropAll], and IP Drop-All disabled. In both of these cases the cleanup is being done hours after the session was disconnected and the extension unloaded from memory. Does anyone know what exactly is happening there, and why the OS isn't cleaning up on disconnect?
7
0
781
Nov ’23
I need the information about the access-points/devices of the connected Wifi network
Hey, I need the information about the access-points/devices of the connected Wifi network, I repeat only of the **connected Wifi network ** My use caes is about the indoor positioning of a user connect the network and for that I need the information of all the access points (e.g. ssid, bssid, rssi etc.) but till now I am unable to find any starting point/solution for this. Any help regarding this will be highly appreciated. Regards, Aqeel Ahmed
8
0
632
Oct ’23
How can I get devices connected to the same wifi network?
I need to get all devices names which are connected to same wifi. I tried NetServiceBrowser, in netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) function I get some devices name like Macbook or iPad with search service type of browser.searchForServices(ofType: "_services._dns-sd._udp.", inDomain: "local.") But in this service type I cant get iPhones. I'm not sure if this is the right way, which framework should I use to accomplish this? Am I on the right track? What permits do I need to get? I need your help. Best regards.
3
1
703
Oct ’23
VPN get disconnected between connecting and connected when includeAllNetworks is set
I am trying to set includeAllNetworks flags right now and I see some wield behaviors from macOS system: default 13:32:50.825941+0800 ***** <debug> newStatus = Connecting... default 13:32:51.816353+0800 ***** <debug> newStatus = Disconnected default 13:32:52.222371+0800 ***** <debug> newStatus = Connected The app which is observing VPN status gets notified with disconnected status between connecting and connected. And in some cases I find that app will never gets connected notification after disconnected. In that case tunnel interface and all tunnel network settings are well set. But our UI logic will just handle the disconnected case. If I just clear the includeAllNetwork flag, then everything is fine. default 14:13:50.075947+0800 *****<debug> newStatus = Connecting... default 14:13:50.829195+0800 *****<debug> newStatus = Connected The test environment is macOS 14.0 and I am using network extension framework for the status KVO. So I am just wondering if this is expected behavior or not. If this is expected, then is there any suggestion that I should use to work around it?
2
0
330
Oct ’23
Identifying actual apps which is using com.apple.WebKit.Networking.xpc
Hi, AFAIK Safari or any macOS apps which uses WKWebview, uses com.apple.WebKit.Networking.xpc to do actual networking. I am working on a packet tunnel, where I am able to get process id associated with packet read. Based on process id, i am using libproc to get process name. I am facing below problem: For Safari or any other apps which uses WKWebview having same process name: com.apple.WebKit.Networking Any ways to distinguish wether it is from safari or other xyz wkwebview apps? Related Problem: https://developer.apple.com/forums/thread/693528 In this thread, app proxy can help but in packet tunnel no such options exposed.
1
0
721
Oct ’23
VPN profile says "update required", doesn't load properties or init packet tunnel provider
I'm setting up an app that will need to intercept all traffic on the device. Configuration is: let manager = NETunnelProviderManager() let protocolConfiguration = NETunnelProviderProtocol() protocolConfiguration.providerBundleIdentifier = "com.***.PacketTunnelProvider" protocolConfiguration.serverAddress = "VPN Server" protocolConfiguration.providerConfiguration = ["key": "value"] manager.protocolConfiguration = protocolConfiguration manager.localizedDescription = "VPN Server" The configuration is correctly saved but in the settings, the profile comes out with "Update required" and "must be updated by the developer before VPN Server can be connected" Looking around the forums, I already checked the entitlements on the binary and everything comes out good: <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider</string> <string>packet-tunnel-provider</string> </array> on the main bundle and [Key] com.apple.developer.networking.networkextension [Value] [Array] [String] app-proxy-provider [String] packet-tunnel-provider on packettunnelprovider.appex When I try to start the tunnel with func startProxyServer() { NETunnelProviderManager.loadAllFromPreferences { (managers, error) in if let error = error { print("Error loading preferences: \(error)") return } let manager = managers?.first(where: { $0.localizedDescription == "VPN Server" }) manager!.loadFromPreferences { error in if let error = error { print("Error loading preferences: \(error)") } else { do { try manager!.connection.startVPNTunnel(options: nil) print("Started tunnel.") } catch { print("Failed to start tunnel: \(error)") } } } } putting a breakpoint will show that the profile gets loaded but it lacks completely the protocol configuration. Funnily enough, I don't get an error so I get to the "Started tunnel" code branch. Of course without the protocol configuration, even if the manager is "loaded" and connection.startVPNtunnel is called, the packettunnelprovider is never initialized and nothing actually starts. Build targets are the same on both the main app and the packet tunnel provider target, and I tried lowering or raising them to no effect. How to further debug this?
4
0
501
Oct ’23