PDA

View Full Version : Authorization in Sandboxed App?




ArtOfWarfare
Jun 13, 2012, 01:17 PM
I have a sandboxed app that I'd like to submit to the app store.

One of the features of the app is that it's "networkable" - it will find other instances of itself on the local network and communicate with them, if the preferences have been set up that way. It's very easy to turn on/off the "broadcaster" and "receiver" in my app - there's a simple checkbox in the app's preferences.

I expect that this feature will be particularly popular for IT departments in charge of public computers. They'll want to set up the computers with the app running and the broadcaster turned on.

But lets suppose they're at a public school with kids who enjoy screwing up the settings on the computer (lord knows they love making the dock tiny and hide on an odd side of the screen while setting on the background with a picture that shows a false dock - on and on, you get the point.)

THE POINT
I'd like to have a lock for my app's preferences, just like Apple has in system preferences. It looks like SFAuthorization perfectly provides this functionality, but is not allowable in a sandboxed app and, by extension, not allowable on the Mac App Store.

If someone knows of a better possibility than those I'm about to list, please share, but otherwise, which of the following would be the best for me to pursue to solve this issue:

1 - Request a new password when the lock is enabled, which must be presented to unlock the app. (Issues: How do you ensure that the person who clicks on the lock is someone who should be allowed to click on it and minimize the chances it's maliciously locked - and then can't be easily unlocked by someone who should be able to modify the settings.)
2 - Make a separate edition of my app, non-sandboxed and distributed by some other means, which just uses SFAuthorization. (Issues: How do I distribute it? How do I advertise it? Plus it'd be a pain to have to keep two editions of the app up to date...)
3 - Don't distribute through the app store, don't sandbox, just use SFAuthorization. (Issues: This would be even more difficult to advertise... I don't even know how I could distribute it.)
4 - Include in my app a link to where a preference panel can be downloaded. The preference panel can use SFAuthorization and modify my app's NSUserDefaults file so that my app knows the preferences normally accessible through it should be disabled. (Issues: Fairly complicated for me to make and my users to use... and how would I distribute this?)

Edit
Does anyone know anything about SMJobBless()? Apple has a sample project, but as far as I can tell, it doesn't actually work at all. I tried compiling and running it, but it appears to quit itself before doing anything? It doesn't post anything to the console, it doesn't add itself to the dock or menubar... as far as I can tell, it simply starts, Xcode says it's running fine, and then the app quits. Does the sample behave differently on anyone else's computer? Mine is running 10.7.4...

Is SMJobBless acceptable in a sandboxed app? It seems like there has to be some way of doing this, as now that I think about it, the MAS version of Xcode is sandboxed and needs authorization to install the command line tools.

2X Edit
Nevermind, just double checked and Xcode is not sandboxed T.T

3X Edit
I just checked... the Console app is actually where the output is placed (not in the Xcode output window.) "Hello World" is appearing as it should, along with the numbers... I'm not quite sure how to use this within my own app, though...



chown33
Jun 13, 2012, 03:28 PM
I think you should take a closer look at your intended audience's needs, and ask yourself whether you're looking at a "managed deployment". I think you are.

A managed deployment is one like public access, schools, enterprises, etc. where the configuration is identical for a large number of machines, and it needs to be easy to deploy that identical config to all those machines. This is in contrast to a "privilege model" deployment, where each machine has a privileged level and an unprivileged level, and there is little or no need to deploy identical privileged config to large numbers of machines.

I mention this because managed deployment is often better handled by having a preference plist in a privileged location, and values defined therein are not overridable by any other preferences files. There may or may not be a mechanism in the app itself to elevate privilege and changes those preferences. Sometimes, the managed model is better if there's no way to edit the managed config within the program. That means an offline editor (like plist editor), and some other privileged program is responsible for downloading the master preferences and putting it in the right place.

If I were in charge of 300 machines, there is no way I'd want to manually go to each machine, enter the admin password, and change the preferences. I would much rather deploy by editing the config file on my machine, and test it it there until I was sure it worked. Then I'd use my god-like deployment app (http://www.apple.com/remotedesktop/) to do a mass download to all the target machines.

So I think you should just make your app look for preferences in a privileged location (under /Library), and if there's a file there load it. Then make sure no other prefs can override what's defined in that managed-prefs file. You can do that simply by always looking in the managed prefs first, and only go on to the normal prefs if the item is missing in the managed prefs.

Oh, and don't implement any privileged editing or writing of anything to the managed prefs file. It's purely read-only as far as the app is concerned. This eliminates everything pertaining to how to manage security and privilege-escalation within the app. I.e. you've made deploying and handling the managed prefs into an externality for the app itself.

ArtOfWarfare
Jun 13, 2012, 05:05 PM
Many excellent points and ideas.

I'm a little confused by this part of it, though:

So I think you should just make your app look for preferences in a privileged location (under /Library), and if there's a file there load it. Then make sure no other prefs can override what's defined in that managed-prefs file. You can do that simply by always looking in the managed prefs first, and only go on to the normal prefs if the item is missing in the managed prefs.

You mean the root Library, correct? I was under the impression that a sandboxed app could neither read from nor write to the Library?

There may or may not be a mechanism in the app itself to elevate privilege and changes those preferences. Sometimes, the managed model is better if there's no way to edit the managed config within the program. That means an offline editor (like plist editor), and some other privileged program is responsible for downloading the master preferences and putting it in the right place.

If I were in charge of 300 machines, there is no way I'd want to manually go to each machine, enter the admin password, and change the preferences. I would much rather deploy by editing the config file on my machine, and test it it there until I was sure it worked. Then I'd use my god-like deployment app (http://www.apple.com/remotedesktop/) to do a mass download to all the target machines.

Are you suggesting that I leave up creation of the preference file and placement of it in the correct directory to the administrator?

Not to offend them, but it seems to me that I should keep it as simple as possible for them - there shouldn't be a way to screw it up - as I'd like them to find the process painless and for them to come back and buy more of my apps in the future.

Is a small app that generates the preference file and tells them where to place it a good idea? (Remember, I don't have any means of distribution right now besides the App Store - which means it needs to be sandboxed - which means it probably can't place it directly at the path itself, assuming this path is non-writable normally.)

chown33
Jun 13, 2012, 05:41 PM
You mean the root Library, correct? I was under the impression that a sandboxed app could neither read from nor write to the Library?

Yes, I mean the root /Library folder. More specifically, a suitable subfolder thereof. E.g. /Library/Preferences (there may be other options that are equally or more suitable.)

The defaults subsystem (i.e. the Preferences API) has a way to specify a series of domains. You might want to look at that, and use it if it meets the requirements. I don't recall if there are restrictions on that for the sandbox.

I'm not up on all the latest restrictions of what can and can't be accessed in /Library. If you attempt the access and fail, then fall back to unmanaged mode, that may suffice. I think the absence of the root-resident file, or inability to read it, should result in normal non-managed behavior. You'll probably have to review the requirements for out-of-sandbox file access.


Are you suggesting that I leave up creation of the preference file and placement of it in the correct directory to the administrator?

Not to offend them, but it seems to me that I should keep it as simple as possible for them - there shouldn't be a way to screw it up - as I'd like them to find the process painless and for them to come back and buy more of my apps in the future.

Don't assume that people who manage multiple-machine deployments are idiots, or even persons who need a lot of hand-holding. I think if you simply documented the location, name, and relevant keys in the plist, it would likely suffice for most of the intended audience.

Remember, you're already talking to an audience who is (or should be) familiar with how to lock down multiple remote networked computers. If they don't already know how to do that, then you're wasting your time trying to tell them how to lock down your specific app's individual prefs file. In other words, if the security of the remote machines is already a shambles, nothing you say or do can ensure anything is secure from unauthorized tampering.


Is a small app that generates the preference file and tells them where to place it a good idea? (Remember, I don't have any means of distribution right now besides the App Store - which means it needs to be sandboxed - which means it probably can't place it directly at the path itself, assuming this path is non-writable normally.)

Your app presumably already writes a prefs file. So if the per-user unprivileged setting is correct, all that's necessary is to copy and deploy that prefs file to multiple machines. Another app isn't needed.

ArtOfWarfare
Jun 14, 2012, 10:13 AM
I'm not quite sure if this solution works with code signing, but this is what I did...

I added a property list file called .Override to my bundle's resource file (it's adde during the build.) My app can read from, but not change, the .Override preferences. Between the file being in the bundle and the file being hidden (it has the starting .), I think it should be secure enough... Right?

It wouldn't be too secure for an administrator, would it?

(As in, it wouldn't be too much of a hassle for an administrator?)