Mac: allow signed CLI + same-uid XPC clients
This commit is contained in:
@@ -458,33 +458,30 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSXPCListenerDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func isAllowed(connection: NSXPCConnection) -> Bool {
|
private func isAllowed(connection: NSXPCConnection) -> Bool {
|
||||||
// Prefer audit token (available via KVC); fall back to pid-based lookup.
|
|
||||||
if let tokenData = connection.value(forKey: "auditToken") as? Data,
|
|
||||||
tokenData.count == MemoryLayout<audit_token_t>.size {
|
|
||||||
var token = audit_token_t()
|
|
||||||
_ = withUnsafeMutableBytes(of: &token) { tokenData.copyBytes(to: $0) }
|
|
||||||
let attrs: NSDictionary = [kSecGuestAttributeAudit: tokenData]
|
|
||||||
if self.teamIDMatches(attrs: attrs) { return true }
|
|
||||||
}
|
|
||||||
|
|
||||||
let pid = connection.processIdentifier
|
let pid = connection.processIdentifier
|
||||||
guard pid > 0 else { return false }
|
guard pid > 0 else { return false }
|
||||||
|
|
||||||
|
// Same-user shortcut: allow quickly when caller uid == ours.
|
||||||
|
if let callerUID = self.uid(for: pid), callerUID == getuid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
let attrs: NSDictionary = [kSecGuestAttributePid: pid]
|
let attrs: NSDictionary = [kSecGuestAttributePid: pid]
|
||||||
if self.teamIDMatches(attrs: attrs) { return true }
|
if self.teamIDMatches(attrs: attrs) { return true }
|
||||||
|
|
||||||
// Fallback: allow same-user processes (still local-only).
|
|
||||||
var pidInfo = kinfo_proc()
|
|
||||||
var size = MemoryLayout.size(ofValue: pidInfo)
|
|
||||||
var name: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid]
|
|
||||||
let result = name.withUnsafeMutableBufferPointer { namePtr -> Bool in
|
|
||||||
return sysctl(namePtr.baseAddress, u_int(namePtr.count), &pidInfo, &size, nil, 0) == 0
|
|
||||||
}
|
|
||||||
if result, pidInfo.kp_eproc.e_ucred.cr_uid == getuid() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func uid(for pid: pid_t) -> uid_t? {
|
||||||
|
var info = kinfo_proc()
|
||||||
|
var size = MemoryLayout.size(ofValue: info)
|
||||||
|
var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid]
|
||||||
|
let ok = mib.withUnsafeMutableBufferPointer { mibPtr -> Bool in
|
||||||
|
return sysctl(mibPtr.baseAddress, u_int(mibPtr.count), &info, &size, nil, 0) == 0
|
||||||
|
}
|
||||||
|
return ok ? info.kp_eproc.e_ucred.cr_uid : nil
|
||||||
|
}
|
||||||
|
|
||||||
private func teamIDMatches(attrs: NSDictionary) -> Bool {
|
private func teamIDMatches(attrs: NSDictionary) -> Bool {
|
||||||
var secCode: SecCode?
|
var secCode: SecCode?
|
||||||
guard SecCodeCopyGuestWithAttributes(nil, attrs, SecCSFlags(), &secCode) == errSecSuccess,
|
guard SecCodeCopyGuestWithAttributes(nil, attrs, SecCSFlags(), &secCode) == errSecSuccess,
|
||||||
|
|||||||
@@ -222,6 +222,8 @@ struct ClawdisCLI {
|
|||||||
let proc = Process()
|
let proc = Process()
|
||||||
proc.launchPath = "/usr/bin/open"
|
proc.launchPath = "/usr/bin/open"
|
||||||
proc.arguments = ["-n", appURL.path]
|
proc.arguments = ["-n", appURL.path]
|
||||||
|
proc.standardOutput = Pipe()
|
||||||
|
proc.standardError = Pipe()
|
||||||
try proc.run()
|
try proc.run()
|
||||||
try? await Task.sleep(nanoseconds: 100_000_000)
|
try? await Task.sleep(nanoseconds: 100_000_000)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user