How To Do Privilege Elevation on OSX with Objective C - objective-c

My custom Cocoa-based setup.app on Mac OSX that I made in Objective C needs to install a LaunchDaemon for doing elevated privilege tasks such as an antivirus program that needs to scan the entire hard drive and therefore needs root privileges. How can I make my setup application prompt the customer for their admin login and then install that LaunchDaemon into /Library/LaunchDaemons (and note I don't mean ~/Library/LaunchDaemons)?
The way I'm currently handling it is by using AppleScript with the admin privilege. It prompts for this login and then the AppleScript does the copying into this folder without the OS complaining. However, I assume that's not the proper technique -- that I should be doing this entirely in Objective C somehow?
Note that I can't use SMBlessJob in this case because it is for this reason that I'm creating the Launch Daemon in the first place.
BACKGROUND INFORMATION
I have a special need to create a custom setup.app -- just like the fact that Norton's AV application uses a custom setup.app. This is because the Apple PKG and DMG installers do not permit downloading of very large files (like virus definitions) from a server during install with some kind of friendly feedback. I mean, I can make a PKG file download a file from the server when running a Perl script or Bash script, but then the installer just hangs the progress bar for the amount of minutes it takes to download, not giving any other feedback to the user except that hung progress bar, and so the user thinks the installer is broke, when it's not. That's why I had to make my own custom setup.app, just like Norton did for their AV application.

Normally, SMJobBless would be the technique to do this. It's the one Apple recommends now as of 2016. Here's the readme.txt for Apple's sample project:
https://developer.apple.com/library/mac/samplecode/SMJobBless/Listings/ReadMe_txt.html
However, that's not the only way to do it. Another route would be to have your installer use AppleScript to prompt and run a Bash or Perl script with elevated privileges to install the LaunchDaemon, as well. (That's actually easier than SMJobBless.)
Basically, either technique installs a LaunchDaemon (e.g., "service") into a special folder, and that daemon can be set with elevated privileges, which can then run anything you want -- even command line commands. A super fantastic explanation of LaunchDaemons and LaunchAgents is here:
http://launchd.info/
Now, the problem is how to communicate with it from your application, once installed. They leave that up to you, and there are various techniques. However, they also leave it up to you to secure this so that it's not an attack vector.
A fantastic article on how to do IPC (Inter Process Communication between your application and this service) is here:
http://nshipster.com/inter-process-communication/
One IPC protocol on OSX is Distributed Objects, which is quite smooth from an architecture perspective -- you'll feel more like it's "coding" instead of "sending messages back and forth" like other IPC protocols. I've written a Stack Overflow post on this because the docs are shoddy and the existing examples on the Apple site and others are stale (won't compile on XCode7.1 with OSX 10.10+).
On communication protocol between your application and daemon/service, you can probably get away with key/value, XML, or JSON messages that are encrypted with AES256 with a long password and converted to Base64 encoding, and then use one of the various IPC mechanisms. However, that's another topic entirely.

Related

Prevent authorization popup when using SMJobBless

we are developing an application with a Helper Tool - which is installed into the system using SMJobBless. This works as expected; but there is a caveat.
We do frequent automatic deployments - sometimes more than one per week. Everytime the Helper Tool version changes, we re-register it - causing a password prompt. These 2 factors would quickly become irritating to our users.
Is there a way to have the password prompt appear only once, during the initial Helper Tool installation? Could subsequent updates happen without a prompt? Perhaps there is a way to leverage the existing Helper Tool to install a newer version of itself?
Short answer: No. SMJobBless() always prompts for admin credentials. There's no way to stop it from prompting. If you call this API, it'll prompt (or fail).
Longer answer on workarounds:
If your helper tool is running with admin/root privileges, it could theoretically replace itself with a new version. Think very carefully before doing this. Getting this right and maintaining security is very difficult, and the fact that even the major OSes have had vulnerabilities in installer functionality is a strong indicator that the risks of going this route may outweigh the benefits.
If you must proceed, read up on:
Race Conditions, Secure File Operations, and Time of Check vs Time of Use
Apple's Security APIs, particularly SecRequirementCreateWithString and SecCodeCheckValidity.
macOS Code Signing In Depth and the Code Signing Requirement Language
You would have to ensure that your helper tool cannot be tricked into replacing itself with (or executing) malicious code, or you will have opened your software up to being a trivial root exploit vector.
Also note: Regardless of what Apple currently does to verify helper tools installed by SMJobBless, it is conceivable that they could tighten the requirements in the future and refuse to run helper tools that have been modified since they were installed via SMJobBless. The safest method (in multiple respects) is to just call SMJobBless whenever you need to install/update the helper.

Mac OS X how can binary application (packaged in .app) change System Configuration without asking for password?

I am writing an application that when is running should modify SystemConfiguration to set system wide proxy.
I know it is possible to do that using "Authorization Services" framework provided by Apple, however I see that it keeps asking for a user password to allow changes.
On the other hand I have 3rd party application (not the one I am writing) that does the same, but does not require user password. The application is not even written in Objective-C, but written in FreePascal (FPC) instead. Unfortunately I have no source code for this application to see how it does this trick.
I know I should be able to achieve the same (system config changes without sudo password) by either having Privileged Helper Tool supplied with the application (and perhaps install it on first run) or by going even nastier and loading a kext.
However I see that this application does neither of above. It only performs system calls and no password asked! I am completely puzzled how did they achieve that and would like to find a way to do the same.
So the question is - how to achieve complete "no password asked" for changing System Configuration on Mac OS X with an application?
PS: Application I have at hand runs as user, not root. And there is no modifications to sudoers neither.
This is silly, but after 2 days straight of searching for a solution I found that there is no special code nor any tricks required.
This is easily done via setting setuid bit to binary that requires escalated privilege and calling setuid(0) in the code before doing operations that require privilege (not sure if second part is necessary).
Relevant links:
Apple documentation
Related question on SO
PS: This works basically on any Unix-like system (BSD, Linux Solaris etc) with one details - this does not work on scripts (the ones that require hash-bang #! in order to execute interpreter) with exception of Solaris, where it seems to work just fine.

Sandboxing Application With Command-Line Tool

I'm a bit confused about sandboxing an application that uses a command-line tool (ffmpeg). I won't mention his name, but I read at least two topics at Apple's Developer Forums where an Apple person suggests that the application requires the com.apple.security.inherit entitlement. This topic here also suggests that you need com.apple.security.inherit. Do I need it if I use ffmpeg through NSTask? My application crashes as long as this entitlement stays. If I remove it, the application starts up. If I take a close look at what Apple person says, the com.apple.security.inherit entitlement may be required if embedded tools are run directly from the application. It doesn't sound like that count ones through NSTask.
Meanwhile, this topic here suggets that I need to codesign the command-line tool inside the package. In this regard, I see consistency that I need to codesign the command-line tool with the entitlement file. But I'm not sure.
Life has become very confusing these days.
Thank you for your confirmation.

Is a scripting application allowed in the Windows Store?

So I have this bit of a project planned for Windows Store and Android. Basically, a networking multi-tool coupled with a scripting engine to implement protocols and behavior. Ideal uses being things like "my embedded device uses this simplistic network protocol. I'd like to quickly prototype a way to control it from my tablet".
It's my understanding that the Android market should have no problem with this. However, the Windows Store policy includes a vague clause concerning remote code execution
3.9 All app logic must originate from, and reside in, your app package Your app must not attempt to change or extend the packaged content
through any form of dynamic inclusion of code or data that changes how
the application interacts with the Windows Runtime, or behaves with
regard to Store policy. It is not permissible, for example, to
download a remote script and subsequently execute that script in the
local context of your app package.
Of course, the scripting engine will be sandboxed and such and should be "safe"(completely intepreted, no reflection), but does it violate this policy?
If you build in your scripting engine, and only run local scripts, you will be good. However, if you were thinking to have a repository of scripts that could be downloaded and subsequently run, that would be in violation of the policy as we understand it.
Unfortunately I don't think anyone but someone on that team can answer that (or someone with direct experience in that) because of the closeness to the legal language. Have you tried the Windows Store Appl Publishing forum at: http://social.msdn.microsoft.com/Forums/en-US/windowsstore/threads
In the context of scripting engine example given, unless the app modifies the scripting engine after deployment on user's system such that the representation of protocol/behavior (the script artifact's format) is made to change then it'll be policy violation. Its as if you submit Python interpreter, and at some point in time it abruptly moves onto interpreting ecmascript.

Making an application launcher

Okay so I want to make an application that launches other applications. However, the goal here is to make the app "portable" in that I can go from one windows desktop to another while using the same application from a usb drive. So here is a different rundown of what I mean:
I have aplication X. I use it on machine 1 and I want to use it on machine 2. However, machine 2 is my buddy's and he does not want me installing things on it. So, I take all the files that the installer made on my system, and put them into folders. App X put files in the windows folder that it expects when it is launched. If I merely run the the app and it looks in the windows dir it will not find the files. I do not have/want the ability to put files in the windows dir. I want to tell the app to look in folder a for files in folder b instead of where it would normally look. I could then use this program on any machine without having to modify the machine in any way.
Is this doable? If so what is it called so I can look it up?
EDIT: the win dir was an example. I would like the app to be self contained in a folder on the thumb drive. I want to redirect the where the app looks for files to a folder I specify.
This can be done, but how easily depends entirely on the program that you are launching.
The sorts of things that applications will do are:
Just run happily being executed anywhere (no dependencies). These are very easy!
Require some environment variables to be set up. This is easy to do - you can launch a new process with a modified environment if you wish.
Read files from disk. Usually when loading things like .dlls, applications will search on the PATH for the dlls, so they can be copied into the application folder (next to the .exe) and it will run happily on any system. However, in some cases applications will use fixed (or at least, less flexible) paths so that they will be harder to launch successfully.
Read registry settings. This is trickier. You need to know what state is required by the application, have your launcher record the old registry state, change it and run the application, then wait for application exit to restore the original state. This has to be bullet-proof to avoid corruption of the user's registry.
Ultimately you'll need to investigate, for each app you want to launch, just what it needs to run.
If the apps are commercial, then be careful that you are not breaking any licensing (EULA) terms by running them in this way.
Another alternative would be to set up a virtual PC image and simply execute that on the host PC so there is no need to worry about any special cases for each application. Depending on the VPC software you have available you may need to install software on the host PC to allow a virtual PC session to be run though, which may defeat the purpose/intent.
I think the system you describe is U3 (more info at http://en.wikipedia.org/wiki/U3). It requires the application to follow the U3 protocol, but if the application does, then it can be run off of a U3 flash drive without any install or admin permissions required on the host machine.
It's a proprietary technology, and supported by only a few vendors that I've seen.
If you really want portability and power, consider VMWare Player, and carry and entire machine, customized to your needs, on the flash drive. Of course, your friend would probably have to allow you to install VMWare Player.