Gain administration privileges with swift for a Mac Application

眉间皱痕 提交于 2019-12-03 15:44:25

The key part of this approach is described under the "PROPERTY LISTS" section under "How It Works" of the ReadMe.txt:

[…] when you sign the helper tool with a Developer ID, Xcode automatically sets the helper tool's designated requirement like this, and that's what you should use for SMPrivilegedExecutables. Moreover, this is what the "setreq" command shown above does: extracts the designated requirement from the built tool and put it into the app's Info.plist source code.

Since you are not signing the products (at least, not with the certificate described in your examples), this process will always fail.

If you are not in the Developer Program, you can create a self-signed certificate to sign with. However, this more or less defeats the purpose of the signing requirement. If you do not plan on enrolling in the Developer Program, you should be able to abbreviate the process as follows:

  1. In your app's Info.plist, abbreviate the requirement under SMPrivilegedExecutables to just match the helper's identifier:

    <string>identifier "com.domain.AppName.SampleService"</string>

    • In your helper's Info.plist, abbreviate the requirement under SMAuthorizedClients to just match the app's identifier:

    <string>identifier "com.domain.AppName"</string>

    • Ignore the "Building and Running the Sample" instructions of the ReadMe.txt, and intead simply build and run the project as normal.

I can't say I recommend this of course; these signing requirements exist for good reason. It is at least better than the final alternative however, which would be using that NSAppleScript to give a helper executable a root setuid bit via chmod and chown.


Addendum to elaborate on some of the concepts in play here:

Running privileged code comes with a lot of potential security holes; safely authenticating the user is only the first step. Delegating all privileged operations to a separate process is another strong step, but the major issue that remains is how to ensure that your app – the one the user actually granted privileges for - is the only entity capable of utilizing the privileged access.

Apple's example demonstrates the use of code signing to solve this problem. Just in case you're not familiar: Code signing involves marking your final products cryptographically in such a way that OS X can verify your programs haven't been replaced with compromised versions. Those extra "certificate leaf" references are in the original example's SMAuthorizedClients and SMPrivilegedExecutables are specifically for this; they describe the the certificate that your app and helper must have been signed with in order to interact with one another.

To help paint the picture a bit, here's a rough rundown of how this plays out:

  1. Your user grants authorization to launchd to install the helper daemon labeled com.domain.AppName.SampleService.
  2. launchd locates the com.domain.AppName.SampleService entry under SMPrivilegedExecutables in your app's Info.plist; this describes the certificate that the helper's binary should be signed with. (If they do not match, then theoretically an attacker has replaced your helper tool with their own version in order to run it as root.)
  3. With the valid helper tool installed, your app makes a request to launchd to spawn the helper under your control. At this point, launchd consults the SMAuthorizedClients section of your helper tool's Info.plist to ensure the app actually does have the right to run the tool. And, of course, it verifies your app's signature to ensure it hasn't been tampered with.

Getting back to your scenario, the way your products are currently working is by eliminating the signing steps. The only thing you have instructed launchd to check is whether your app's Info.plist lists its ID as "com.domain.AppName". Since there's nothing stopping an attacker from changing their Info.plist to say this as well, you're banking on the hope that they couldn't use your helper tool to do any harm once they have control of it.

Additional addendum outlining the alternatives:

You are moving in right direction. Currently privileged helper tool is the best practice for executing task in privileged mode. For doing that you can use Swift too but just replace C version of functions call with Swift. (Apple has introduced alternatives in 10.11 SDK) For example instead of

Boolean SMJobBless( CFStringRef domain, CFStringRef executableLabel, AuthorizationRef auth, CFErrorRef *outError);

you can use:

SMJobBless(_: CFString!, _: CFString, _: AuthorizationRef, _: UnsafeMutablePointer<Unmanaged<CFError>?>) -> UInt8

But I have never seen examples of privileged helper tool in Internet... So you need see into Objective C code. Fortunately Obj C code not much.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!