I've created a simple Mac app that gives you statistics on your working behavior over time. For example, your average words per minute, what language you are typing in, usage of the delete key, etc. Interesting stuff! However, some test users have said they wouldn't use the app if they didn't know me personally, since it collects keystrokes like a keylogger.
Is there some certification I can get to show that I'm not doing anything nefarious? (I never keep more than one word in memory!) Or will it be enough to have my app signed? Or open-source that part of the code? (Other parts I know I cannot make open source.)
Distributing through the Mac App Store will help, since users can see that Apple has tried your application and found nothing nefarious in it. [Added:] Also, sandboxing your app means that your app is restricted to an explicit set of abilities, which technically-skilled users could inspect. Anything not listed, you're unable to do, so this would be an easy way to prove that you don't send anything back over the internet.
Another thing would be to save all data in user-readable files. No binary plists, no Core Data stores, etc. (Whether the XML variants of either of those should count as user-readable would be more arguable, but for this purpose, I think at least an XML plist would be readable enough. Not sure about Core Data.)
If the user can read all of the raw data you store using applications that they trust (such as TextEdit), and not just your usual fancy in-app presentation of it, then they can check for themselves, and eventually trust, that you're not storing anything they wouldn't want you to.
If any concerned potential users email you about whether you report their keystrokes to your own server via the internet, and assuming that you don't make any internet connections at all (not even an update check), you can recommend that they should install Little Snitch, which pops up a confirmation alert anytime any app tries to connect to something. When they don't see such an alert about your app, they know that you're not phoning home.
You might also, on your product webpage, include a link to a tech profile. Here's Jesper's article proposing them, and here's one example of such a document, for one of his products.
I would think that Gatekeeper would be adequate for most users. If it turns out an app is doing bad things, then Apple could pull the plug on a malware developer. So that and maybe some time live should establish your program as 'safe' to those who are not technically inclined (e.g. cannot understand your source).
Simply distributing it in your or your company's name can do a lot to build trust in an app (provided of course your other products/programs have not violated users' trust).
If you can get the application onto Apple's App Store, then that means they will have checked it for such problems. There's no way they'd knowingly allow a key-logging app on there. Also, signing the app with an Apple certificate ensures that if it has been downloaded from the App Store and later is found to be nefarious, they can black list it.
Open-sourcing code would also be a good idea. I assume you can't Open Source all of it because it doesn't belong to you? If so, then make it clear what technologies it uses and be as open and honest about what the application does and how it goes about doing it.
Related
By using runningApplications of NSWorkspace, it is possible to get a list of running apps on Mac OS as NSRunningApplication objects, and from this get additional information like what application is in the foreground.
It is possible to identify the running application using their name (localizedName), but I'm sure that can be spoofed by rogue applications. Other things like bundleIdentifier seem better, but I believe that too could be spoofed.
I would imagine that pretty much all of the metadata could be spoofed for applications outside of the public app store, but for any apps gotten from the app store things like bundleIdentifier should be safe ways to identify an app, right?
If we include arbitrary apps that someone downloads from the Internet, is there any better way to identify an app as to filter out rogue apps? I realize that there may be no solution that has no drawbacks, but looking for a best-effort attempt.
As you mention, all of these things can be pretty easily spoofed. Having written a product that does exactly what you're describing professionally, the solution is relatively straightforward: fingerprint every version of every popular app into a massive database, and then fingerprint each app you discover on the machine and look them up in your database. When you discover an app you've never seen before, flag it for adding to your database.
Maintaining that database is very large and ongoing endeavor. That's where most of the value of the product is. The agent code is not that complicated. The up-to-date database is what customers pay for. It's a pretty hard space to get into.
You're correct that you can verify signatures to make sure that things downloaded from MAS or part of the OS are what they claim to be. This will get you started, but isn't nearly enough; there's just so much that doesn't come from MAS.
The other headache is that you can see what "apps" are currently running in NSWorkspace, but it's pretty messy what it means. A lot of things that you don't think of as "apps" show up in runningApplications, like MobileDeviceUpdater and nbagent. On the other hand, things like mysqld aren't. Fingerprinting from runningApplications can miss things that aren't in that list, or malicious apps could lie about their bundle path to make themselves look legitimate. You can use tools like lsof to see what files a process really has open, but it gets more and more complicated.
Best of luck; it's a deep rabbit hole with dozens of corner cases, and very little documentation.
I'm trying to get a better understanding of OSX Code Signing and the advantages that it affords me in terms of protecting my software. Could someone please clarify certain questions for me?
Given an application that is Code Signed but not sandboxed:
Should a hacker change the application's binary the application is no longer considered as signed. However will it still run correctly (with the Caveat that Lion will warn the user about the application not being code signed)?
Given an application that is Code Signed and sandboxed:
What will not happen if a hacker changes the code in this case? Can he/she simply remove the entitlements file to create an unsigned version of the application that no longer has any sandbox restrictions?
Given a signed but not sandboxed application that contains a signed and sandboxed XPC service helper is there anything I can do to guarantee that a hacker can't create a non-signed (and modified) version of either part. It seems to me that as it currently stands a hacker can do the following:
Create a binary-modified version of the helper. This new version
would thus be non-sandboxed and non-signed.
Create a binary-modified version of the main application. This new
version would thus also be non-sandboxed and non-signed, and able to
start up the new version of the helper.
Am I wrong? If so, why?
Thanks,
Tim
You're basically right. What you're looking for is copy protection, and that's something nobody's ever figured out how to do (well), and it's not something that either code signing or sandboxing attempt to do. What sandboxing does is limit the damage if your program is taken over at runtime and made to do things it's not supposed to. What code signing does is prevent someone else from passing their program off as yours.
I used the words "their program" intentionally. You have to realize that once "your program" is on someone else's computer and they start messing with it, it's not really yours anymore; it's theirs, and they can do pretty much anything they want with it. They can take parts out (sandboxing, etc) add parts (malicious code, etc), change things, ... They could even write a "completely new" program that just happens to include parts (or the entirety of) your program.
There are things you can do to make your code hard to modify/reuse, but nobody's ever figured out how to make it impossible. Apple isn't trying; their security measures are aimed at other targets.
I've used plenty of cocoa demo apps that stop working after 3 days or a month or so. How do they do that? What's the best way? Also, what are the limitations?
(Disclaimer: I've never made a trial version before, only read up on the subject and used a bunch of them.)
The limitations all come from the fact that anything on the user's system, the user can modify. So:
Clever cheapskates may alter your app's executable to stub out or otherwise defeat any check you make.
You have to store the amount of time used (or, more lazily but not as user-friendly, the date they started using your app) somewhere. Wherever you store it, the user must be able to change it (since your app runs as them), which means that if they find it, they can reset the clock.
It isn't possible if you run in a sandbox, unless you store the aforementioned time-tracking data in the user defaults or the Keychain, either of which might as well be in plain sight, or request the temporary exception entitlement for writing anywhere on the file-system. Time-limited trials can't be in the App Store anyway, but if either the App Store or sandboxing becomes required in a future version of Mac OS X, your time limit will break, and we can only hope it doesn't prevent the user from using your application entirely.
There's also the matter of handling payments. One way would be to sell the app in the App Store, without any trial-enforcement code, and distribute a separate build yourself that always enforces a time limit. If you do handle payments yourself, you need to store a record of the user's license on the user's system, and you need to check that license. This then becomes vulnerable to the same problem: The user may forge a license or “borrow” (e.g., download from a warez site) someone else's.
The upside, of course, is that the user has some amount of time to try the application for free without having to cough up any money, so at the end of that time (if your application is good and fills their needs), they'll be more likely to buy.
At the end of the trial period, you have a choice of what happens:
Lock the user out of the application entirely.
Cut out features. Acorn does this.
Let them open documents, but not save or print. (You can block screenshots, but then good luck handling bug reports.)
Let them save or (if applicable) print, but degrade part or all of the document in some way. For visual creations, such as images, a watermark may work. For audio, you can limit the sampling rate to something unpleasant like 20 kHz or less. (There's a case here for having your own proprietary format that you always handle losslessly, and only degrading exports to common formats such as TIFF, JFIF, or AIFF.) Fission does this.
Just nag them. (Can be combined with any of the above.)
Nag them and put a delay on the user's ability to dismiss it. You can even increase the delay the longer the user goes without paying.
One good alternative to the trial period is to have a separate “free” version with fewer features (or with ads). This is especially common on both App Stores.
Another consideration is whether the trial period is days used or days since first use. The latter is easier to implement, since you just record the date of first use and do subtraction. The former is more user-friendly, as it does not punish the user for launching the app once, playing with it for five minutes, and coming back to it for a real trial 31 days later.
You can also implement a limit on number of launches. It's as simple to implement as days-since-first-use, but doesn't punish only playing with the app once.
Some users just won't pay. Some users will do practically anything to not pay.
So you need to strike a balance. You need to provide a basic level of difficulty so that the laziest cheapskates cannot simply defaults write com.example.yourapp DaysSinceFirstUse -int 0 and keep using your app forever, while not making your app so onerous to try out (much less pay for) that they don't.
So here are some things not to do:
Attempt to enforce equality between the name of the user on their license (entered at purchase) and their name on their account or in the Address Book. There are a dozen different ways to write any name, and some people have multiple names (through marriage, aliases, legal name-changes, multiple languages, Star Trek fandom, etc.), so this or anything like it is a bogus check that will upset more legitimate users than discourage pirates.
Hold the user's data hostage. See my above point about the merit of a proprietary format that you always handle losslessly. If you do always degrade output during trial, make that absolutely clear up front in the app's on-launch “This is a trial version” dialog.
Require an internet connection. Not everybody has one (that can connect to arbitrary servers), and not everybody has one all of the time. Learn from the games industry: Don't alienate your users.
Install any sort of copyright enforcement software that runs in the background and/or is in a separate place from your application. Users will rightly hate you for this.
As for how to do it, here's what I recommend:
Implement a “days of actual use” check. This can be a selling point. It warms my heart when a trial explicitly says it uses this kind of check.
I'd say store it in hours. On launch, get the current number of hours from wherever you store it. Add two hours and write it back (so the user can't force-quit your app to defeat this). On quit, add the real number of hours since launch to the originally-read number and write the revised number back.
Store it in an invisible file in Application Support. Encrypt it (again, you want to defeat casual piracy), but don't waste too much time bulletproofing it. Remember, your app must contain everything to both encrypt it (to keep track) and decrypt it (to perform the check), so a sufficiently determined (and educated) cheapskate can break this no matter what you do.
On launch, get the current number of hours from wherever you store it and test whether it's over the limit. (If you take my add-two-hours-right-away suggestion, do that after you test against the limit.) 30 days is 30×24=720 hours. If it's over the limit, enact your trial-expired measures.
If you sell the software yourself, use symmetric public-key encryption for the license file. I think AquaticPrime does this. You encrypt licenses with your private key, and distribute the public key in the app, which uses the public key to decrypt and check the license. Practically unbreakable. You send license files to customers by email using the email address they provide at purchase. (Tell them that they will receive the license by email so they don't enter a made-up address.)
If you do this, make sure you test entering the license, both before the trial ends and after it ends.
Do the trial check only if there is no license.
If you can sell your app in the App Store, I recommend you just do that. If you want to also distribute a trial version yourself, do that with no licensing code in place, so the trial check simply happens unconditionally. The App Store version, of course, does not need (and must not have) a trial check.
Watch this. (Note: It pre-dates both of Apple's App Stores.)
In general, they save a count of days/hours/whatever used somewhere, e.g. in the app's user defaults.
Since it's fairly easy to change an app's user defaults, some write a simple hash to the file that has to match the number of days used. If not, they expire the build right then and there because a user obviously just mucked with that setting. Others keep several copies of the number of days used counter. If one is missing, they restore it based on the lowest number in one of the other locations.
Good locations are invisible files in locations the user wouldn't expect, maybe named so they look similar to a file by another app or a system file. But be careful that you don't litter files across the file system that then give the other app they look like a bad name. Also worth considering is writing a resource into a file's resource fork, where most people don't look anymore these days (one of your files! Another app or the system may replace their file and strip your info, or may use the same resource type and cause a collision).
Chances are, a casual hacker will try to edit the user defaults and then give up. A dedicated hacker will keep going no matter how much effort is put in the protection scheme, so it's not worth spending too much time on protecting it.
Some app developers instead generate a license key that has an expiration date in it and make the app refuse to run without a valid license key. There's a nice article by Allan Odgaard on how to sign information using OpenSSL (make sure you use LibreSSL or CommonCrypto.framework these days, which are very similar) to get the expiration date to your user without them being able to edit it: http://sigpipe.macromates.com/2004/09/05/using-openssl-for-license-keys/
Based on your ideas I made a short proof of concept in Java using Elliptic Curve Cryptography to generate a UUID on start up and then sign that UUID with ECC to create a registration key. The code is here if anyone wants it.1
OK, it might be a problem with my system but I'm having a very difficult time getting Windows 7 to recognize my custom exe as the default handler of the mailto protocol.
First, I've seen this:
Register Windows program with the mailto protocol programmatically
Next, I've seen these:
How to Register an Internet Browser or Email Client With the Windows Start Menu
Registering an Application to a URL Protocol
I've added what seemed the appropriate registry entries but I still get Windows Live Mail coming up every time I click a mailto link (whether in a browser or via the Run window). I've set the registry entries for all users and for the current user, still it doesn't work.
When I go to the 'default programs' app and scroll down to the mailto protocol, I only see Outlook and Windows Live Mail listed. My custom app doesn't even appear.
I figure that it's either something special with Windows 7 or it's something with my computer.
My custom app is a WinForms .Net app but I don't think that matters.
Any ideas are greatly welcome.
The way described in the answer which you referenced in your question seems correct way for Windows 7 as for other operation systems.
I suppose that you use 64-bit version of Windows 7 and your program is 32-bit application. So if your application write in the HKEY_LOCAL_MACHINE\SOFTWARE\Classes\mailto\shell\open\command key it modifies only the key HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\mailto\shell\open\command used for 32-bit applications. You can read more about registry virtualisation here and here.
If it's your case you can call directly native Win32 API RegOpenKeyEx with the KEY_WOW64_64KEY flag which will be ignored on 32-bit operation system.
Though a pretty late answer, what worked out for me is this: On regedit, this supersedes the registry keys mentioned in other answers:
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\URLAssociations\MAILTO\Userchoice
Have a look at this page:
Default Mailto Registry
How can I add a custom url handler on Windows. Like iTunes itms:// Related but not.
This seems like a very high-nerd-level context to a fairly common problem. As a nerd, I'm swept up by the discourse on 64 vs x86 and the pseudo-universal binary aspects of .net. But the tech support troubleshooter in me can't help but think that the core problem needs to be made plain and addressed systematically...
So your real problem, regardless of the mail client (as you said yourself), and regardless of your CPU, is that you can't get your mail client to be the default protocol handler for mailto. Or to make it really simple, you can't get the program you like to be the default program.
I'm inclined to think that the 64/86 aspects of the problem are not relevant. They are interesting, and possibly having some effect, but if the program is running just fine (no issues with the code in that architecture, etc), and if it does email just fine (emails get send and received, all SMTP and IMAP all the way), then I doubt the OS is plotting to keep the client from taking over as the leader of the porch dogs.
If anything, I would say that the client had self-esteem issues and is afraid to be the mailto protocol handler. Most clients can't resist asking if the should be the primary and if you say yes, they pass the word along to the other apps and to the registry. They make sure everyone knows they are the new Mailbox king in the house.
So, what I would try first (basic troubleshooting): install another mail client and see if it has the same issue. If it does, your OS is a bully and you'll want to explore such routes.
But if this other client can get into the default programs club and be made the mailto handler, then the problem is with your app. It's a big wimp that doesn't know how to properly assert himself.
But like so many underdogs waiting for a cool kid to take them under their wing (and by wing, I mean Thunderbird. Don't bother with any other client), your app can stand on the shoulders of the working third-party client.
We have to assume that Thunderbird did at least one and possibly two things that your app didn't do. The first was getting it's name tied to the protocol in the registry. Go poke around and see if you can find his name and how it's associated to the mailto protocol. Chances are good that you can swap out his name for yours, or at the very least try to pin the protocol to you as well.
The second thing that T-Bird may have done was get himself in the "Default Programs" list (a feature of 7 that I didn't really like, because it had a cool concept behind it -- ie, let's group apps together up front rather than wait and see every time if one of them can do a similar job. But Windows screwed that good time (big surprise) by acting like the overprotective parent it always is, and showing up at the kids' party and saying "I think these two should be in this group, don't you?"
Well, my hope is that by getting access to the mailto by borrowing it from Thunderbird, that you'll be welcomed into the default programs club, but if you aren't and you are still the mailto handler, I'd write it off, at least gloat about it for a week or two, before trying to tackle that issue.
Now, if Thunderbird can't get mailto control, I'm very inclined to think that Windows 7 as actually put in to place some sort of strange caste system, where the application and it's installer (eg user) must some how prove their worthiness to be in the group by figuring out what the big secret is.
Oh, and if all else fails, try restarting in Safe Mode with no networking, install your client in that environment, and starting it up. See if you can't make it the default while the others are in suspended animation. Do a test run (with no network, obviously) by writing a basic HTML page with a mailto and see if clicking on it opens your client.
THen cross your fingers when you start back up in normal mode.
Let me know if any of the above proved the least bit helpful.
Mac OSX has this feature called (I think) 'Services'. It is available in the menu bar under the filename of the application (e.g. Finder) and then selecting 'Services'. This gives you access to a list of applications that provide 'services'. For example, if you are browsing a website with firefox and you have some text selected on the page, the services list has an entry for Mail > send selection.
I've been using a Mac for almost 3 years and I've literally never used it (but I've known it to be there from the beginning).
So, is it worth for an application developer to provide support for this (i.e. provide some services actions)? Or would it be a waste of effort (because no one, or very few people, uses it) ?
I've attempted to use it a few times over the past ten years.
Previously, the menu was cluttered with disabled items, and uselessly disorganized. Actually making a selection was unpredictable, as the few items that weren't disabled were often supposed to be. The appearance of possibly doing something was itself just a bug.
However, it appears to be much improved in 10.6. If you want to provide a universal, context-sensitive service, I'd say go for it. Maybe it will be the killer app for this decade-dormant delivery doodad.
I have used Mac OS X since Developer Preview 2 (and earlier versions of Mac OS before that, though they didn't have the Services menu), and I have never used the Services menu.
I'm sure some people, somewhere must use them occasionally, though I have never seen it. I would say it's likely a waste of effort unless one of your users specifically requests the feature.
I use them from time to time. But other pretty high profile users seem to think they're the dog's bollocks. So I suspect it depends on your audience.
Only you can judge whether there's the remotest chance your users will care, but I certainly wouldn't rule it out. If your software genuinely does provide a service that would be of benefit beyond its own application context, exposing that as a service definitely seems like something worth considering. You wouldn't neglect copy and paste out of hand, would you?
In 10.6 they are a lot more useful (as Potatoswatter indicates, they are properly Contextual in 10.6, so that it only displays text based services, when you have text selected).
For what it's worth - I've rarely used the Services menu at the top, but have sometimes used them via the context menu - but primarily with Apple's own apps (send to iPhoto, open in Preview). There aren't many third party apps that offer services I find useful.
However, I am aware that some users of journaling/clipboarding software swear by them. WalkyTalky has the right view - if your application exposes a service that is useful (or if you think users would want to regularly select and push data into your app) then adding support would be useful.
(In contrast - if it doesn't, then adding one is just adding to the 'noise' - I have a notebook application that adds a service for every single new notebook created).