18 July 2016

Test Gatekeeper Quarantine

Recently we have found out that people have issues with our free version of Icon Cast. We distribute the free version outside of Mac App Store and sign it with the Developer ID certificate. This should work well and worked in the past. At some point (we were unfortunately unable to trace back) this started to happen to people downloading the free version:

Dialog that offers users to move an app to the Trash if it Gatekeeper believes the application was tempered with
A scary dialog without option to launch the app
Based on Apple's documentation this dialog appears when the contents of the application is changed after the application is signed. The strange thing is that we were not aware of any changes to the app after we signed it.

Painful Workaround for Users 

There are many threads discussing this and a similar issue for different apps: OSXDaily, Ask Different, iMore, Stack Overflow etc. And they pretty much describe a same way how to remove the scary warning on a user's machine.

One very user-unfriendly way how to overcome this is to change preferences in Security & Privacy and allow to launch applications downloaded from anywhere. In this case Gatekeeper will not check signature of any launched app. However the dialog above and forcing users to change the settings is definitely a road block that may stop users from trying you app. It also does not earn a lot of trust.

Preferences in OS X that show how to disable Gatekeeper and enable any application to run without warning
Allowing this will efficiently disable Gatekeeper

Because all the above is extremely discouraging for your users it is best to sign your app. We have done it from the very beginning. Yet we found out that the dialog appears to our users. We looked for the cause of the dialog.

What Was the Gatekeeper's Problem

We build Icon Cast outside of Apple's xcode which brings interesting challenges at times. We were afraid it can be something exotic that xcode does out-of-the-box without without a developer even noticing and it takes non-xcode developers agest to track down some details.

After couple of hours of Googling there were a two things that pushed us into the right direction. First was this Stack Overflow question about failing to sign an app outside of xcode. We have also found that Apple made Gatekeeper stricter (Gatekeeper Changes in OS X v10.10.4 and Later) when it comes to external libraries referenced from the application.

The only external frameworks that we use are Paddle (for sales outside of Mac App Store) and Sparkle (for auto-updates). These are directly included in our app so they were not issues as such. We have just tried to update both to their latest versions to see if there are not some OS X-compatibility fixes. Release notes suggested that there might be some fixes in Sparkle.

And voilá. That was it. It seems that Paddle or Sparkle  was not compatible with the latest Apple security updates. Good we have fixed that. Next we needed to make sure this does not happen again.

Testing The Signed App

Apple recommends to upload the app to a web server or send it to yourself via email or something similar. All these methods are pretty inconvenient if you have a large app. It is especially inconvenient when you need a couple if iterations to find our what is causing the problems with Gatekeeper.

We wanted to test this more conveniently. What Gatekeeper actually does is - it check the extended attribute called com.apple.quarantine. If the attribute exists then it shows users different dialogs warning them the application was downloaded from The Internet.

There is a Terminal command xattr that enables to modify the extended attributes. People in most cases use this command to bypass Gatekeeper. However you can also use it to simulate that the file was downloaded from The Internet. By doing so you avoid a long roundtrip by uploading your built application and re-downloading it.

The instructions are very following:

  1. Open Terminal
  2. Go to the folder where you application is
  3. Type xattr -w com.apple.quarantine "0000;00000000;Safari;" "YourAppName.app"
  4. Press Enter
  5. Try to launch your app
Using these steps you should be able to quickly check if your users are not bothered by a scary dialog. If your signing process works well you should see dialog like this:
Nicer dialog that enables users to actually launch the app

Conclusion

We didn't want to test Gatekeeper's behavior manually in Terminal. So we have added an automated build step that creates a copy of our application and then runs a script that emulates quarantine by setting the com.apple.quarantine extended attribute. We have to still launch the quarantined application manually though. Still we reduced the amount of manual work significantly.

Build folder with Icon Cast and its quarantined version
Gatekeeper does a great job in protecting users and you should really sign your apps. It is also a good idea to test if the signed app works as it should. We were caught by surprise. So watch you back.

Useful Links

List of the most interesting links from the post:



No comments:

Post a Comment