0

I want to use the XPC technology simply to launch an app. I do not need any interprocess communication, or any of the other feature of XPC.

The only documents that I can find on the internet show a complex structure, with code for the XPC service, separate code to launch the XPC service via a script, and app code to communicate with the service.

In other words, I only want something that does the equivalent of this:

NSWorkspace.shared.openApplication(at: path,
                                   configuration: configuration,
                                   completionHandler: nil)

but with XPC. So I would need something along the lines of:

let listener = NSXPCListener.service("/path/to/my_app.app")
listener.resume()
RunLoop.main.run()

Obviously, the service method does not take an argument that would be an executable path, so this does not work.

How can I do that ?

PS: to explain the motivation, launching an XPC service will preserve sandbox restriction form the launching app, whereas launching the app directly via NSWorkspace.shared.openApplication will not preserve sandbox restrictions (because the spawned app does not have "com.apple.security.inherit" as entitlement).

DevShark
  • 8,558
  • 9
  • 32
  • 56
  • The documentation for [NSTask](https://developer.apple.com/documentation/foundation/nstask) says "In a sandboxed application, child processes created with the NSTask class inherit the sandbox of the parent app". Does that achieve what you want more simply? – TheNextman Dec 19 '19 at 17:52
  • Thanks @TheNextman, it's a great idea. I just tried. Only problem now is that the sandboxed launcher app refuses to run the third party app. This third party app is signed with a different codesign (since it came from the app store), so that might be the issue... Not sure. – DevShark Dec 19 '19 at 19:00
  • I managed to make it work, but very unfortunately, the launched app is actually still not sandboxed. I tried with Safari for example, and I can still browse the internet... – DevShark Dec 19 '19 at 19:18
  • What is the app you are trying to launch? Is it sandboxed? What are its entitlements? – TheNextman Dec 19 '19 at 23:31
  • I tried with a few different things. I built an empty app, and tried different entitlements. For example, only the Sandbox entitlement. I’ve also tried with Safari. – DevShark Dec 20 '19 at 07:57
  • Did you read "Enabling App Sandbox Inheritance" on [this page](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html)? "To enable sandbox inheritance, a child target must use exactly two App Sandbox entitlement keys: com.apple.security.app-sandbox and com.apple.security.inherit. If you specify any other App Sandbox entitlement, the system aborts the child process. You can, however, confer other capabilities to a child process by way of iCloud and notification entitlements." – TheNextman Dec 20 '19 at 16:24
  • Thanks a lot, yes I just read that actually. I think that means I cannot launch any app that do not have exactly these 2 entitlements, and therefore I can’t launch appstore apps... do you have any idea for a work around ? – DevShark Dec 20 '19 at 16:38
  • The question feels like an XY problem. What are you actually trying to achieve? You just want to launch a Mac App Store app programmatically? – TheNextman Dec 20 '19 at 17:03
  • My goal is to launch a third party app from the appstore, in a sandbox. That way, it can’t use tracker or perform activities that I have no need for. It’s basically the function of the deprecated “sandbox-exec” – DevShark Dec 20 '19 at 17:12
  • Right, but an App Store app is already sandboxed. So you are trying to override the entitlements it has? I know `sandbox-exec` is deprecated, but does it do what you want? – TheNextman Dec 20 '19 at 17:18
  • Yes, the app from the app store is already sandboxed, but has permissions too wide. So I want to start it in an encompassing sandbox to restrict it further. sandbox-exec does not work unfortunately on catalina. – DevShark Dec 20 '19 at 17:48
  • `sandbox-exec` *does* work on Catalina; I just tried it. But I don't think it allows you to override the sandbox of an already sandboxed app. I'm happy to be proven wrong, but I don't think what you want to achieve is possible. – TheNextman Dec 20 '19 at 18:08
  • Ah really ? On my end, this command fails : "sandbox-exec -f sandbox_profile.sb /Applications/Safari.app" – DevShark Dec 20 '19 at 18:11
  • Ah actually, sandbox-exec works for non sandboxed app. That's probably what you meant. It does not work with Safari because Safari is already sandbox. I don't know if there's a way to "increase" the sandbox restrictions of a third party app... – DevShark Dec 20 '19 at 18:20
  • Yes, that's what I meant. Safari is already sandboxed: 'codesign -d --entitlements :- /Applications/Safari.app | grep -i "com.apple.security.app-sandbox" -A 1' – TheNextman Dec 20 '19 at 18:20
  • Yep, you're right. I'm a bit short of ideas at that point... It feels though that it should be doable, but I'm not sure how. – DevShark Dec 20 '19 at 18:21
  • The protections are probably just to prevent you from altering the sandboxing restrictions, full-stop. All I can think is that you can modify the target to remove the sandboxing entitlement, re-code sign it using an ad hoc identity, and then run it using sandbox-exec (or NSTask, etc) – TheNextman Dec 20 '19 at 18:22
  • That sounds like a great option, but is that possible? Can I really remove entitlements of a third party app? – DevShark Dec 20 '19 at 18:32
  • https://stackoverflow.com/questions/7018354/remove-sandboxing – TheNextman Dec 20 '19 at 18:44
  • Thanks a lot! That looks very promising, I'll look into that. – DevShark Dec 20 '19 at 18:48
  • Amazing, that worked ! Thanks a lot @TheNextman! You definitely deserved some points on this, so I upvoted some other responses you made, since you didn't have a response on my question. – DevShark Dec 20 '19 at 23:42
  • can you answer https://stackoverflow.com/questions/69297472/simplest-client-server-example-code-using-ipc-using-xpc-using-swift-on-macos – Alok Sep 23 '21 at 10:07

1 Answers1

1

It does not seem possible to launch a sub process while altering it's sandbox (i.e. giving it more or less entitlements than it was originally blessed with).

I recommend stripping the sandboxing from the existing application, modifying the entitlements appropriately and then re-signing it. It's not a regular approach but would solve your specific issue.

TheNextman
  • 12,428
  • 2
  • 36
  • 75