SMJobBless to sudo install HAL Plugin

In an installer-free, non MAS mac app, I need to let the user do the equivalent of

sudo (cp MyAudioDriver.driver /Library/Audio/Plug-Ins/HAL/ && killall coreaudiod)


so they request the installation of the optional component, see the standard “[App X] wants to make changes, enter a password to continue” and the above happens with elevated privileges.


After looking at the sample code `SMJobBless`, `BetterAuthorizationSample` and `EvenBetterAuthorizationSample` (we don’t talk about plain `AuthorizationSample` any more), the picture that I’m getting is that the solution is a mixture of


1. use SMJobBless to install privileged helper app managed by launchd (this - hopefully - can do the one-liner above)

2. code signing & (mutual?) whitelist to establish trust between app and helper

3. XPC for communication between helper and app (hi, this is the app, please install the thing)


This seems so complicated, is this really the way to do what I want in a non-deprecated fashion? The client justifiably points out that requesting elevated permissions for Accessibility scripting is very easy, but there’s a dedicated API for that.


I got the SMJobBless sample code working, and confusingly, its security dialog says “[App X] wants to install a helper app, enter password” which is not the message I want to give, so hopefully there’s some plist customisation somewhere where I can say “[App X] wants to install an audio component”.


Am I on the right path?


I have many doubts and questions


  • XPC to a privileged app is apparently not supported (mentioned here: http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/)
  • can I shell out to the one liner script? it's codesigned...
  • aren't helper apps supposed to be long running?
  • every other app seems to have the "[App X] wants to make changes" dialog. Does that mean they're using the deprecated AuthorizationExecuteWithPrivileges()? or are they asking AppleScript to run a shell script with elevated privileges?
  • the calling app is not a bundle, it's just a binary/CLI tool, that acts as a plug-in for an electron .app package/bundle. can the CLI tool communicate with the helper?
  • I'm no security expert, but having a helper app/server running as root & performing commands (in this case file copies to directories owned by root) on behalf of my app seems kinda... insecure.

Replies

The idea is that the helper app is more secure because all it can do, in theory, is copy this one file to that one location.


Unfortunately, there is no good answer here.


Clearly, Apple wants to discourage apps from running as root. In some future macOS update, it seems likely that this will be enforced, much like iOS today. By the same token, I can't imagine that Apple is all too interested in supporting 3rd party audio plugins. I always tell people, "how would you accomplish the same task on iOS today?" If the answer is laughter, then you are in a high risk line of development.


Given that your product may very well be summarily terminated within 3 weeks - 3 years, how much do you really care about doing it all the "right" way? My suggestion is to implement it using the best API that works, regardless of deprecation status. At the same time, implement a fallback method using command-line AppleScript. Test your installer with each and every macOS beta build. That's pretty much all you can do, isn't it?


If all that falls apart in early June anyway, wrap your product inside an installer package that runs as root to begin with. Problem solved until 3rd party audio drivers get deprecated altogether.

I’m happy to answer all of your detailed questions but, before we go down that rabbit whole, I think we should talk about the big picture. Ultimately what you’re building here is an installer. There are three basic approaches you can use:

  • An installer package, to be installed by the Apple installer (A)

  • AuthorizationExecuteWithPrivileges
    (AEWP) (B)
  • The

    SMJobBless
    process, as illustrated by EvenBetterAuthorizationSample (EBAS) (C)

You seem to have not considered A, which is a shame because IMO that’s the best option for you. B and C both have problems, and I think it’s important that you understand those problems are before you pick an approach.

The problem with B is that it’s deeply insecure. Specifically, it’s highly vulnerable to impersonation: AEWP has no ability to determine whether the tool it runs is the tool that the user authorised to run. This fundamental brokenness is the reason why AEWP was deprecated.

The problem with C is that it’s complex. When using C to implement an installer, you have to… well… implement an installer. It’s a specialist installer, but it’s an installer nevertheless.

The best way to think about this is that you’re not running a one-off installation, but installing an entire system for managing the installation of your product, now and in the future.

SMJobBless
is used solely to bootstrap your privileges. After that, you are responsible for how you use those privileges to achieve your installer’s goals (typically those would be install, upgrade, and uninstall). The system provides all the infrastructure for doing this, you just have to write the code to use it properly.

Ultimately this is a decision that you have to make, balancing a bunch of different requirements (time to write the code, desired UI, complexity, security, long-term compatibility, and so on). Given your description of your requirements I think that approach A is the right one for you, but only you have all the information needed to make this choice.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Quinn! Thanks for the response, I must have not had email updates on because I missed these answers, and I sort of forgot about the whole thing because the question was moderated for days, due I think to the blog link that I put into the question, so I won't do that again.


I did consider and recommend your option (A) to the client as the simplest and best supported solution, but they ruled it out due to the extra clicks/friction. (C) was rejected due to time constraints and complexity. I also presented the possibility of what I guess is a variation of (B), with all its insecurity, which was an NSAppleScript "do shell script with administrator privileges" and that was accepted. I expect the next request will be to skin/theme the password dialog as best as possible (icon and intent string), so the next stop is probably AEWP, but I will repeat your security concerns as maybe I didn't emphasise that aspect enough.

Ouch. I hope audio plugins aren't going to be dumped, not after all the effort to make them sandboxable. That said, this use case isn't particularly driverly nor do I want root privileges - what I need is an audio device that passes input through to output. Maybe there's already a way to do this, or maybe Apple could provide such a driver, or maybe an API could be added.


On the other hand, if audio plugins are user space now, why doesn't coreaudio hot load them from ~/Library/Audio/Plug-Ins/HAL/ or even better, from my app bundle, like AUv3 audio units? Then I wouldn't need to escalate privileges.


Thanks for the advice, we'll be watching the 10.15 betas closely.

I have no idea what Apple plans are for the future of audio plugins. I'm just speculating based on past behaviour. It seems reasonable that future versions of macOS will simply be iOS with larger screens and different input devices. My advice to any software developer would be to focus on projects that would work in such a hypothetical system. Perhaps I'm wrong. But if I'm right, you've got nothing. If I'm wrong, you've still got a product, albeit not one involving audio plugins. Maybe consider a hardware device instead. Unfortunately, it sounds like your product could be used to facilitate bypassing copyright protection. Even if audio units are technically possible in the future, that seems like a risky project.


Otherwise, it sounds like you have already found the AppleScript solution I proposed. I don't think you will be able to skin the authorization dialog. I suggest a warning dialog that explains what is going to happen and tells the user that "osascript" is going to be asking for their password. In my app, I leverage this by explaining in this dialog how this is an Apple tool and my product never actually has access to the user's password at all.


To mitigate potential security issues, I strongly suggest that you verify your app's signature and construct an osascript command to run via a sub-process. I suppose it is still possible to hack that, but most such hacks are purely theoretical anyway. It is mostly just Security Theatre designed to push 3rd party security software. But verifying your app's signature really has no downside. It makes your app more difficult to pirate.

> Unfortunately, it sounds like your product could be used to facilitate bypassing copyright protection.


It could, but not in a very satisfying way, I guess you could create a recompressed, metadata-free 90s style mix tape in real time.

That doesn't seem so interesting in these times of ubiquitous music streaming.


I don't see a core audio protocol for DRMed output, however apps are free to refuse to output to non apple devices.

Anecdotally, Spotify Mac doesn't care, yet Spotify iOS detects and outputs plausible nonsense over IDAM...


> Even if audio units are technically possible in the future, that seems like a risky project.


I'll pass on this warning and also recommend signature checking, thanks very much!