As part of making sure my customers have the latest version of their applications available, I use AutoPkg, JSSImporter, and AutoPkgr to ensure that as new software updates are released, they are automatically uploaded to my shop’s Casper server.
As part of this process, some applications need to be converted by AutoPkg from using the drag-and-drop installation method provided by the vendor to now being installed using an installer package.
In the case of certain applications, the process of packaging can change an application which is fine when installed via a drag-and-drop installation method to one which is broken when installed via an installer package. This is due to Apple’s pkgbuild tool erroneously stripping certain metadata used by the application’s code signing. If an application is set to check for that metadata as part of its code signature verification process, this can result in the application reporting that it’s been damaged and not launching.
An example of this which I’ve run across is Labtiva’s Papers.app, a reference library application designed to collect, organize and enable citation of scientific journal articles and other reference materials. The Papers.app installation method provided by Labtiva is a drag-and-drop install, where the customer is supposed to copy the application from a disk image and into a convenient location (like /Applications.)
When the application is installed by copying it into place, there are no problems with the application and it launches normally.
When Papers.app is packaged, then installed via an installer package, an error message will appear at first launch to report that the application is damaged.
Why the difference? In the case of Papers.app, the verification of the application’s code signing appears to include verification of certain metadata which pkgbuild appears to remove as part of the packaging process. For more details, see below the jump.
The removal of the code signing metadata can be checked using RB App Checker Lite, an application designed to help developers check code signatures and receipts for OS X applications. Using RB App Checker Lite, we can compare the code signing from Papers.app which has been installed via a drag-and-drop install vs. Papers.app which has been installed using a pkgbuild-generated installer package.
Drag-and-drop
Installer package
When checked, the package-installed Papers.app shows that the code signing has been removed from a particular file:
- Papers.app/Contents/Frameworks/libtriggersync-OSX.a
In this case, the metadata which has been stripped is associated with three different code signing attributes:
- com.apple.cs.CodeDirectory
- com.apple.cs.CodeRequirements
- com.apple.cs.CodeSignature
After additional investigation with the xattr tool, it looks like some metadata is missing from two additional files as well:
- Papers.app/Contents/Frameworks/libjpeg.a
- Papers.app/Contents/Frameworks/libtiff.a
Now that it’s known which metadata is missing, the question now is how to put it back? Fortunately, the xattr tool provides the following:
- A way to export the metadata from an existing known-good instance of the code-signed file
- A way to write the exported metadata to a file which is missing it.
Exporting the metadata:
The xattr tool includes two options which assist in exporting the metadata. The -p option tells xattr to display the metadata for a particular code signing attribute and the -x option forces the attribute value to be displayed in hexadecimal format. To export specific extended attribute metadata for a code signature, you can run the command shown below:
xattr -px com.apple.cs.code_attribute_here /path/to/file
To display the com.apple.cs.CodeSignature metadata for Papers.app/Contents/Frameworks/libtriggersync-OSX.a in hexadecimal format, run the following command:
xattr -px com.apple.cs.CodeSignature /path/to/Papers.app/Contents/Frameworks/libtriggersync-OSX.a
That will produce a long string of hexadecimal format. To use stdout to export the data into a text file, run the following command:
xattr -px com.apple.cs.CodeSignature /path/to/Papers.app/Contents/Frameworks/libtriggersync-OSX.a > /path/to/filename_here.txt
The output stored in the text file will appear similar to this:
To prepare it for the next step, writing the metadata back, the line breaks need to be removed from the exported metadata. That will result in a long one-liner of data that appears similar to this:
Writing the exported metadata back to a file:
To write the metadata to a file which is missing it, the xattr tool includes two options which assist in the writing of the metadata. The -w option enables the provided data to be written as the value of the specified code signing attribute and the -x option specifies in this case that the provided data will be written in hexadecimal format. To write the metadata to a file which is missing it, you can run the command shown below:
xattr -wx com.apple.cs.code_attribute_here metadata_goes_here /path/to/file
To see how this is being applied to the com.apple.cs.CodeDirectory attribute of /path/to/Papers.app/Contents/Frameworks/libtriggersync-OSX.a, please see the link below:
https://github.com/autopkg/homebysix-recipes/blob/master/Papers/Scripts/postinstall#L22-L24
Writing this information back fixes the issue with the code signing, which in turn allows Papers.app to launch and run normally after being installed by an installer package.
To help automate this process for AutoPkg, Elliot Jordan added a postinstall script to his Papers .pkg recipe. Papers.app installer packages generated by this AutoPkg recipe will automatically fix the code-signing problem introduced by pkgbuild, by writing the correct metadata back to the necessary files as a post-installation action.
Hat tip to Elliot Jordan for both diagnosing the problem with Papers and showing how to fix the problem.