Post

Replies

Boosts

Views

Activity

Getting old filesystem events - check which process deleted a specific folder
After macOS minor upgrade of Monterey I've noticed that a directory of mine that lies under /Library/Application Support/myCompany/myProj/myFolder has been mysteriously deleted. Is there a way to check in retrospect which process deleted my directory ? I know of fs_usage, but it's used to record ongoing file activities... the question is how to get file auditing event from the past. Thanks
1
0
1.1k
Dec ’22
macOS, call uninstall script when drag-and-drop app into the trash icon
I'm working on some app that has LaunchDaemon running on the background, and thus it requires some operations to be removed, prior to deleting the data/exe files. Is there an option to call an uninstall script upon drag-and-drop my app into the trash bin ? or at least, prevent the uninstallation and trigger popup window that tells the user this app cannot be removed until he unload the service (sudo launchctl stop /Library/LaunchDaemons... or sudo launchctl unload -w /Library/LaunchDaemons...) my app uses pkg file format for deployment, but I couldn't find any uninstall callback within this format. is there a way to do so ? Thanks
1
0
1.5k
Dec ’22
How to enable multiple proxy managers waiting for user approval event before execute SaveToPreferences completionHandler
I have a MacOS network extension that activates 3 network "Proxies" (TransparentProxy, AppProxy and DNSProxy). To activate the proxies I do: NEAppProxyProviderManager.loadAllFromPreferences { saveToPreferences { error in if (error) { /* failed to save */ } /* saved */ } } Now I do this 3 times (once for each proxy). The behavior I observe is the following: Once the "saveToPreferences()" is called for the first time the app is installed, user gets an approval popup. Even before user clicks anything, the first 2 calls to "saveToPreferences" fail (both with the same message): Failed to save configuration MyTransparentProxy: Error Domain=NEConfigurationErrorDomain Code=10 “permission denied” UserInfo={NSLocalizedDescription=permission denied} The third call to "saveToPreferences()" does NOT return until a user either accepts or rejects the "allow vpn configuration" pop up. My question is, how can I make all the calls to block the completion callback until user decision ? For now, I figured out that this works as workaround: In the initialization of the first proxy I do: NEAppProxyProviderManager.loadAllFromPreferences { saveToPreferences { error in if (error) { /* failed to save */ } /* saved */ /* here I start the “next” proxies */ StartNextProxy(); } } In this case the first one is blocked until user accepts the pop up and once he does I start the second and the third proxies. This ensure avoidance of "permission denied" error as only one "saveToPreferences()" call waits for user approval. This doesn’t feel like the correct method to me, is there a way for multiple proxy manager to wait for "VPN Configuration" approval event ? Thanks !
1
0
1.4k
Jan ’23
NSURLSession fails on TLS due to "TLS Trust evaluation failed(-9802)"
Hi, I'm using NSURSessionDataTask in order to send REST command to remote server. the server doesn't request client-side verification in TLS, but the client does request server authentication as implemented in the following code if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { NSURLCredential* credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); However, even though I set the server certificate as "Trusted" I get the following failure : 2023-01-13 00:45:51.139349+0700 0x348f4 Default  0x0        7633 0 pas: (CFNetwork) System Trust Evaluation yielded stat us(-9802) 2023-01-13 00:45:51.139390+0700 0x348f4 Error   0x0        7633 0 pas: (CFNetwork) ATS failed system trust 2023-01-13 00:45:51.139413+0700 0x348f4 Error   0x0        7633 0 pas: (CFNetwork) Connection 132: system TLS Trust eva luation failed(-9802) 2023-01-13 00:45:51.139432+0700 0x348f4 Default  0x0        7633 0 pas: (CFNetwork) Connection 132: TLS Trust result -98 02 2023-01-13 00:45:51.139450+0700 0x348f4 Error   0x0        7633 0 pas: (CFNetwork) Connection 132: TLS Trust encountere d error 3:-9802 2023-01-13 00:45:51.139467+0700 0x348f4 Error   0x0        7633 0 pas: (CFNetwork) Connection 132: encountered error(3: -9802) 2023-01-13 00:45:51.139488+0700 0x348f4 Default  0x0        7633 0 pas: (CFNetwork) Connection 132: cleaning up 2023-01-13 00:45:51.139508+0700 0x348f4 Default  0x0        7633 0 pas: (CFNetwork) [com.apple.CFNetwork:Summary] Connec tion 132: summary for unused connection {protocol=“(null)“, domain_lookup_duration_ms=0, connect_duration_ms=0, secure_connection_duration_ms=0 , private_relay=false, idle_duration_ms=0} I also tried to connect the same URL from various browsers, and it passed those security checks... How can I figure out what is the problem here? I made sure that the server certificate is set to trusted on system keychain, and my process is running in elevated user mode. I know how to disable this check, but I prefer to understand exactly what It means and fix the certificate chain if needed. thanks
1
0
2.1k
Jan ’23
macOS installer skipping new packet due to old version, but still performs scripts
Hi, I've built an installation package (file with .pkg suffix). when I double click the pkg file whereas newer version of the package is already installed, then the installer skip the downgrade process due to the following reason. 2023-02-22 20:19:11+02 my-Mac installd[744]: PackageKit: Skipping component “com.myapp.mycompany” (22.9.0-2209.0.0-*) because the version 23.2.3559-2302.3559.11638-* is already installed at /Applications/myapp.app. However, I still see that the preinstall and postinstall script being executed. Perhaps there's a way to either enable the downgrade, or disable it completely, so I won't get this partial install scenario. Is there a way I can get indication that the installer has skipped the file copying of the target pkg, from within the post/pre install scripts (so I can handle it properly) ?
1
1
1.1k
Feb ’23
codesign fails due to timestamp issue - server probably down
I'm signing using "Developer ID Application" and it suddenly started failing due to the following reason A timestamp was expected but was not found.. from the logs it looks like a failure to connect Apple's dedicated server. Perhaps there's a way to verify this theory, or get another timestamp server to be set in --timestamp option? thanks 2023-04-24 15:53:38.977560+0300 0x2e29ef5 Error 0x0 696 0 XPCTimeStampingService: (CFNetwork) NSURLConnection finished with error - code -1001 2023-04-24 15:53:38.977753+0300 0x2e29ef5 Default 0x0 696 0 XPCTimeStampingService: (CFNetwork) [com.apple.CFNetwork:Summary] Task <42F5893A-941A-4293-BB14-F75C42363836>.<0> summary for task failure {transaction_duration_ms=15792, response_status=-1, connection=817, reused=1, request_start_ms=0, request_duration_ms=0, response_start_ms=0, response_duration_ms=0, request_bytes=0, response_bytes=0, cache_hit=false}
1
0
1.3k
Apr ’23
How to make my daemon run only in pre login mode.
Hi, I'd like to be able to run my daemon process only in pre-logon mode that can be reach by either reboot the machine prior to provide user credentials, or by log out from current user. So far I couldn't find any useful configuration in the plist file under /Library/LaunchDaemon. Perhaps there's a way to get notification programmatically for when the system enter/exit pre-login mode ? Thanks
1
0
512
Sep ’24
Load network/security extension skip the finish callback
Hi, i'm working on an endpoint security extension loader and implement several callbacks from delegate object OSSystemExtensionRequestDelegate the callback i'm interested in is : public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result); public func requestNeedsUserApproval(_ request: OSSystemExtensionRequest); I've noticed that if I manually approve the extension long time after it was activated, the extension process goes up, but the callback isn't being called. The requestNeedUserApproval callback always gets called. I see in the unified logs that when the extension goes from activated_waiting_for_user -> activated_enabling -> activated_enabled Than the request callback doesn't get called. But whenever the extension goes activated_waiting_for_user -> activated_disabled The request callback gets called. (this is counter intuitive since we expected the state activated_disabled may hint that the extension failed to be activated somehow) Any Idea why my callback doesn't gets called if the extension gets approved long after it was activated ?
1
0
424
Dec ’24
Getting connection settings from method handleNewUDPFlow
I'm using NETransparentProxyProvider to intercept udp sockets using the method handleNewUDPFlow. An application may create a UDP socket and set the DONTFRAG using setsockopt method setsockopt(s, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val)) In this case, do I have option in this case, to get the connection settings inside the callback (void)handleNewUDPFlow:(NEAppProxyUDPFlow *)flow initialRemoteEndpoint:(NWEndpoint *)remoteEndpoint; So in this case, I would be able to create the outgoing socket with the exact same characteristics, after the original app socket got intercepted by my proxy provider ?
1
0
371
Feb ’25
NEPacketTunnelProvider performance issues
Following previous question here :https://developer.apple.com/forums/thread/801397, I've decided to move my VPN implementation using NEPacketTunnelProvider on a dedicated networkExtension. My extension receives packets using readPacketsWithCompletionHandler and forwards them immediately to a daemon through a shared memory ring buffer with Mach port signaling. The daemon then encapsulates the packets with our VPN protocol and sends them over a UDP socket. I'm seeing significant throughput degradation, much higher than the tunnel overhead itself. On our side, the IPC path supports parallel handling, but I'm not not sure whether the provider has any internal limitation that prevents packets from being processed in parallel. The tunnel protocol requires packet ordering, but preparation can be done in parallel if the provider allows it. Is there any inherent constraint in NEPacketTunnelProvider that prevents concurrent packet handling, or any recommended approach to improve throughput in this model? For comparison, when I create a utun interface manually with ifconfig and route traffic through it, I observe performance that is about four times faster.
1
0
79
3w
launchDaemon choose shared file location that doesn't require full disk access
I've got an mach-o executable that runs from launchDaemon plist file, and is communicating with other processes using unix domain socket. The file that backs this socket created in /tmp. However, this cause the executable to fail reading the file unless given full disk access. I'd like to find a location for the socket file, which is shared to all processes and doesn't require full disk access. the executable reside in /Library/Application Support/myProj/bin/exec_file is there such location ? Perhaps can i use the same location of the executable itself ?
2
0
850
Sep ’21
SwiftUI using .tag in picker doesn’t work on ForEach generated items
I've got an array of strings that I want to present using swiftUI Picker widget. Each string is composed of multiple words delimited by spaces. I'd like to get the Picker showing the full string of each item in the list, while the selection variable should only get the first word (the selected item is stored in arg) This was my attempt to do so. notice that the object that hold the items called myHandler, and it's shared to the swiftUI view, and can be modified by external swift closure: class myHandler: ObservableObject { @Published var items = [String]() } struct ContentView: View { @State var arg: String = "" @ObservedObject var handler : myHandler ... VStack { Picker("items", selection: $arg) { Text("AAA").tag("xxx") Text("BBB").tag("yyy") Text("CCC").tag("zzz") ForEach(handler.items , id: \.self, content: { Text($0).tag($0.components(separatedBy: " ")[0]) }) } } .frame() TextField("firstword", text: $arg).frame() For the options outside the ForEach statement, I can see that arg get the value written in the tag. However, for all options that derived from the ForEach, I see that arg equals to the iterable item ($0) which is the multi work string, and not to the first word as expected. Any idea how to fix those items that are generated from the ForEach, so that selection of such item, will set the arg to the string value of the first word in the iterator ?
2
0
3.0k
Feb ’22
Network extension crash during process startup.
Hi, I've developed network extension that is being loaded from container application. Currently, i'd like to test the extension using development profile in signature. I've implemented 4 providers inside the extension, each derived from NE basic class. here are the definitions of my providers : @interface myAppProxyProvider : NEAppProxyProvider @interface myFilterDataProvider : NEFilterDataProvider @interface myFilterPacketProvider : NEFilterPacketProvider @interface myDnsProxyProvider : NEDNSProxyProvider and added them in the Info.plist accordingly: <key>NetworkExtension</key> <dict> <key>NEMachServiceName</key> <string>MY_TEAM_ID.com.myBrand.ext</string> <key>NEProviderClasses</key> <dict> <key>com.apple.networkextension.app-proxy</key> <string>myAppProxyProvider</string> <key>com.apple.networkextension.dns-proxy</key> <string>myDnsProxyProvider</string> <key>com.apple.networkextension.filter-data</key> <string>myFilterDataProvider</string> <key>com.apple.networkextension.filter-packet</key> <string>myFilterPacketProvider</string> </dict> </dict> I also gave the extension proper entitlements, that my developer provision profile supports. <dict> <key>com.apple.application-identifier</key> <string>MY_TEAM_ID.com.myBrand.ext</string> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider</string> <string>content-filter-provider</string> <string>packet-tunnel-provider</string> <string>dns-proxy</string> <string> </array> <key>com.apple.developer.team-identifier</key> <string>MY_TEAM_ID</string> <key>com.apple.security.application-groups</key> <array> <string>MY_TEAM_ID.myGroup.com</string> </array> <key>com.apple.security.network.client</key> <true/> <key>com.apple.security.network.server</key> <true/> </dict> First, I activate the extension from the container app, so it set to [activated enabled] Then, In order to spawn the xpc client process, I start the xpc connection from the container application. but the process gets immediate exception and crash right after startup for the following reason : System Integrity Protection: enabledCrashed Thread:       0 Dispatch queue: com.apple.main-threadException Type:       EXC_BREAKPOINT (SIGTRAP) Exception Codes:      0x0000000000000001, 0x00000001aab620f8 Exception Note:       EXC_CORPSE_NOTIFYTermination Reason:   Namespace SIGNAL, Code 5 Trace/BPT trap: 5 Terminating Process:  exc handler [1268]Application Specific Information: Configuration error: Couldn’t retrieve XPCService dictionary from service bundle. The problem may hint wrong configuration of the Info.plist, no ? Any idea what can lead to this ? Thanks
2
0
1.2k
Aug ’22
Mixing NEDNSProxyProvider and NEAppProxyProvider create problems sending DNS requests
Hi, I'm using 2 separated providers, each derived from dns and application providers respectively. in the application provider I use the object NETunnelNetworkSettings as input in method to setTunnelNetworkSettings to catch all network data originated from some specific applications (including dns packets). in the dns provider I'd like to catch all dns traffic in general disregarding any specific application where the request was originated from. in my experiment, If I avoid setting the DNS server addresses in DNSSettings inside NETunnelNetworkSettings, than all DNS originated from the specific application I set using the app proxy tunnel, will be destined to address 10.0.0.10 by default (and not the default DNS address). However, If I do set this DNSSettings value, I get the following block (in my example I set the app proxy to catch the traffic of zoom.us application) 2023-04-19 11:34:45.493033+0300 0x1206 Default 0x0 501 0 mDNSResponder: [com.apple.mDNSResponder:Default] [Q36288] ShouldSuppressUnicastQuery: Query suppressed for zoom.us. Addr (blocked by policy) 2023-04-19 11:34:45.493582+0300 0x1206 Default 0x0 501 0 mDNSResponder: [com.apple.mDNSResponder:Default] [Q14787] ShouldSuppressUnicastQuery: Query suppressed for zoom.us. AAAA (blocked by policy) my desire is to catch the application connections using the app proxy provider, and leave the dns requests/responses for the dns proxy provider. I know this might not be the best approach, but perhaps there's a way to "tell" my application proxy provider to "ignore" DNS packets on udp connection, and let the DNS proxy handle it (without getting blocked by policy error, which happen before the packet reaches any of the proxy providers.) thanks !
2
0
959
Apr ’23
MTU cache doesn't gets updated when PMTU is set.
HI, I've created a virtual interface that used to get all outgoing packets, encapsulate with some VPN header, before resend them to their final destination through the physical adapter. In order to choose the optimal MTU size that won't trigger fragmentation, I'd like to calculate the PMTU between the physical interface and the destination, subtracted by the encapsulation header size. Then I'll set the virtual adapter's MTU with this result. In order to do so, I poll the overall MTU cache using sysctl on macOS. First, I verified that path mtu discovery is set sysctl net.inet.tcp.path_mtu_discovery net.inet.tcp.path_mtu_discovery: 1 Then, I tried to extract the cached pmtu for the gateway from the other size of the tunnel using the routing table . static constexpr auto kSysctlMibLength = 6; void get_pmtu_cache() { std::map<std::string, std::uint32_t> res; size_t size_needed = 0; std::vector<char> route_table; std::array<int, kSysctlMibLength> mib; char *next = nullptr; char *lim = nullptr; struct rt_msghdr *rtm = nullptr; struct sockaddr *saddr = nullptr; struct sockaddr_in *sockin = nullptr; char dest_ip_address[INET6_ADDRSTRLEN]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; // stage 1 : get the routing table // get routing table size if (sysctl(mib.data(), kSysctlMibLength, nullptr, &size_needed, nullptr, 0) < 0) { return; } // allocate local var according to size route_table.reserve(size_needed); // get routing table contents if (sysctl(mib.data(), kSysctlMibLength, route_table.data(), &size_needed, nullptr, 0) < 0) { return; } In the next step, I simple iterate the routing table elements and extract the following field for each destination : rt_msghdr.rt_metrics.rmx_mtu which is the path MTU from current endpoint to dest address. lim = route_table.data() + size_needed; for (next = route_table.data(); next < lim; next += rtm->rtm_msglen) { rtm = reinterpret_cast<struct rt_msghdr *>(next); saddr = reinterpret_cast<struct sockaddr *>(rtm + 1); if ((rtm->rtm_addrs & RTA_DST) != 0) { sockin = reinterpret_cast<struct sockaddr_in *>(saddr); if (nullptr == inet_ntop(saddr->sa_family, &sockin->sin_addr.s_addr, dest_ip_address,INET6_ADDRSTRLEN)) { continue; } const std::string dest_ip_address_str(dest_ip_address, strlen(dest_ip_address)); auto iter = res.find(dest_ip_address_str); if (iter == res.end() || iter->second > rtm->rtm_rmx.rmx_mtu) { res.insert_or_assign(dest_ip_address_str, rtm->rtm_rmx.rmx_mtu); } } } when I finally print all the values in res I see that my pmtu to my VPN server is 1500, even-though I've set the server's mtu size to 1000, and I check that ping -D -s 1500 <server> doesn't work since packets from size 1500 that cannot be fragmanted won't work. auto item = res.find(vpn_server_address); if (item == res.cend()) { printf("no pmtu found to %s\n", vpn_server_address ); return; } ret = item->second; I've tried to trigger the pmtu discovery to the VPN server using nscurl by sending https requests there, but the pmtu still remained on 1500. Perhaps I'm missing something ? do I extract the pmtu correctly ? do I trigger the pmtu discovery by sending https messages using nscurl which is based on NSURLSession ? Thanks !
2
0
987
Aug ’23