Archive

Archive for the ‘Scripting’ Category

Apple Setup Assistant and First Boot Package Install Generator.app

June 22, 2016 2 comments

A while back, I built an Automator application named First Boot Package Install Generator.app. It’s designed to generate installer packages, where the generated packages in turn serve as a delivery mechanism to enable other installer packages to be installed when a Mac boots up.

As part of the process of installing the other installer packages, an application named LoginLog is supposed to open over the login window and display a log of what actions are taking place, what is being installed and whether that particular installation succeeded or not.

Screen shot 2014 10 19 at 2 39 21 pm

For the most part, this process of launching LoginLog and displaying the log works as designed but it was brought to my attention that there was one scenario where LoginLog did not appear as expected. When a firstboot package created by First Boot Package Install Generator.app was installed onto a new installation of OS X El Capitan, LoginLog did not appear over the Setup Assistant.

Screen Shot 2016 06 21 at 8 11 00 PM

The reason it didn’t appear is because the LaunchAgent for LoginLog is triggered by the Mac being at the login window.

Screen Shot 2016 06 21 at 8 04 30 PM

However, Apple’s Setup Assistant on El Capitan no longer runs over in the context of the login window. Instead, it runs in the context of an account named Setup User.

Screen Shot 2016 06 21 at 8 07 23 PM

In order to have LoginLog appear again in this scenario, I needed to develop a method which could accomplish two tasks:

  1. Suppress Apple’s Setup Assistant during the time when I wanted the LoginLog application to appear.
  2. Avoid interfering with an otherwise desired launch of the Apple Setup Assistant.

For more details, see below the jump.

Read more…

Diagnosing and fixing code signing issues for applications installed by installer packages

June 6, 2016 Leave a comment

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.)

Screen Shot 2016 06 05 at 6 16 42 PM

 

When the application is installed by copying it into place, there are no problems with the application and it launches normally.

Screen Shot 2016 06 05 at 1 55 34 PM

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.

Screen Shot 2016 06 05 at 4 58 14 PM

 

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.

Read more…

Migrating OS X Macs from one Apple push notification certificate to another using Casper

April 27, 2016 Leave a comment

As mentioned previously, I needed to migrate my Casper server from using the Apple Push Notification Service (APNS) certificate generated by one Apple ID to now using another APNS certificate generated by another Apple ID.

This project is fairly straightforward, thanks to a couple of factors:

  1. The Casper server in question is managing only OS X devices.
  2. I have a way to identify via a Casper Extension Attribute which Macs have MDM profiles associated with the APNS certificate which is no longer active.

I was able to set up a Casper smart group to look for machines that fit the following criteria:

  • Criteria: Extension Attribute name (In this case, the EA is named Apple Push Notification Service certificate identifier.)
  • Operator: Like
  • Value: com.apple.mgmt.External.uuid_of_former_apns_certificate_goes_here

Screen Shot 2016 04 27 at 11 10 04 AM

Screen Shot 2016 04 27 at 11 20 45 AM

Screen Shot 2016 04 27 at 11 21 59 AM

From there, I set up a policy that is scoped to run on the members of that smart group. For more details, see below the jump.

Read more…

Checking the Apple Push Notification Service certificate identifier used by MDM profiles

April 26, 2016 Leave a comment

A few years ago, I set up my Casper server with an Apple Push Notification Service (APNS) certificate. That by itself is not remarkable, but the way I did it would be frowned upon these days. That’s because I used an Apple ID tied to my work email address to generate it.

The reason that I did this was that back then, you needed to have a paid membership in the Apple iOS Developer Program in order to get an APNS certificate. I was not part of an enterprise team, so the Apple ID I was using to log into my ADC account was tied to my own work email address. Consequently, I generated my initial APNS certificate for my Casper server using an Apple ID tied to my work email address.

Fast forward to 2016 and the world of the Apple Push Certificates Portal, where it’s no longer necessary to have an Apple Developer Connection account to have an APNS certificate. In fact, it’s not a great idea at all because people come and go, but hopefully the Apple ID used to generate your APNS certificate (also known as an MDM certificate or push notification certificate) does not. That’s because you can’t transfer an Apple ID to another email address and only the Apple ID used to generate your initial APNS certificate can generate the new certificate needed for the annual APNS certificate renewal.

For iOS devices, where everything is managed via MDM, changing the Apple ID used to generate your APNS certificate means that you are going to have to re-enroll all of your devices. This is usually a sizable effort and one that should be avoided if at all possible.

For OS X devices, where MDM-only management is still fairly rare, changing Apple IDs (and APNS certificates) is less problematic. You will also need to re-enroll your devices but it should be possible to use alternate means to remove your old MDM profile(s) and make the Mac pull down a new set of MDM management profiles that would incorporate the new APNS certificate for the Mac’s push notifications.

Fortunately, I’m in the situation of having to change out my Apple ID and APNS certificate only on OS X devices. These devices are also managed by my Casper server, so I can automate a fix for the issue using a script like the one below:

However, I still had one issue – identifying which machines had the “old” MDM profiles associated with the APNS certificate which I was trying to move away from. For details on how this was addressed, see below the jump.

Read more…

Identifying FileVault 2 institutional recovery keys on OS X El Capitan

April 10, 2016 Leave a comment

On OS X 10.9.0 – 10.11.x, you can run the following command to verify if a FileVault 2-encrypted Mac is using an institutional recovery key (IRK) as a valid recovery key.

fdesetup hasinstitutionalrecoverykey

If FileVault 2 is using an IRK, this command will return true.

Screen Shot 2016 04 10 at 4 20 04 PM

Otherwise it will return false.

Screen Shot 2016 04 10 at 4 03 57 PM

As part of the release of OS X 10.11.2, a new function was added to fdesetup‘s hasinstitutionalrecoverykey verb. Now, in addition to identifying whether or not FileVault 2 on a particular Mac has an institutional recovery key, a new -device option has been added which outputs a SHA-1 hash in hexadecimal notation of the IRK’s public key. This helps Mac admins answer two questions about institutional recovery keys:

  1. Is an IRK being used as a valid recovery key on this Mac?
  2. If an IRK is in use, which one is being used?

The -device option needs to be supplied with an identifier for the encrypted drive in question. This can be in the form of a BSD device name ( /dev/diskX ), the mount path ( /Volumes/Macintosh HD or ), or a UUID for the Logical Volume or Logical Volume Family of a CoreStorage volume.

To display the hash for an IRK’s public key on the Mac’s boot volume, run the command below with root privileges:

fdesetup hasinstitutionalrecoverykey -device /

It should output the hash of the IRK’s public key in hexadecimal notation.

Screen Shot 2016 04 10 at 4 19 21 PM

This value should be consistent across all FileVault 2-encrypted Macs which are using this IRK, so it should help Mac admins identify if a particular Mac is set up with the correct FileVault 2 institutional recovery key (or keys) used by their shop.

To assist with this, I’ve written a script to report the hash of the IRK’s public key. For more details, see below the jump.

Read more…

Checking XProtect and Gatekeeper update status on Macs

March 28, 2016 9 comments

As part of making sure that XProtect and Gatekeeper are providing up-to-date protection, it can be worthwhile to see when your Mac received the latest updates from Apple for both XProtect and Gatekeeper. As both are background processes, as well as also receiving Config Data updates silently in the background, it’s not always obvious when updates have been applied.

To assist with this, I’ve written a couple of scripts to report the last time that Gatekeeper and XProtect have been updated on a particular Mac. For more details, see below the jump.

Read more…

Running processes in OS X as the logged-in user from outside the user’s account

March 25, 2016 2 comments

One challenge that can crop up for Mac admins is the problem of running a script or other tool with root privileges and using it to launch and run another tool, script or application as if the logged-in user had launched it. An example of this would be installing Dropbox using an installer package, then launching the Dropbox application as the logged-in user as a post-installation task. One reason to do so would be to give the user the opportunity to sign into their Dropbox account.

To accomplish this task, Apple has provided functionality in the launchctl tool.

For 10.9.x and earlier, launchctl‘s bsexec function was used for this purpose. bsexec allows you to start a process like a tool, script or application in a specific context. One way to get the correct context for the logged-in user is to identify the process identifier (PID) for the loginwindow process associated with the logged-in user, which can be accomplished by using the command below:

ps auxww | grep "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow" | grep logged_in_username_here | grep -v "grep" | awk '{print $2}'

For example, if I logged in with an account named username, running the command shown below should provide the PID for the username account’s loginwindow process:

ps auxww | grep "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow" | grep username | grep -v "grep" | awk '{print $2}'

Screen Shot 2016 03 25 at 1 08 11 PM

 

Once the PID has been identified, it can be used to identify the context that I want to start a process in. For example, the commands below can be run with root privileges to first identify the correct PID for the username account’s loginwindow process, then launch Safari as the username account using the open command:

ps auxww | grep "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow" | grep logged_in_username_here | grep -v "grep" | awk '{print $2}'
launchctl bsexec PID_number_here open "/Applications/Safari.app"

Screen Shot 2016 03 25 at 1 17 19 PM

 

Screen Shot 2016 03 25 at 1 19 46 PM

 

When we check the process list for which account is was launched from, the Safari process should show up as being run by the username account.

Screen Shot 2016 03 25 at 1 18 37 PM

 

If you wanted to automate opening Safari as the logged-in user, you could run a script like the one below with root privileges:

Starting in OS X Yosemite, Apple made a number of changes to the launchctl tool and added a new asuser function. The asuser function is designed to take the place of the bsexec function, in the context of starting processes in the context of a specific user account. This makes it easier, as you now just need to figure out the username and do not have to figure out the PID of the user’s loginwindow process.

You can identify the user by either the user’s account name, or by the account’s UID. One way to identify an account’s UID is to use the id command as shown below:

id -u username_goes_here

To continue with the example of opening Safari, you can run the commands below to first identify the correct UID, then launch Safari as the username account using the open command:

id -u username_goes_here
launchctl asuser username_uid_goes_here open "/Applications/Safari.app"

 

Screen Shot 2016 03 25 at 2 09 27 PM

Screen Shot 2016 03 25 at 2 07 21 PM

 

Screen Shot 2016 03 25 at 2 49 03 PM

If you wanted to automate opening Safari using the logged-in user’s UID, you could run a script like the one below with root privileges:

As mentioned earlier, you can also use just the account name with launchctl‘s asuser function. In that case, you can run the command below to launch Safari as the username account using the open command:

launchctl asuser username_goes_here open "/Applications/Safari.app"

If you wanted to automate opening Safari using the logged-in user’s account name, you could run a script like the one below with root privileges:

%d bloggers like this: