trilemma-dev/SecureXPC

SMAppService and MachServiceCriteria

Closed this issue ยท 12 comments

rurza commented

Hey!
First of all, AMAZING work!
I'm trying to use the framework to talk with a daemon launched by the new SMAppService api. The daemon launches, launches server but I can't make it to talk with the client. It fails on the first condition. But...
I'm not sure that validateThisProcessIsAnSMAppServiceDaemon should work at all. It checks for the Bundles bundleURL and it assumes that it'll receive a path with the Contents folder. It doesn't work in my case, it returns a path, but to the bundle itself (so the last component is *.app). Am I doing something wrong?

private func validateThisProcessIsAnSMAppServiceDaemon() -> ValidationResult {

Thanks for opening this issue, I'll take a look this weekend.

rurza commented

@jakaplan I have a fork that "works". Please take a look :)

I don't see anything immediately wrong with the code as it currently exists. Could you provide me with the error message that's associated with the XPCError.misconfiguredServer error? (If you don't currently have a good way of getting access to this, the easiest is using NSLog(...) and looking for the result in Console.app)


It checks for the Bundles bundleURL and it assumes that it'll receive a path with the Contents folder.

It validates that the daemon or agent is located within its parent's application bundle. This means a Contents folder must exist in its path.

It doesn't work in my case, it returns a path, but to the bundle itself (so the last component is *.app).

When you "it returns a path" what is "it" referring to?

Am I doing something wrong?

Possibly. Are you creating the XPCServer in the daemon? And where is the daemon located within the parent app's directory structure?

@jakaplan I have a fork that "works". Please take a look :)

I took a look, but don't understand them. Are you trying to run the XPCServer from within the app as opposed to the daemon?

rurza commented

@jakaplan

It validates that the daemon or agent is located within its parent's application bundle. This means a Contents folder must exist in its path.
I don't see anything immediately wrong with the code as it currently exists. Could you provide me with the error message that's associated with the XPCError.misconfiguredServer error? (If you don't currently have a good way of getting access to this, the easiest is using NSLog(...) and looking for the result in Console.app)

I'm getting XPCError.misconfiguredServer(description: "This server does not have a parent bundle.\n" "Path components: \(components)") error. Despite the fact that both binaries (the app โ€“ client, and the server, mach service which is a product of Xcode's "Command line tool" template) are in the same bundle. Maybe that's the issue โ€“ is it expecting a bundle in the bundle?

Is it literally logging "Path components: \(components)"? When I asked what the error was I wanted to see what the components value was.

A command line tool should work. Can you confirm you're using XPCServer inside of the command line tool?

Also wanted to let you know I'm committed to working through this issue, but it might take a bit of time to communicate back and forth as we're far apart timezone wise: I'm in UTC+12 and it looks like you're in UTC+2.

rurza commented

Hey! :)
Time difference isn't a problem โ€“ we have a public holidays in Poland right now and my time spent on coding is limited :)
But a big thank for your help!
My project is open source and you can check out two branches:
https://github.com/rurza/BatFi/tree/SecureXPC-sameTeamIdentifier
https://github.com/rurza/BatFi/tree/SecureXPC-sameBundle

The error I'm having with the sameBundle criteria is thrown by the server and it's:

SecureXPC.XPCError.misconfiguredServer(description: "This server does not have a parent bundle.\nPath components: [\"/\", \"Users\", \"rurza\", \"Library\", \"Developer\", \"Xcode\", \"DerivedData\", \"BatFi-hkjasvdzzboyvufdpvzqvkhemujc\", \"Build\", \"Products\", \"Debug\", \"BatFi.app\"]"

For the same teamIdentifier I'm getting:

SecureXPC.XPCError.misconfiguredServer(description: "An SMAppService daemon must have a property list within its parent bundle\'s Contents/Library/LaunchDaemons /\ndirectory.")
rurza commented

Why do I need XPC? I need to run privileged process to make some changes in Apple's SMC. That's all. So ideally I would need to:
โ€“ launch the privileged helper, run the command, quit the helper
โ€“ not have to worry about updating the helper tool. Sure, I would like to have the guarantee that messages are coming from my client, but ideally I would always open the latest helper. That's why I need the launch and quit scenario.

I now understand what's going wrong for you and why your PR did not make sense to me. Thank you for pointing me at your entire Xcode project, I would not have been able to figure this out otherwise!

The root cause of the issue is that my code is expecting Bundle.main.bundleURL to return a path to the directory containing the executable running the XPCServer and this is in fact what it does in my own test setups which located the daemon (or agent) in <App Name>.app/Contents/Resources/ directory in the app's bundle. Apparently when the daemon is located in the <App Name>.app/Contents/MacOS/ directory (as your Xcode project does) instead of returning a path to the executable it returns a path to the containing <App Name>.app.

I will look for an alternate API that behaves consistently to fix this issue and then put up a PR.

@rurza Could you take a look at #132 and confirm it works for you? I'm pretty sure it will as I tested it against BatFi, but since I'm not 100% sure how your app and helper tool are supposed to behave, you testing directly against this branch would be appreciated.

rurza commented

@jakaplan Everything is tip-top :)