Modify defaults of sandboxed application from non-sandboxed app - cocoa

I have an application which I'm now sandboxing. I do automated acceptance testing using the accessibility API from a different process. Before sandboxing, the test suite used CFPreferencesSetValue and friends to set certain default values for the application.
After sandboxing, the defaults are read from ~/Library/Containers/BUNDLEID/Data/Library/Preferences but the CFPreferencesSetValue functions only writes to ~/Library/Preferences as far as I understand.
Is there a way to programmatically write preferences to the sandboxed preferences without e.g. hardcoding the location and modifying the plist directly, or using the defaults command line utility.

One solution is to add an "Application Group" to your sandboxed app, thereby allowing other apps of this group to share its preferences, see: Reading NSUserDefaults from helper app in the sandbox

Actually, there is a better way, see the answer to my own question here: How does OS X's defaults command get access to prefs of sandboxed apps?
The trick is to use the full path to the preference file in the sandbox container, minus the ".plist" extension, as the application ID.

Related

OSX: Avoid userprompt when opening embedded binary

I have a sandboxed app that uses an embedded binary to show it's status item.
On first launch of the main app (where it launches the embedded binary like this:
NSWorkspace.sharedWorkspace().launchApplication(statusItemPath)
) OSX displays a user prompt, if the user really wants to start the embedded app:
I find this really confusing for the user - I understand that it is for security reasons but I want to distribute via MAS and so both binaries needs to pass review.
Is there a way to avoid this user prompt (maybe a singing option or entitlement key?)
When an application is downloaded from the internet, or run via another program for the first time, OS X is protecting the user with a mechanism known as 'quarantine'.
Once the user accepts running the application, the quarantine extended attribute on the app is removed.
Removing the quarantine attribute can be done with the following command:
xattr -d com.apple.quarantine /PATH/TO/APPLICATION
So you could call out to the system to run this from your initial application on the embedded binary. However I'm not sure this would be acceptable to Apple for the App Store.
The preferred method would be to use XPC and create a helper app which is launched automatically by launchd. You can read about that here.

Write folder in Mac OS X with sandbox active

I created a small application in Xcode with Cocoa Desktop and this application has to create a folder in the current user's desktop Mac OS X
When I run the application without using the app creates a sandbox folder properly on desktop
If I use the sandbox putting right files for read / write I can not create a folder on the desktop
Does anyone know how to solve this as to send the application to the AppStore is necessary to use sandbox?
You shouldn't just create a folder on the desktop, regardless of whether you are using the sandbox or not. Instead use NSOpenPanel configured to select folders and ask your user to provide you either a folder to use. That is compatible with both open and sandboxed apps.
In the sandbox world once you've asked the user for a folder you can create a security scoped bookmark and save it in your apps preferences; on subsequent runs you can use that bookmark to re-establish rights to access the folder without user intervention. E.g. a browser might ask once for access to a folder to store downloads and then save a security scoped bookmark to that folder.
HTH
For some applications it just better to use some directory as default directory (Eg. Mail and Firefox uses Downloads as default directory). I guess this is your case. But, for better user experience (and for higher chances of your App's acceptance in AppStore) follow best practices - like avoiding direct Desktop access. And, mostly you will find the answer yourself if you go through these guides:
App Sandbox Design Guide (https://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html)
Entitlement Key Reference (https://developer.apple.com/library/ios/DOCUMENTATION/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html)

Can Mac app store apps access local file system?

I am wondering what limitations are imposed on the Mac app store. Can someone point me in the right direction? For instance, lets say I wanted to write an app that does incremental auto-backups of files on the Mac file system, is that possible with an app in the Mac app store, or would my only option be a standalone mac app?
On the iPhone, apps are self contained in their own "sandbox"? Does this same principal apply to mac app store apps?
Fellows, what the OP is really referring to is described here:
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html
It is all about
Containers
Entitlements
PowerBox (daemon)
Once an application is "sandboxed" its view of the ~ "home" directory is that of a Container (which happens to be created upon first start in $HOME/Library/Containers/appBundleID/Data). Therein it finds its "private copy" of config, cache and data files. And off course it can't read anything else, unless...
... you give the application the appropriate Entitlements in the form of a codesign-ed property file (in fact, codesigning is integral part of the sandboxing concept).
One of these Entitlements is the "com.apple.security.files.user-selected.read-write" which allows the application to read and write exactly those files which the user has explicitly chosen via the standard save and open dialog respectively.
The PowerBox (pboxd) daemon then renders the appropriate file dialog in its own process space and adds the selected file paths to the list of allowed files. This is transparent to the application, that is no code changes are required - as long as the application uses the standard NSOpenPanel or NSSavePanel dialogs.
"To facilitate application sandboxing, Mac OS X v10.7 provides a trusted system daemon that is tasked with presenting open and save panels on behalf of applications running in an application sandbox. That daemon is called Powerbox (its process name is pboxd). These Powerbox-presented remote panels appear fully indistinguishable from in-process panels in terms of user experience.
Any time an application running inside a sandbox invokes an NSOpenPanel or NSSavePanel dialog, rather than showing the panels directly, AppKit automatically asks the Powerbox to present the dialog. From a developer perspective, there are no code changes required in terms of how these panels are used; this process is fully transparent." [end quote from Apple docs]
Given all that, what the OP would need (for a backup solution) are "unmediated read/writes":
"If an application chooses to derive the user's home directory in a way that bypasses Cocoa APIs (by directly invoking getpwent, for example), the application sandbox prohibits it from writing to the paths it receives (unless the application has the unmediated write entitlement, which is strongly discouraged for obvious security reasons." [end quote from Apple docs]
However the closest Entitlements which would give "free access to the file system" I could fine would be:
"
Absolute file read-only—The ability to read the files or directories at the specified absolute paths. (com.apple.security.temporary-exception.files.absolute-path.read-only)
Absolute file read/write—The ability to read or write the files or directories at the specified absolute paths. (com.apple.security.temporary-exception.files.absolute-path.read-write)
" [end quote from Apple docs]
And I am not sure whether an application could simply provide the root directory "/"
Anyway, carefully note that these entitlements are marked "temporary": Apple might remove/deprecate those entitlements at seen fit!
I believe that starting in November, Mac App Store submissions must adopt the App Sandbox. There are specific entitlements that you can request when your app is submitted to the app store, along with an explanation of why you need those entitlements. More information can be found in WWDC Session 204 video on the Developer site.
Technically, there is sandboxing on the OS X. However, applicants started manually by the user bypass those sandboxing restrictions (sometimes requiring escalation / admin verification screens).
Take a look at:
http://techjournal.318.com/security/a-brief-introduction-to-mac-os-x-sandbox-technology/
The are changing or have changed with the Lion release. Mac Store apps used to be able to do anything within the filesystem that the logged in user privs could allow but I think you are now required to use the entitlements system and hence sandbox your App.
Read this for more ideas
https://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html#//apple_ref/doc/uid/TP40010572
This will help. Take a good look at it.
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16
You can currently find Hype or Pixelmator on the Mac App Store.
This proves evidently that you can save to disk and read from disk, which seems a basic feature of any serious application. Moreover, Apple is pushing developers to start using incremental auto-backups of files, it would therefore be very surprising if they forbade that in the App Store, wouldn't it?

How to make an Invisible / Hidden Cocoa Application

I want to develop a application like http://orbicule.com/undercover/ or
http://hiddenapp.com/.
I know how I could do that for windows but I have totally no clue, what kind
of approach I would need for mac os x, cocoa/xcode.
Is there anything I should be aware of when building applicatons / background services
with no GUI for mac os x?
The service will post data to the webpage with the usual data like geo location & IP
information about the machine so it should be able to access the internet too.
Please lead me to the right path.
It's fairly straightforward.
Go to:
Information Property List Key Reference
http://developer.apple.com/library/ios/#documentation/general/Reference/InfoPlistKeyReference/Introduction/Introduction.html
in the Launch Services Keys, you will see one called "LSBackgroundOnly" simply define this in your Info.plist and set it to true.
<key>LSBackgroundOnly</key>
<true/>
From the documentation:
LSBackgroundOnly (Boolean - Mac OS X)
specifies whether this application
runs only in the background. If this
key exists and is set to “1”, Launch
Services runs the application in the
background only. You can use this key
to create faceless background
applications. You should also use this
key if your application uses
higher-level frameworks that connect
to the window server, but are not
intended to be visible to users.
Background applications must be
compiled as Mach-O executables. This
option is not available for CFM
applications.
Your application will be a background application.
Give System Startup Programming Topics a read. Create a command line tool project, not a Cocoa Application nor a Cocoa Document-Based application. To provide a GUI to interface with it you'll want to use a separate application (ideally one you don't have to install with the "hidden" app, since you seem not to want it to be easily discoverable).
With the exception of AppKit (UI) stuff, the rest of the basic Cocoa frameworks is still available to you via the command line. This means you'd write the main logic of your app (the non-GUI parts) the same as you would otherwise.

Autostart Mac application programmatically

We have a cross platform application. The application has a feature to autostart it once the user logs in. How to do this in mac? from within the application. Manually adding it Login Items works but I am looking for how to do it using an API or something similar.
If it's a GUI app adding it as a login item is the best way to go. Apple's dev note on the subject lists 3 ways to do this: with the Shared File Lists API, via Apple Events, or with the CFPreferences API.
You have to create a launchd property list file and place it in ~/Library/LaunchAgents or /Library/LaunchAgents, depending if you want the change system-wide or only for the current user.
This guide from Apple will help you accomplish that task.

Resources