Post

Replies

Boosts

Views

Activity

Passing NSURLCredential in XPC connection fail in decoder
Hi, I’d like to perform client-side certificate authentication from https based connection in macOS. I’m using the method didReceiveChallenge from URLSession. However, I cannot read the keychain directly since my process is running as Daemon, and my client certificate reside in login keychain. So I've followed the guidance from this question https://developer.apple.com/forums/thread/106851, and sent this authentication request to a user-based process which is running in the current user so it has access to the keychain. After I acquire the NSURLCredential object, I’d like to return it back to the Daemon, so it may run the completionHandler with that credential. However, After I successfully create the NSURLCredential in the user process, and send it back using some reply callback. It looks like the object didn’t serialized properly and I get the following error : Exception: decodeObjectForKey: Object of class "NSURLCredential" returned nil from -initWithCoder: while being decoded for key <no key> Here’s my client side code ( I made sure that the server side create a valid NSURLCredential object). and the problem occur after I send the XPC request, right when i’m about to get the callback response (reply) - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) { [myXpcService getCertIdentityWithAcceptedIssuers:challenge.protectionSpace.distinguishedNames withReply:^(NSURLCredential *cred, NSError *error) { if (error != nil) { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); } else { completionHandler(NSURLSessionAuthChallengeUseCredential, cred); } }]; } Perhaps anybody can tell me what did I do wrong here ? Does XPC is capable to pass complex objects like NSURLCredentials ? thanks !
12
0
2.9k
May ’22
Restrict access to keychain using non-standard access control policy
Hi, I'd like to allow only a specific process to read sensitive items from keychain (based on process signature using method SecItemCopyMatching), and fail any other read attempt. Is it possible, what are the access control rules I can define for keychain access if this is not possible ? I'm now using the default user keychain, perhaps I should create a different keychain with non-trivial access control, so that not all processes that are running with user context or even with root privileges, would be able to get the data. Thanks Here's my read example : func read(service: String, account: String) -> Data? { let query = [ kSecAttrService: service, kSecAttrAccount: account, kSecClass: kSecClassGenericPassword, kSecReturnData: true ] as CFDictionary var result: AnyObject? SecItemCopyMatching(query, &result) return (result as? Data) }
9
0
1.9k
May ’23
How to restore macOS routing table after VPN crash or routing changes?
Hi, I have a VPN product for macOS. When activated, it creates a virtual interface that capture all outgoing traffic for the VPN. the VPN encrypt it, and send it to the tunnel gateway. The gateway then decapsulates the packet and forwards it to the original destination. To achieve this, The vpn modifies the routing table with the following commands: # after packets were encoded with the vpn protocol, re-send them through # the physical interface /sbin/route add -host <tunnel_gateway_address_in_physical_subnet> <default_gateway> -ifp en0 > /dev/null 2>&1 # remove the default rule for en0 and replace it with scoped rule /sbin/route delete default <default_gateway> -ifp en0 > /dev/null 2>&1 /sbin/route add default <default_gateway> -ifscope en0 > /dev/null 2>&1 # create new rule for the virtual interface that will catch all packets # for the vpn /sbin/route add default <tunnel_gateway_address_in_tunnel_subnet> -ifp utunX > /dev/null 2>&1 This works in most cases. However, there are scenarios where the VPN process may crash, stop responding, or another VPN product may alter the routing table. When that happens, packets may no longer go out through the correct interface. Question: Is there a way to reliably reconstruct the routing table from scratch in such scenarios? Ideally, I would like to rebuild the baseline rules for the physical interface (e.g., en0) and then reapply the VPN-specific rules on top. Are there APIs, system utilities, or best practices in macOS for restoring the original routing configuration before reapplying custom VPN routes? Thanks
5
0
357
Sep ’25
Default Dns server is loopback although the connection provide default servers
I'm trying to understand where do I get the dns server configuration from. As I understand, if the file /etc/resolve.conf contain no servers, than it fallback to servers that are defined by the physical connection (Wi-Fi) However, once I removed all dns servers from /etc/resolve.conf, I got that my DNS is configured to the loopback address (127.0.0.1) instead of what the connection provides. nslookup > server Default server: 127.0.0.1 Address: 127.0.0.1#53 Default server: ::1 Address: ::1#53 and Here's the the default dns servers from the Wi-Fi connection: Here's what's configured by the interface : Perhaps anyone can tell me why doesn't the default DNS server is selected to 10.196.X.X as provided by the connection (instead I get the loopback address)
4
0
1.4k
Oct ’22
Using SimplePing example to send ICMP with DF flag set
Hi, I've tried to modify the simplePing example from here https://developer.apple.com/library/archive/samplecode/SimplePing/ and set the DF flag on. In my attempt, I've used setsockopt right after socket was created : fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); int val = 1; setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val)); However, from wireshark I could clearly see that the icmp packet had the DF bit unset ... Please help me figure out what's wrong in my code. Thanks !
4
0
1.7k
Aug ’23
Excessive batter drain in macOS during sleep mode.
We are experiencing abnormal battery drain during sleep on several machines that installed our product. The affected devices appear to enter and exit sleep repeatedly every few seconds, even though the system logs show no new wake request reasons or changes in wake timers. Symptoms: Battery drops ~1% every ~15–20 minutes overnight. pmset -g log shows repeated "Entering Sleep" and "Wake Requests" events every few seconds. Wake requests remain unchanged between cycles and are scheduled far into the future (i.e. 20+ minutes later), yet the log lines keep repeating. On healthy machines, the same wake request entries appear only once every 20–30 minutes as expected, with minimal battery drop during sleep (~1% in 9 hours). What we've checked: No user activity (system lid closed, device idle). No significant pmset -g assertions; only powerd and bluetoothd are holding expected PreventUserIdleSystemSleep. pmset -g on affected machines shows sleep set to 0, likely due to sleep prevented by powerd, bluetoothd. No third-party daemons are holding assertions or logging excessive activity. Sample Logs from Affected Machine: 2025-06-28 21:57:29 Sleep Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active Using Batt (Charge:76%) 3 secs 2025-06-28 21:57:31 Wake Requests [process=mDNSResponder request=Maintenance deltaSecs=7198 wakeAt=2025-06-28 23:57:29 ...] 2025-06-28 21:57:38 Sleep Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active Using Batt (Charge:76%) 3 secs 2025-06-28 21:57:40 Wake Requests [process=mDNSResponder request=Maintenance deltaSecs=7198 wakeAt=2025-06-28 23:57:38 ...] 2025-06-28 21:57:47 Sleep Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active Using Batt (Charge:75%) 3 secs 2025-06-28 21:57:49 Wake Requests [process=mDNSResponder request=Maintenance deltaSecs=7198 wakeAt=2025-06-28 23:57:47 ...] The only change in logs is the wakeAt timestamp being slightly updated . The wake requests themselves (process, type, deltaSecs) remain identical. Yet, the system keeps entering/exiting sleep every few seconds, which leads to power drain. We would appreciate your help in identifying: Why the sleep/wake cycles are repeating every few seconds on these machines. Whether this behavior is expected under certain conditions or indicates a regression or misbehavior in power management. How we can trace what exactly is triggering the repeated wake (e.g., a subsystem, implicit assertion, etc.). Whether there are unified log predicates or private logging options to further trace the root cause (e.g., process holding IO or waking CPU without explicit assertion). We can provide access to full logs, configuration profiles, and system diagnostics if needed.
4
0
195
Jul ’25
Network extensions ordering of packet filter and vpn tunnel.
Hi, I'd like to write a network extension for a vpn product, that also filter several types of packets before they arrive to the tunnel represeted by the tunnel virtual interface (utun0) Is there anyway I can set the packet filtering to occur before the tunnel ? is it the default case ? Can I use the same network extension for both NEPacketTunnelProvider and NEFilterPacketProvider / NEFilterDataProvider ? thanks !
3
0
1.4k
Jun ’21
Using NSURLSession to create webSocket that can receive async messages from server.
Hi, I've got an object from type NSURLSessionWebSocketTask from which I create webSocket. However, currently it can only receive responses as can be seen here:    NSURLSessionWebSocketMessage * msg = [[NSURLSessionWebSocketMessage alloc] initWithString:myStringBody;   [socketConnection sendMessage:msg completionHandler: ^(NSError * e) {     if (e == nil) {       [socketConnection receiveMessageWithCompletionHandler:^(NSURLSessionWebSocketMessage * _Nullable message, NSError * _Nullable error) {        NSLog(@"got message = %@", message.string);       }];   }]; I'd like to be able to receive messages from server that wasn't triggered from client request (messages that initiated by the server). Ideally, i wish to get them in some sort of queue (maybe NSOperationQueue or dispatch queue). But the bottomline should be that some listener would work in the background. Perhaps there's some delegate to implement this requirement ?
3
0
1.5k
Jun ’21
File upload task called from launchAgent process sometimes take too long.
Hi, I'm working on macOS launchAgent based project, and using 3rd party code to upload big files to remote server. from time to time, I see that the upload rate is very slow and when i try it to use command line tool, the paste is much faster. Therefore, I believe that launchAgent based processes, may get low priority in using network bandwidth compared to foreground tools. I wonder if there's anything I can do on the process' info.plist file to get better prioritization on network resources. Perhaps I need to call the file uploader/downloader from dedicated XPC helper tool, but I prefer doing it from the same process. Thanks !
3
0
833
Jul ’23
Detect and thwart file copy operation using securityExtension.
For a security product, I wonder if security extension has a capability to catch a file during copy operation (I guess it's composed out of multiple basic ops like file read and file write). I'd like to store the file in some quarantined temporal (let's say when someone copy file from external file system like usb/network location and copy it back once the file has properly scanned. So far, i've used the authorization capabilities of the security extension. I wonder if there's also an option to change the target location of a file being copied ? Thanks.
3
0
877
Feb ’24
Don't fragment bit doesn't get set in Sequoia
Hi, I've noticed a weird behavior happening on Sequoia with DF bit: On machine where SIP is disabled, when I do /sbin/ping -D -s 1400 8.8.8.8 I do see the DF bit in wireshark On machine where SIP is enabled, when I do /sbin/ping -D -s 1400 8.8.8.8 I do not see the DF bit in wireshark The -D flag should set the DF bit but for some reason it doesn’t if the SIP is enabled. Perhaps there was any change in permission/entitlements mechanism in Sequoia that can explain it ? I'm using the built-in ping command so maybe it should be signed with more entitlements ?
3
0
369
Mar ’25
Creating machine identifier to be used by daemon based app
I am developing a daemon-based product that needs a cryptographic, non-spoofable proof of machine identity so a remote management server can grant permissions based on the physical machine. I was thinking to create a signing key in the Secure Enclave and use a certificate signed by that key as the machine identity. The problem is that the Secure Enclave key I can create is only accessible from user context, while my product runs as a system daemon and must not rely on user processes or launchAgents. Could you please advise on the recommended Apple-supported approaches for this use case ? Specifically, Is there a supported way for a system daemon to generate and use an unremovable Secure Enclave key during phases like the pre-logon, that doesn't have non user context (only the my application which created this key/certificate will have permission to use/delete it) If Secure Enclave access from a daemon is not supported, what Apple-recommended alternatives exist for providing a hardware-backed machine identity for system daemons? I'd rather avoid using system keychain, as its contents may be removed or used by root privileged users. The ideal solution would be that each Apple product, would come out with a non removable signing certificate, that represent the machine itself (lets say that the cetificate name use to represent the machine ID), and can be validated by verify that the root signer is "Apple Root CA"
3
0
563
Nov ’25
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