As mentioned previously, we deploy a custom Safari Toolbar with links to various sites to our Macs.
With the release of Safari 6.2 & 7.1 Apple has changed the method to install extensions, once a Mac has been updated to Safari 6.2 or 7.1 the user is prompted to “migrate” their extensions.This change breaks the previously posted method to install extensions, as the installed extensions list is now in the users Keychain (!?).
Below is how to install extensions via Self Service, which in testing works for all Safari versions & allows the user to reinstall if they recreate their login.keychain.
Keychain?! That’s whackadoodle!*
It took me sometime to figure out how extensions get installed once Safari 6.2 & 7.1 have been installed. My usual approach of using Composer & “monitor file system changes” only led to an array being populate in ~/Library/Preferences/com.apple.Safari.plist similar to the below. (See the “com.mycomany.extension-myDeveloperID identifier” string).
Scripting this change, only added the extension into Safari’s list of extensions to be enabled, & doesn’t enable the extension.
Digging around, I stumbled across a new entry in my login.keychain called “Safari Extension List”
Running the below will show you the contents of this application password, (SPOILER: it’s not pretty).
security find-generic-password -l "Safari Extensions List" -g
After looking through the above commands output & realising that even if I could cobble together a method that would add an entry to this key, it would then be removed whenever a user forgets their password & has to reset their login.keychain.
So, I decided to instead mirror what Apple expects leveraging Self Service for the install.
Self Service Install
So the below basically recreates the method of someone downloading an extension themselves & then double clicking it to get the below prompt:
If you’re running the below via a Self Service policy, you can specify the path to the Extension as $4 in the policy. Else you can hardcode the location (this script added as a pkg as a post flight may work with Munki’s Managed Software Center etc…).
NOTE: Do not place the extension in ~/Library/Safari/Extensions, as this will error if Safari is installing it when it has not been installed before. As an example, we put ours in /private/tmp/. A copy of the extension can be in ~/Library/Safari/Extensions, you just can’t install it from there.
Updating The Extension
With all of this, I was worried about updating the extension. Well, it appears that just replacing the extension in ~/Library/Safari/Extensions works fine.
However, I’m not sure if Apple with further tighten extensions & therefore a method more like that outlined here might be worth looking at.
*credit to Rich Trouton for the exclamation on IRC.
Thanks for the update – I had recently come across your older version, and was rather annoyed (with myself) when I couldn’t get it to deploy properly. That is until I found out about the Keychain changes elsewhere and realized the ~/Library/Safari/*.plist method was’t working anymore. Tested and this works nicely now.
One other note – the code on your website isn’t displaying on Chrome, OS X 10.9.5 ver. 38.0.2125.104.
Thanks. Reached out to the plugins author of the plugin I use to link to GitHub.. hopefully it can be fixed soon.
Thanks for your hard work figuring this one out. Apologies if this reply is in error. I am having the same issues, deploying an extension that used to work just by placing it in ~/Library/Safari/Extensions. You mention by running the script below, but I didn’t see one? Any help would be greatly appreciated.
Yep, as John mentioned about Chrome 38 isn’t showing the github stuff.. Safari works.
Thanks for the info. I have an issue in finding out where the safari extension state(enabled/disabled) is stored if I toggle between enabling and disabling. Any help would be greatly appreciated.
Closest I found to your answer is this:
http://stackoverflow.com/questions/24241198/where-is-the-details-of-extension-of-safari-8-is-stored-in-yosemitemac-os-10-10
Sadly, it’s written into the users keychain. Which is not easily readable.. (Perms & prompts fornaccess etc)
Thanks I got to know how to get it.
Cool.
Would you mind sharing?
The way I found it is through some coding. It will be stored as a password in the keychain item Safari Extensions List. Try to get the safari extension password using the command security find-generic-password -l “Safari Extensions List” -g
From the output of the command, copy only the password string, remove the prefix 0x.
convert this string to nsdata or nsmutabledata and then use NSPropertyListSerialization propertyListWithData method. The output of the method is a dictionary, where extension names and their states are stored.
and how did you then use this data to write the on/off state?
Is there any way to find out the version number of the installed extension using objective-c or applescript? Any code snippet is much appreciated.