Hi everyone :)
I'm exploring XPC these days; more specifically, I'm trying to establish a connection between a macOS application and an XPC service. I succeeded in establishing the connection, but now I'm trying to verify the incoming connection by using SecCodeCopyGuestWithAttributes, passing it an audit token.
But I got the following error:
2024-01-18 10:43:06.805435+0100 DemoService[1627:7118397] [logging-persist] cannot open file at line 46922 of [554764a6e7]
2024-01-18 10:43:06.805452+0100 DemoService[1627:7118397] [logging-persist] os_unix.c:46922: (0) open(/private/var/db/DetachedSignatures) - Undefined error: 0
Cannot get SecCode: 100001 - UNIX[Operation not permitted]
Audit token: Optional(32 bytes)
The last two lines come from my code:
class XPCClientValidator {
var secCodeOptional: SecCode? = nil;
func identifyGuest(for connection: NSXPCConnection) -> Bool {
let auditToken = AuditToken.extractToken(from: connection)
let hostSecCode: SecCode? = nil; // This is a way to indicate that the code signing root of trust hould be used as host.
let attributes = [ kSecGuestAttributeAudit: auditToken ] as CFDictionary
let secFlags = SecCSFlags(rawValue: 0)
// Asks a code host to identify the guest given the audit token
let status: OSStatus = SecCodeCopyGuestWithAttributes(hostSecCode, attributes, secFlags, &self.secCodeOptional)
if (status != errSecSuccess) {
let msg = SecCopyErrorMessageString(status, nil)!
print("Cannot get SecCode: \(status) - \(msg)")
print("Audit token: \(String(describing: auditToken))")
return false
}
guard let _ = secCodeOptional else {
NSLog("Couldn't unwrap the secCode")
return false
}
return true
}
}
I saw a few posts on the forum, but nothing helped me to solve this issue.
The complete source code is here: https://github.com/tony-go/XPCDemo/tree/secure-xpc
Note: If you want to reproduce it, you have to:
- start the app
- type a random input
- click on "uppercase it"
now I'm trying to verify the incoming connection by using
SecCodeCopyGuestWithAttributes
To what end?
If you’re building an XPC service that’s embedded within your app, its named XPC endpoint is only exported in your app’s namespace. Thus, only your app can connect to it. Doing an extra level of checking is pointless.
If your named XPC endpoint is available elsewhere, say you’re building a launchd
agent, or you just want to add some pointless extra code (-; your best option is to do this declaratively, by configuring your XPC listener with a code signing requirement. See Validating Signature Of XPC Process.
Is it acceptable to remove the sandbox for an XPC service?
In general, yes. If you plan to deploy via the Mac App Store, then no.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"