I have an application that uses SIMBL. I know that there's a installer available on their website but how can I install it manually? In other words, without the user knowing. What files will I have to place and where?
I very much hope that there is no way that the SIMBL installer could be run without the user knowing (but I'm pretty sure that is not the case). Certainly, if I were to discover that SIMBL had been installed behind my back, I would hunt down the guilty app, nuke it from my system and then publicly point out that it is doing so.
Don't get me wrong; SIMBL is neat stuff. It is also wickedly dangerous. It modifies applications in ways that cannot possibly be supported and, thus, are exceedingly fragile. As much as I've enjoyed hacking around with such tools, I cannot abide by that level of indeterminate fragility on any system I rely upon.
I.e. tell the user that you are going to install SIMBL, open the package in the Installer, and let the user do so or decline. Do not do this behind their back.
Related
I am trying to build a desktop app.
I am thinking of using electron on the recommendation of a web-developer friend of mine, but as I am the only sole developer, I don't have the means to test the software on different platforms(OS, hardware etc.).So I am anticipating that this will cause a problem later, in the end, to test/debug software on different platforms and different OS.
I have ruled out web-apps because of some privacy concerns of the users for the remote data hosting.
Software is pretty lightweight and is almost equivalent to the image viewer apps with some slight modifications.
How to solve the problem of variations of different platforms?
Any literature suggestions pointing me in the general direction are also welcome.
Sometimes it helps to think of Electron as two processes.
The renderer vs the main processes. Generally the renderer process which runs the HTML/CSS/JS is it's own isolated component, and you communicate to the main process using IPC.
So generally for the UI, you can use mostly any web based testing framework to test reliability. At Amna, for example, we use Cypress as our E2E testing platform. You an also use something like QAWolf. Both should work with localhost. In general, most website testing tools should work fine, and consistently across platforms.
Where this gets tricky is when a UI functionality makes a call to the OS or the main process. For example, saving to the disk, or launching a program.
The general flow is this, and I've yet to find radically simpler options:
Set-Up a VM or buy a machine with the corresponding OS. I used Spot VMs in Azure for this.
Manually test the scenarios you care about in each VM before you ship
If you have a lot of cases that rely on the OS, then you should be able to further optimize this by using an automated test runner like Spectron.
From experience, what I've realized is that most of the iterations I do happen more on the UI than the underlying functions with the cross-platform capabilities. And if your code has good separation (e.g. contextIsolation:true, nodeIntegration:false), it should be pretty obvious when you need to do an entire "cross-platform" test vs just UI tests.
I'm not familiar with a lot of large-scale electron testing frameworks, I do know that ToDesktop handles package building and generating binaries to perform a smoke test and verify things open across different operating systems.
It depends.
The answer depends on what you are building, so it makes sense to figure out what you actually want to build. Some questions you might ask yourself:
Do I need a database?
Do I need authentication?
Do I need portability?
Do I need speed to market?
Do I want to pick a language I'm familiar in?
These are all good questions and there are dozens more we all ask ourselves. However, back to your original question.
Electron is a fine choice
Yes, there are alternatives. But Electron is used for Visual Studio Code, Facebook Messenger, Microsoft Teams and Figma. Choosing Electron means there are other developers making apps and there are proven apps in the market so you don't have to worry about a dead ecosystem.
Electron is easy to onboard if you know web technologies, think js, html and css. If you know these, you can transfer your web dev knowledge and make a cross-platform app. You don't have to worry about learning each OS since the UI is the webpage which will look mostly* the same between each OS. (*some very minor differences, but essentially the same).
Cross-platform deployment is easy
There are a few ways of bringing your app to multiple platforms, I happen to be most familiar with electron-builder, but the other two solutions work as well.
Many templates to start with
I am biased, since I'm the author of secure-electron-template which is one of the many templates you can choose from when starting an app. However, I recently reviewed all Electron templates and found that only 4 do not have serious security vulnerabilities.
The Electron framework frequently is updated, and over the course of the past few years there has been a shift in the way Electron apps are made. Some earlier frameworks didn't have good secure defaults which some of the older Electron templates inherited and thus, aren't as secure as new frameworks that follow security guidelines.
If you decide on Electron, give my template a try. It's got a number of features I'm building out in order to help the community with features they might want (ie. internationalization (i18n), saving local data, custom context menus, page routing, e2e unit testing, and how one can use license key validation, to name a few things).
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.
I have two versions of the same MSI package: 'genuine' and 'developer'. The former is intended for shipping, whereas the latter is built on developers' computers for the sake of testing, etc. I want to prevent accidental leaking of the 'developer' version, so that the end user couldn't have it installed. What are the possible approaches?
The MSI is built with WiX, just in case.
I've seen Securing an msi to prevent unauthorized use, but the answers there are focused on preventing launch not installation. I don't need to obfuscate, encrypt or protect the package contents. I only need to protect unqualified users from accindentally screwing things on their machines, due to erroneous packages being installed.
Honestly, because MSI is an open book ( Edit with ORCA ), it's best to do this type of enforcement (DRM) in the application at runtime. I could suggest all sorts of techniques in the MSI but they could be removed by someone knowing what they are doing.
What is your "leaking" concern? Do you not trust your developers? Do you not trust your CM / Release practices? Do you have a strong NDA in place? Proper IT security?
If you are trying only to prevent accidental misuse - that is, someone unknowingly installing a developer copy who wanted a user copy - I would suggest a simple launch condition. You would document that "developers" must put something on their machine (perhaps a file, a registry key, or even an environment variable), and have the msi check for that. It would then refuse to install unless the "I am a developer" footprint was there.
If you want to avoid the footprint, you could require that "developers" launch the msi from the command line and pass DEVELOPER=1 and instead check for the property. Or more extreme you could require specific and changing values for the DEVELOPER property. It all depends on how annoying you want to make it to be a "developer" for your product.
Note that this is not secure in the slightest against malicious misuse. Among other limitations, it does nothing to prevent administrative installations that allow access to all the files.
Note as well that it's still a smart idea to follow the usual launch condition patterns to avoid preventing uninstallation of the package.
Even though the API has been open since Mac OS X Leopard, there's surprisingly, and unfortunately, very little documentation on how to correctly use SMJobBless() for creating privileged helper tools. There are a lot of gotchas, even when copying code directly from Apple's sample project. Luckily, I've found my way around this, and have gotten the basis for my helper tool working.
However, it would seem that SMJobBless() only blesses the tool and copies it over, but doesn't run it. I've included code in my helper tool's main() function that should run, but doesn't (since NSLog() inexplicably doesn't work–according to the tiny bit of information I have found–I've tried syslog()ing some "Hello world" type strings, but nothing appears on the system console). There's no indication that the helper tool is launched at all.
The documentation is mostly useless. It simply says that after SMJobBless() is called, the helper tool is 'ready', with no indication of what 'ready' even means.
Furthermore, Apple's sample doesn't include any interprocess communication code, and doesn't explain how one is supposed to interact with the helper tool. Do you use Distributed Objects? Mach ports? Who knows? There's no official word on how to do it.
So, does anyone have any information on how to get this done? I've confirmed that the helper tool is installed, and authentication works, but I simply can't figure out how to launch the helper tool and communicate with it - there's simply such a gap in the documentation that this is a mystery for now. It's very frustrating; I can't be the only one with this problem (but there's little mention of it anywhere), and SMJobBless() obviously works somehow, since it's what Apple uses.
(Please don't mention AuthorizationExecuteWithPrivileges(). I'm not using it: it's deprecated, sure to go away, and is a major security hole. No thanks.)
XPC isn't an option if you're trying to elevate privileges (from https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html):
By default, XPC services are run in the most restricted environment
possible—sandboxed with minimal filesystem access, network access, and
so on. Elevating a service’s privileges to root is not supported.
SMJobBless will install a helper tool and register it with Launchd, as in the SMJobBless example provided by Apple. The trick to getting your helper tool to actually launch is to simply attempt to connect to your helper tool's advertised services.
There was a WWDC2010 example called ssd that demonstrated a simple launchd client/server model via sockets. It's not available from Apple any longer, but I've found a link here: https://lists.apple.com/archives/macnetworkprog/2011/Jul/msg00005.html
I've incorporated the dispatch queue handling in the server code from the ssd example into the helper tool in the SMJobBless example and can confirm that my helper tool is indeed running (as root) when my main app attempts a connection on the appropriate port. See the WWDC2010 video on Launchd to understand the other mechanisms with which you can communicate with your helper tool (other than sockets).
I'm not sure I can legally redistribute the modified sources I have, but it should be fairly straightforward to merge the two projects and get your helper tool running.
Edit: Here is an example project I wrote that uses a distributed object for communication between the app and helper: https://www.dropbox.com/s/5kjl8koyqzvszrl/Elevator.zip
In fact #KurtRevis's comment is right, you can use XPC APIs without using XPC services, and it is ideally suited to the job since.
Nathan de Vries has an excellent writeup of using XPC APIs with SMJobBless and has even modified the SMJobBless sample app to use mach XPC to both activate the job and for bidirectional communications:
http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/
https://github.com/atnan/SMJobBlessXPC
Somewhat related to all this is avoiding unnecessary admin password prompts. See the following email list thread for ideas on how to check if the bundle version and code signature of an already installed helper match (which also allows you to remove a higher versioned helper in the case of a user downgrading):
http://www.cocoabuilder.com/archive/cocoa/309298-question-about-smjobbless.html
If you don't want to wade through the thread, here is a link to the modified SMJobBless sample project provided by Eric Gorr:
http://ericgorr.net/cocoadev/SMJobBless.zip
Also note that the ssd example mentioned in other answers here is still available online from Apple as part of the WWDC 2010 download bundle:
http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645
Apple now (2015) has an "EvenBetterAuthorizationSample" that demonstrates installing a privileged helper tool and using the NSXPCConnection API to communicate between the app and the helper tool:
https://developer.apple.com/library/mac/samplecode/EvenBetterAuthorizationSample/Listings/Read_Me_About_EvenBetterAuthorizationSample_txt.html
The README is some of the best (only?) documentation of SMJobBless() available.
I feel your pain and am in the same boat. I'm in charge of the Mac version of an app that needs to perform various system configuration tasks. Of course some of these task need to be done with administrative rights. I started by using the sample code from BetterAuthorizationSample. It was a major pain to implement but it seemed to work. But then ran into cases where it would crash on some systems. I didn't understand everything that the BAS code did and my own lack of coding experience probably contributed to the problems. So I had to remove these privileged functions from my app.
Apple doesn't seem to care about the lack of documentation. See this message from the creator of the ServiceManagement framework. From his comments, I assume that XPC is the "intuitive replacement" he is referring to, but since it is only available on Lion, you'll still have to find another solution for Snow Leopard or earlier clients. It's also not clear to me if XPC can be used for privileged helpers (system level tasks that require admin or root access) or is just intended for privilege separation within your own app to make it more secure.
The BAS documentation is in desperate need of an update, but it also doesn't appear to be a top priority.
Now I'm attempting to rewrite my app from the ground up. Professional Cocoa Application Security by Graham Lee gives some insight on how to do use privileged helpers with SMJobBless, but doesn't go into much detail about on-demand access to launchd jobs.
So here's what I've been able to find:
If you want to launch your privileged helper on demand, you'll have to use an IPC socket. You should add a Sockets entry to your helper's launchd.plist. After you install the app with SMJobBless, the helper will need to "check-in" with launchd (via LAUNCH_KEY_CHECKIN) to get the socket file descriptors.
Sadly, the only mentions of LAUNCH_KEY_CHECKIN seem to be in the SampleD and BAS sample code.
I don't have any experience with sockets, so that's my roadblock at the moment. I'd like to use the highest level API I can, so I'm trying to find out if I can use any Objective-C classes for this (like NSStream).
You might find the launchd developers mailing list helpful. Another XPC option I just found out about is XPCKit. It's worth a look.
HTH
I wrote a blog post on this a few months ago, which included a cleaned up version of Apple's SMJobBless sample. Might help...
http://www.bornsleepy.com/bornsleepy/os-x-helper-applications
Itai have you looked at the SMJobBless sample code from WWDC 2010? It includes a helper tool and app to bless it.
https://developer.apple.com/library/mac/#samplecode/SMJobBless/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40010071-ReadMe_txt-DontLinkElementID_3
Its README file says:
This sample as it stands does not actually run the helper tool. The following samples show how to [sic] a launchd job and set up interprocess communication:
ssd (Doesn't seem to be online anymore. Was part of the WWDC 2010 sample code.)
BetterAuthorizationSample
A lot of my programs require the ability to write files to the hard drive. When I first made these programs for XP they worked great. Now I'm less ignorant about UAC (got a new laptop recently). And for future customers...I've noticed the potential for a LOT of annoying error messages....and quite frankly if the program can't write data to the hard drive or thumb drive it's on...there's no point to running it....
I've tried multiple times to build in the manifest a requirement for administrator or user access....I'm not sure if anything less would solve the problem...but have failed because click-once has security features in place to prevent me from doing so.
I'd rather not have to tell my customers how to make the program run as an administrator by editing the file's properties...I'd much rather have a convenient pop up like what you'd see new programs such as Itunes or Filezilla show if they were in conflict with UAC requesting the privileges they need.
I'd really like to do this but have had little success.
Any and all advice that can remedy this grievous problem appreciated.
Thanks.
First, let me tell you that the design goal of ClickOnce deployment is not to require administrative privileges. This translates into "you can't elevate privileges when running a ClickOnce application".
When Windows Vista came out, Microsoft published guidelines on where to store files that you want to be able to update. NOTHING should be placed in Program Files; they generally recommend LocalApplicationData or Isolated Storage. The same issues are in place for Windows 7.
So where are you trying to write data for your customer?