Mac OS X

Of Flash Player versions and codesigning and signatures

It’s certainly an understatement to say that there’s been a lot of talk about the Adobe Flash Player on Apple platforms in the last year. On Mac OS X, Apple bundles the Flash Player and tends to distribute some — but not all — updates to it.

I wanted compare the bundled Flash Player version against the latest version from Adobe, which is currently v10.1.82.76. So, let’s look at what comes with Snow Leopard from the perspective of a codesigned executable.

# Flash Player version 10.0.45.2
# Installed with Mac OS X Snow Leopard v10.6.4
$ codesign -vvv /Library/Internet\ Plug-Ins/Flash\ Player.plugin
/Library/Internet Plug-Ins/Flash Player.plugin: valid on disk
/Library/Internet Plug-Ins/Flash Player.plugin: satisfies its Designated Requirement

A quick look at the bundled plugin shows that it is codesigned. This means that it has a known signature. If the executable is modified, the signature will no longer be valid. The signature is tied to the identity of a signing authority, which is generally the source of the software.

It may be helpful to think of codesigning as a tamper-resistant seal from the manufacturer. It’s not going to protect you from lots of different kinds of vulnerabilities, but if its cryptographic signature is intact and valid, you have a good idea that the software hasn’t been modified by a third party.

Mac OS X Leopard and Snow Leopard have shipped with applications signed by Apple. The Flash Player plugin comes from Adobe. So, who signs the bundled Flash Player?

$ codesign -dvvv /Library/Internet\ Plug-Ins/Flash\ Player.plugin
Executable=/Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player
Identifier=com.macromedia.Flash Player.plugin
Format=bundle with Mach-O universal (i386 ppc)
CodeDirectory v=20100 size=34023 flags=0x0(none) hashes=1694+3 location=embedded
CDHash=f81bb75e4ec6f085f59e3c21021136c0f974fa7a
Signature size=4064
Authority=Software Signing
Authority=Apple Code Signing Certification Authority
Authority=Apple Root CA
Info.plist entries=12
Sealed Resources rules=9 files=2
Internal requirements count=1 size=188

You’d be forgiven for not having your eye drawn to the answer immediately, but it’s right there on the “Authority” lines. Just as with the rest of Mac OS X, Apple signed the Flash Player plugin they bundled with the OS.

Now, let’s upgrade the plugin to the latest version available from Adobe and see what happens to the signature. Courtesy of Preston’s WatchedInstall tool, we can see that the plugin’s CodeResources file is removed during this upgrade. Interestingly, the “Adobe Flash Player Install Manager” application installed with the update is codesigned.

- /Library/Internet Plug-Ins/Flash Player.plugin/Contents/CodeResources
- /Library/Internet Plug-Ins/Flash Player.plugin/Contents/_CodeSignature/CodeResources
+ /Applications/Utilities/Adobe Flash Player Install Manager.app/Contents/CodeResources
+ /Applications/Utilities/Adobe Flash Player Install Manager.app/Contents/_CodeSignature/CodeResources

The newer Flash Player version, however, seems to consist of two new plugins contained within the overall structure of a parent plugin. Neither the parent nor the new applications within the same bundle install a new code signature. This results in three unsigned executables:

# Flash Player version 10.1.82.76
# Installed on Mac OS X 10.6.4
$ codesign -vvv /Library/Internet\ Plug-Ins/Flash\ Player.plugin
/Library/Internet Plug-Ins/Flash Player.plugin: code object is not signed
$ codesign -vvv /Library/Internet\ Plug-Ins/Flash\ Player.plugin/Contents/PlugIns/FlashPlayer-10.6.plugin
/Library/Internet Plug-Ins/Flash Player.plugin/Contents/PlugIns/FlashPlayer-10.6.plugin: code object is not signed
$ codesign -vvv /Library/Internet\ Plug-Ins/Flash\ Player.plugin/Contents/PlugIns/FlashPlayer-10.4-10.5.plugin
/Library/Internet Plug-Ins/Flash Player.plugin/Contents/PlugIns/FlashPlayer-10.4-10.5.plugin: code object is not signed

Therefore, you trade the known security vulnerabilities of the older version of Flash Player bundled with the operating system with a different kind of security problem with the new version. It would be silly to not make that trade if you are browsing the Web at all on a Snow Leopard-based computer.

However, it’s also difficult to understand why a large corporation with the resources of Adobe cannot codesign a piece of software as critical to the Mac OS X browsing experience as the Adobe Flash plugin is — especially when its “Install Manager” application is signed.

It’s also puzzling why Apple continues to trail well behind the latest releases of Flash Player. Add to that mystery the question of why Apple never updates the absolutely antique bundled version of the Shockwave Player plugin.

Get the display resolution on Mac OS X with PyObjC

I came across this hint about display properties on StackOverflow and thought it was worthwhile to write down for later. If you want to get the screen or Desktop resolution of a Mac via Python, you can do so with PyObjC.

First, let’s get the information about the main screen:

>>> from AppKit import NSScreen
>>> print(NSScreen.mainScreen().frame())
<NSRect origin=<NSPoint x=0.0 y=0.0> size=<NSSize width=1920.0 height=1200.0>>

If you want just the horizontal and vertical resolution from that blob of data, you can pull the width and height out:

>>> print(NSScreen.mainScreen().frame().size.width)
1920.0
>>> print(NSScreen.mainScreen().frame().size.height)
1200.0
>>> width, height = NSScreen.mainScreen().frame().size.width, NSScreen.mainScreen().frame().size.height
>>> width, height
(1920.0, 1200.0)

This might be useful in situations where you don’t have any of the “hundred of portable libs in Python that give you access to that information” — such as in your stock Mac OS X Python installation. To clarify: I’m in no way meaning to belittle that there are portable libraries that would let you do the same thing, but you also have to program for your audience and its constraints. One of the reasons I appreciate Python over some scripting languages is that you get so much capability in the Standard Library. However, on Mac OS X, you don’t get modules like pygame by default (yet … and maybe never) while you do get PyObjC.

Generate version numbers for Mac OS X package installers with Mercurial and Semantic Versioning

I’ve had occasion to create some installer packages lately, and the topic of assigning a version number to them has rattled around in my head. The version number of an installer package is shown in the Finder’s Get Info windows, and in the preview pane of column view, so it has some usefulness just for telling one installer apart from another. And, importantly, the version number provides a way for Installer to determine whether a package has previously been installed and simply needs to be upgraded.

At first, I was just going to assign the date in YYYYMMDD format as the version, just to “keep things simple” by using:

$ date +%Y%m%d
20100324

Then I was rebuilding the packages several times a day, and wanted to distinguish between the builds, so I switched to YYYYMMDD.hhmm.

$ date +%Y%m%d.%H%M
20100324.2240

This seemed ridiculous after a day. Although I could distinguish between builds, the installers I was building weren’t really changing per se. They were the same payload and scripts and resources, just rebuilt by the command line packagemaker tool using The Luggage.

I crowdsourced my question about versioning, and Steve Losh helpfully responded with the idea to use Mercurial tags along with Semantic Versioning.

My package sources are already checked into Mercurial repositories, so this made a good deal of sense. It meant that I’d have to use tags to identify a version number — it would no longer be as automatic as using the current date. However, certain parts of the version string would be automatic, and the only manual part would be tagging revisions in Hg.

I had already bookmarked Semantic Versioning a while back, but had forgotten about it and never done much of anything with it. If I followed the Semantic Versioning standard, I’d create a “semver” tag to set up the repository, and then a new “vX.Y.Z” tag for actual releases thereafter. Steve further suggested the use of the “latest tag distance” and “short node hash” for the Hg revision, and that information is automatically available from Hg.

Semantic Versioning states, “when tagging releases in a version control system, the tag for a version MUST be ’vX.Y.Z’ e.g. ’v3.1.0’.” I felt I would have to strip the “v” from the version tag to use it cleanly as a package version. This results in commands like the following, where I’ve used sed to remove that character:

# Full Semantic Version with further identifying information from Mercurial
$ hg log -r. --template '{latesttag}+{latesttagdistance}-{node|short}\n'
v1.0.0+1-df34ebfc12c9
# Strip the "v" with sed
$ hg log -r. --template '{latesttag}+{latesttagdistance}-{node|short}\n' | sed -e 's/^v//'
1.0.0+1-df34ebfc12c9
# Basic Semantic Version
$ hg log -r. --template '{latesttag}\n'
v1.0.0
# Strip the "v" with sed
$ hg log -r. --template '{latesttag}\n' | sed -e 's/^v//'
1.0.0

This is something I can build into makefiles for use with The Luggage, so I’m going to try it out. On first glance, I think it even fits in nicely with the concept of The Luggage. It automates much of the version-assignment process. And, it takes advantage of version control for both repeatable results and peer review.

Local logins succeed but network logins fail on an Active Directory bound Mac OS X Leopard system

I came across an interesting “problem” with Active Directory binding on Mac OS X Leopard. The symptoms were:

  • No Active Directory user accounts could log into the computer from the loginwindow.
  • Some of the attempted logins involved cached mobile accounts from the Active Directory.
  • The account login failures happened even though loginwindow’s “network accounts are available” indicator was green.
  • The login problem persisted it the computer been unbound and rebound to the domain.
  • The same Active Directory users could log in on other Macs.
  • Local users could log in to the affected computer.
  • Using “su” to switch users from a local user to an Active Directory user worked in Terminal.
  • Lookups using “dscl” and other DirectoryService tools worked.

Since I’ve written (what seems like a) a book about Active Directory troubleshooting, I threw the book at this problem. It ended up taking quite some time to troubleshoot, and the answer ended up being very simple. However, it wasn’t on my normal list of culprits.

The biggest clue I found, besides the symptoms above, was that the DirectoryService debug logs yielded this during Active Directory logins from loginwindow:

2010-02-24 21:33:37 EST - T[0xB0103000] - mbrmig - Dispatch - Membership -
is user jaharmi member of group GUID 3BBC71F5-3497-4494-904B-8AC3E25CCA52 =
false

It didn’t seem like a smoking gun, but I’d never come across this “false” response on a bound system before. So, what group was so important to the login process that the DirectoryService debug logs cared enough to note the failure? I was darned if I knew, and I had no other promising clues at that point.

So, I investigated that group further, and found it by its UUID using dsmemberutil:

$ dsmemberutil getid -X 3BBC71F5-3497-4494-904B-8AC3E25CCA52
gid: 200

Well, that helped a little, but the name would have helped a lot more. I had to find which group corresponded to the GID of 200. That GID was not at all familiar to me, but it was under 500, so there was a pretty good chance it came from Mac OS X.

$ dscl /Local/Default -list /Groups PrimaryGroupID | awk '$2 == 200 { print
$1; }'

com.apple.access_loginwindow

This was my eureka! moment. I wasn’t entirely sure, but I was pretty confident that the “com.apple.access_loginwindow” group was the access control list group for the loginwindow process. Loginwindow controls all graphical logins to Mac OS X, and is the parent process of each GUI login session.

Looking up the group’s description confirmed that it was the ACL group. I did the lookup in Workgroup Manager, which was set to view the DSLocal directory service. While I was there, I also checked the membership: it listed only the computational group “localaccounts.” The “localaccounts” group is essentially a query that returns all accounts in the local directory service.

Well, that would certainly prevent Active Directory users from logging in with loginwindow. The ACL consulted the membership of the “com.apple.access_loginwindow” group to determine who was allowed to log in via the GUI. Because it contained only the “localaccounts” group, the ACL was preventing all non-local users from logging in.

WorkgroupManager-loginwindowacl-localaccountsonly-20100224.png

Not knowing how this group was handled or even what had last edited it, I compared the affected system to a different AD-bound Leopard computer, which also had Workgroup Manager. (It’s handy to have the Mac OS X Server Admin Tools deployed out to your computers even if you don’t have a server to maintain.) The second computer didn’t have the group at all, which perplexed me a bit.

However, that made me reasonably sure I could simply delete that group. I backed it up from the filesystem at the command line, just to make sure, and then deleted it with Workgroup Manager on the affected computer.

After that, logins for all Active Directory accounts I tried proceeded normally at the loginwindow on that system.

With the problem solved, I sought more information about the workings of the “com.apple.access_loginwindow” group. I confirmed that it is created when the “Allow network users to login in at login window”
option is turned on in System Preferences > Accounts > Login Options. This should be turned on by default, and that initial state results in no “com.apple.access_loginwindow” group at all.

SystemPreferences-accounts-allownetworkusers-20100224.png

Since the option is on by default, the really simple solutions to this kind of problem are:

  1. Don’t turn off the “Allow network users to login in at login window” option in System Preferences > Accounts > Login Options.

    SystemPreferences-accounts-disablenetworkusers-20100224.png

  2. If “Allow network users to login in at login window” has been turned off, either:
    1. delete the group named above, or
    2. toggle the option back on.

Deleting the “com.apple.access_loginwindow” group removes it completely and reinstates login capability for both local and network user accounts.

Toggling the System Preferences option back on, adds the “netaccounts” group to the “com.apple.access_loginwindow” group, reenabling login for both local and network users. It does not, however, remove the group “com.apple.access_loginwindow,” which remains on the system afterwards.

Here's what that looks like in Workgroup Manager:

WorkgroupManager-loginwindowacl-localandnetaccounts-20100224.png

To prevent this on managed clients, I could see a system administrator proactively creating and managing the membership of the “com.apple.access_loginwindow” group. To ensure that managed clients bound to an Active Directory allow both local and network users to log in, make sure the group is populated with the appropriate nested groups: “localaccounts” and “netaccounts.”

Access to this item is restricted

I had an odd situation over the weekend that resulted in the inability to view the passwords associated with keys in my Mac OS X user keychain. Every time I clicked on the “Show password” checkbox in a key’s detail window, I’d get an “Access to this item is restricted” dialog.

Needless to say, this was disconcerting. I happened to have a lot of data in that keychain — this is what I get for keeping the same one around since Mac OS X 10.0 or 10.1. While I could revert to a backup, the newest backup wasn’t as recent as I would like. Plus, I just wanted to know why the problem had cropped up.

So, I asked about my problem on the Apple-CDSA mailing list. If anyone would be able to help with the obscure corners of keychains, I figured the people there would.

Very promptly, I got a reply from Ken McLeod, which led me to check the validity of the code signature on the Keychain Access utility.

$ codesign -vvv /Applications/Utilities/Keychain\ Access.app
/Applications/Utilities/Keychain Access.app: code or signature modified

Clearly, the signature and the application didn’t match. Something was amiss.

I reinstalled Mac OS X 10.6.2 on the system, using the latest combo update installer package, and cleared up the problem signature mismatch.

$ codesign -vvv /Applications/Utilities/Keychain\ Access.app
/Applications/Utilities/Keychain Access.app: valid on disk
/Applications/Utilities/Keychain Access.app: satisfies its Designated Requirement

In retrospect, although I wouldn’t have thought of this being a problem, this breakage between the signature and the app — and its affect on my ability to view stored passwords — gives me confidence that thought has been put into the code signing mechanism in Mac OS X. You wouldn’t want a compromised app displaying your unencrypted keychain items, after all.

Find Info.plist files for applications on Mac OS X

There is some important information in the Info.plist files contained in Mac OS X applications. But, some of that information isn’t really standardized — I’m looking at all of you, you crazy version number and vendor attributes (just the ones I'm interested in!). So, given that, how do you find them all to make comparisons between Apple and third-party apps?

Answer: You can use the “find” command to find all of the Info.plist files for applications in your /Applications directory.

$ find /Applications -name Info.plist -ipath /Applications/\*.app/Contents/Info.plist -depth 3 -print 2>/dev/null

Since that intentionally limits the depth traversal, you could modify it slightly to support finding Info.plists in your /Applications/Utilities directory, as well. However, I would say it’s less likely you’ll be dropping third-party applications in the Utilities directory, so you might not care.

Finding and viewing the Test Print document in Mac OS X Leopard

When you have the print queue window open for a printer in Mac OS X Leopard, the Printer menu > Print Test Page command is active. That command sends the CUPS test page to the selected print queue.

The test page file itself is a PostScript document located at this path:

/usr/share/cups/data/testprint.ps

Since Leopard — like Mac OS X versions since Panther, has a built-in PostScript interpreter — you can open up this PostScript document and have it rendered as a PDF. By default, it will be sent to the Preview application.

It’s helpful to be able to view this document on-screen, so you can see what it is supposed to look like, in case your printer is not working as intended. You can compare the on-screen results with the printed output to verify how well your printer is working.

Mac OS X Service to create the man page URL for a command

Mac OS X has a type of URL specifically for opening UNIX man pages. For me, using one of these URLs opens a new Terminal window to display the man page. Just put the name of the man page after the “x-man-page://” URL scheme to create one of these URLs.

For example, a link to the rsync man page would look like “x-man-page://rsync” when written out.

This is a handy way to refer to UNIX man pages with other Mac OS X users in e-mail correspondence, on mailing lists, or on the Web. Because of that, I wanted a quicker way to create these man page URLs. I wrote the Mac OS X Service named “Man Page URL for Command” to satisfy that desire. The “Man Page URL for Command” Service is provided “as-is” with no warranty.

The Service was wrapped up with ThisService by Peter Hosey, as with my earlier Mac OS X Service to shorten a URL with Bit.ly.

To install the Service:

  1. Unzip the downloaded file.
  2. Drag the unzipped Service to /Library/Services (for all users) or ~/Library/Services (for just the current user).

To use it:

  1. Select a single word from some text you can highlight in an application. The word should ideally correspond to the name of a general UNIX command (“ls”), a Mac OS X-specific command (“dsmemberutil”), or another term the matches a man page (“sshd_config”). The Service is specifically coded to work only when you select a single word; if you select a text string with any white space in it, the Service will just return your original text. The Service also checks to ensure that the selected word corresponds to either a command in the $PATH or an existing man page, so it will not generate a “x-man-page://” for just any word.
  2. Choose “Man Page URL for Command” from the Services submenu of the application menu. As long as you have selected only a single word that matches a command or existing man page, the selection will be replaced with the “x-man-page://” URL.

Thanks to Nigel for the inspiration.

AttachmentSize
ManPageUrlForCommand.zip34.45 KB

Mac OS X Service to shorten a URL with Bit.ly

Since the Bit.ly URL-shortening service is all the rage lately, and I hadn’t seen anyone create a Mac OS X Service for it yet, I decided to try my hand at it.

Here’s the result. The core is a relatively simple Python script and requires Mac OS X 10.5 (or Python 2.5 if you have an earlier version of Mac OS X). The Service was wrapped up with ThisService by Peter Hosey. It’s my first attempt at creating a Mac OS X Service — with or without ThisService — and I hope it works for you. However, it is provided “as-is” with no warranty.

That said, if you have comments or suggestions, please feel free to contact me.

Also, I’m not counting this as an endorsement of Bit.ly; I just looked at info on their site and thought I could probably script it and, as you can see, I did.

To install the Service:

  1. Unzip the downloaded file.
  2. Drag the unzipped Service to /Library/Services (for all users) or ~/Library/Services (for just the current user).

To use it:

  1. Select the full text of an “http” or “https” URL that you’d like to shorten. (Don’t just select a site’s domain name. The Service is specifically coded to work on full URLs starting with “http” or “https.” So, “www.jaharmi.com” will not work but “http://www.jaharmi.com” will.)
  2. Choose “Shorten URL with Bit.ly” from the Services submenu of the application menu. The selected URL will be replaced with the text of the shortened URL from Bit.ly. If it is not, the original URL will remain.

Of special note, however, is that if you shorten URLs with Bit.ly this way rather than through your browser, you probably won’t see them show up in your history (the most recent 15 URLs you’ve shortened). The script just shortens URLs for you and does so outside of your browser, so whatever cookies or other tracking Bit.ly is doing to generate your history, it doesn’t appear to carry over when using this simple little Service.

AttachmentSize
ShortenUrlWithBitly.zip34.17 KB

Mac OS X keychain and password storage

I’ve found that trying to explain the Mac OS X keychain at all tends to make peoples’ eyes glaze over. The keychain is poorly-understood overall, perhaps because it tries to bridge the gap between security and convenience.

A few thoughts:

  • A keychain has its own password which may or may not be set to the same as the password for the login account.
  • The keychain password is completely independent of the login account’s password, even if it is the same text as the login account’s password. They can be changed independently. When they are the same, they are just two passwords which happen to be the same.
  • User keychains are created within user home directories, and are protected by file system permissions while they are enforced.
  • Keychain keys are further protected by 3DES encryption. Directory or metadata information is in cleartext.
  • The Mac OS X Setup Assistant and Accounts System Preferences both create accounts whose login passwords and keychain passwords will match.
  • If the password is shared between the login account and that account’s default keychain, the keychain will be unlocked during the login process. This is the default for accounts created by the Mac OS X Setup Assistant and Accounts System Preferences.
  • If the default keychain’s password does not match the login account’s password, the keychain will not be unlocked automatically during the login process. The user may be prompted to unlock it, using the keychain password, if other applications require a key stored within.
  • The only time that a password change for a login account changes that user’s default keychain password is when the login account is logged in and changes its own password through Accounts System Preferences.
  • If the computer is bound to a directory service, a login account may be tied to that. However, the keychain is not. Changing the login account’s password through a directory service does not reset the keychain’s password. The keychain’s existing password will remain until or unless it is changed.
  • A third-party software utility, Keychain Minder, can help to keep login and keychain passwords in sync, if desired. This may be especially helpful in a directory service environment, where you are more likely to change account passwords externally rather through Mac OS X’s built-in means. It also provides an opt-out capability for those who specifically want different login and keychain passwords.
  • If the computer is bound to a directory service, and a directory service-based login account was compromised, there is a chance that the password for the default keychain in that account is also compromised. Changing the password for the login account in the directory service will protect the login account. However, that will not necessarily protect the keychain stored within the account’s home directory on disk. Whether or not the keychain password was the same as the former password for the login account — the keychain’s password should probably also be changed.
  • The long-term use of the same password for a keychain can be a risk; as it gets stale, it lessens the protection on each key in the keychain.
  • There is currently no policy enforcement mechanism, akin to pwpolicy, for keychain passwords.
Syndicate content