From 65af850a3bcc2beb2657f3e6096afe7bfd0545fd Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Sat, 18 Jan 2025 11:22:22 -0500 Subject: [PATCH 1/2] Detect bless from sandbox --- Sources/Blessed/BlessError.swift | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) mode change 100644 => 100755 Sources/Blessed/BlessError.swift diff --git a/Sources/Blessed/BlessError.swift b/Sources/Blessed/BlessError.swift old mode 100644 new mode 100755 index 5b5517b..507d86a --- a/Sources/Blessed/BlessError.swift +++ b/Sources/Blessed/BlessError.swift @@ -38,7 +38,8 @@ public struct BlessError: Error { toolAssessor.infoPropertyListAuthorizedClients(type: .bundled), // 7 & 8 - bundled toolAssessor.infoPropertyListAuthorizedClients(type: .installed), // 7 & 8 - bundled toolAssessor.infoPropertyListBundleVersion(), // 9 - appAssessor.infoPropertyList(bundledHelperToolLocation: toolAssessor.bundledLocation, label: label) // 10 + appAssessor.infoPropertyList(bundledHelperToolLocation: toolAssessor.bundledLocation, label: label), // 10 + appAssessor.isNotSandboxed(), // 11 ] } } @@ -528,4 +529,20 @@ fileprivate struct AppAssessor { """) } } + + // 11 + func isNotSandboxed() -> Assessment { + if ProcessInfo.processInfo.isSandboxed { + // XPC services are usually found in a path like ".../MyApp.app/Contents/XPCServices/Bar.xpc/Contents/MacOS/MyService" + let isXPCService = Bundle.main.executableURL?.deletingLastPathComponent().path.hasSuffix(".xpc/Contents/MacOS") ?? false + let programType = isXPCService ? "XPC service" : "App" + + return .notSatisfied(explanation: """ + This \(programType) is sandboxed, which will cause SMJobBless() to always get denied. + Helper tools can only be blessed from a non-sandboxed \(programType). + """) + } + + return .satisfied + } } From f093073604f6984658c5b77824273cbeb5d16e55 Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Sat, 18 Jan 2025 11:32:33 -0500 Subject: [PATCH 2/2] Remove redundant type-check --- Sources/Blessed/ProcessInfo+Sandbox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Blessed/ProcessInfo+Sandbox.swift b/Sources/Blessed/ProcessInfo+Sandbox.swift index c86d778..7972653 100644 --- a/Sources/Blessed/ProcessInfo+Sandbox.swift +++ b/Sources/Blessed/ProcessInfo+Sandbox.swift @@ -28,7 +28,7 @@ extension ProcessInfo { return false } - guard CFGetTypeID(entitlement) == CFBooleanGetTypeID(), let boolValue = (entitlement as? Bool) else { + guard let boolValue = entitlement as? Bool else { // The entitlement value must be a boolean value. If it's not, then it's presumbly not sandboxed. return false }