Facebook’s Design Vacuum

August 2nd, 2011

Facebook has acquired Push Pop Press, the tablet-oriented publishing company that was co-founded by one of the Mac community’s most successful young designers: Mike Matas.

I learned about the news via Lessien on Twitter, a woman about whom I know little, except that she offers reliably intelligent opinion about the tech world, and the mobile industry in particular. She shared the news with some curiosity about Facebook’s role in the deal:

Wow, although I’m a bit surprised by the buyer. Congrats to the @pushpoppress team.

It does seem a little unusual for Facebook to acquire a publishing company. But Facebook has made at least one similar acquisition recently: Sofa, the Dutch Mac developer and design firm. What interest did Facebook have in a company that sells Mac-only point of sale and developer software tools? They didn’t.

Facebook bought Sofa for their world-class design team. I expect the situation is similar when it comes to Push Pop Press. I can imagine Facebook putting Push Pop’s publishing software to some good use, but that’s just the icing on the Mike Matas cake.

Who will Facebook acquire next? Don’t let product scope cloud your crystal ball. Look for the most consistently polished user experiences in the software you use in any industry, on any platform. If it’s on Facebook’s radar, don’t be surprised to see them acquired next.

This speaks well to Facebook’s product priorities, especially as they are increasingly framed as a competitor to Google, whose design is famously underwhelming. For Facebook, setting themselves apart as purveyors of finely crafted interfaces will become a huge competitive advantage.

MarsEdit 3.3.2: Fixed Spell Checking

August 2nd, 2011

MarsEdit 3.3.2 is now available as a free update for registered MarsEdit 3 customers. New customers may purchase via the Mac App Store or directly from the Red Sweater Store.

This update addresses an annoying issue that popped up with Lion 10.7 and on Snow Leopard 10.6 when Safari 5.1 is installed: continuous spell-checking stopped working. It also improves the effectiveness of font-style changes in the rich editor, and includes a couple other minor enhancements.

  • Fix for continuous spell-checking in Rich Text editor when Safari 5.1 is installed
  • Fix a bug that prevented Font Panel size changes from applying to text
  • Fix autoconfiguration to fail more gracefully on unrecognized blog systems
  • Add “Edit With” external editor item to post list contextual menu

 

Safari Keychain Woes

July 29th, 2011

I’ve been running OS X Lion for a long time and generally enjoying it. But at some point along the line, Safari 5.1 stopped correctly inserting my keychain passwords into forms for me.

For the longest time, I assumed it was simple mistakes: I had neglected to ever approve “remember this password,” or I had somehow invalidated the password in my keychain. But recently I have come to realize that Safari is no longer auto-filling passwords for me on any site. Ever. This sucks. Usually when something like this happens, the first thing I do is “Repair Keychain” from the Keychain Access application. But in this case, the keychain is reportedly not damaged. No help.

To research this problem, I started the way I usually do: Googling it. While there are many promising search results, most of them lead to “solutions” that are not applicable to my scenario. Most commonly it seems the user has somehow ended up with the appropriate “User names and passwords” checkbox being turned off in Safari’s AutoFill preferences.

So how does a programmer like myself approach a problem like this? In recent years, Apple’s Instruments application has become an incredible asset for tracking down weird behavior not only in my own apps, but in other apps and in the system itself. I opened it up and started a new “Time Profiler” instrumentation session, targeting Safari. I know that Safari used to autofill my password whenever I typed in an account name that it recognized, so I start Instruments “sampling” Safari while I type my PayPal account name into the PayPal login page, and stop it after I’m done.

I want to figure out where Safari is failing to get my password, so I take a wild leap and assume the corresponding function call in Safari contains the word “password.” Typing this into the Instruments search box yields promising results:

Instruments

Now I know that Safari is at least making an effort to fetch the corresponding password for me. I see that it’s calling -[NSURLCredential password], which in turn calls a lower-level Keychain Services function, SecItemCopyMatching(). But why isn’t it filling in my password?

At this point I switch to gdb, where i can attach to the running instance of Safari and dig a little deeper into the issue.

% gdb
(gdb) attach Safari
(gdb) b -[NSURLCredential password]
Breakpoint 1 at 0x7fff8ddff4af
(gdb) c
Continuing.

I know from Instruments that Safari will call this method when it tries to autofill my password, so I go back to Safari and enter my PayPal ID again. Sure enough, Safari “freezes” indicating that gdb has interrupted it where my breakpoint was set. Now, I realize this isn’t for the faint of heart, but you can use gdb to effectively debug an application, even if you don’t have the source code. You just have to know a bit about how Apple’s compiler translates source code into corresponding assembly language instructions, and where the arguments are placed when calling methods.

Breakpoint 1, 0x00007fff8ddff4af in
-[NSURLCredential password] ()
(gdb) d
Delete all breakpoints? (y or n) y
(gdb) po $rdi
<NSURLCredential: 0x7ffd34d62920>: [email protected]
(gdb) po [$rdi password]
2: x/i $pc  0x7fff9192760e <gdb_class_getClass+4>:
	mov    0x20(%rdi),%rax
Can't print the description of a NIL object.
(gdb)
(gdb) p (int) [$rdi hasPassword]
$11 = 1

What I’ve done here is first delete the breakpoint, so I don’t get interrupted while poking around from gdb itself. Then, I display the NSURLCredential object’s description, confirming it corresponds to the account I’m trying to log into. Finally, I call the password method on this NSURLCredential object myself, so I can see quickly and easily what the response will be. Gdb’s objection to trying to print a NIL object confirms that the password is not being returned. I am further able to confirm with NSURLCredential’s “hasPassword” method that the keychain does have a password for this account, but it isn’t being returned.

Here we have a situation where apparently Safari is trying to get my password, but the system is vexing it. Let’s confirm by setting a breakpoint a little deeper, at the Keychain Services level that we also noticed in Instruments.

(gdb) b SecItemCopyMatching
Breakpoint 3 at 0x7fff85919582
(gdb) c
Continuing.

Breakpoint 3, 0x00007fff85919582 in SecItemCopyMatching ()
(gdb) po $rdi
{
    acct = "[email protected]";
    atyp = form;
    cdat = "2007-06-02 16:17:01 +0000";
    class = inet;
    desc = "Web form password";
    icmt = default;
    labl = "www.paypal.com ([email protected])";
    "m_Limit" = "m_LimitOne";
    mdat = "2011-07-29 15:30:15 +0000";
    port = 0;
    ptcl = htps;
    "r_Data" = 1;
    srvr = "www.paypal.com";
}

So far, so good. It looks like NSURLCredential is properly passing a set of criteria to the keychain, describing the kind of password item it’s looking for. I take a peek at the second argument to SecItemCopyMatching, which is a pointer to where the result will be stored, and then I ask gdb to continue executing until the function is complete.

(gdb) x/x $rsi
0x7fff62eb3590:	0x0000000000000000
(gdb) fin
Run till exit from #0  0x00007fff85919582 in SecItemCopyMatching ()
0x00007fff86417c29 in URLCredentialInternetPassword::copyPassword ()

When gdb returns control to me, I know the function has finished calling, so I examine the result area in memory.

(gdb) x/x 0x7fff62eb3590
0x7fff62eb3590:	0x0000000000000000

Indeed, it’s NULL! What is going on, here? I decided to dust off my Usable Keychain Scripting tool, which makes it easy to use AppleScript to search and inspect the keychain. Is the inability to access the password a system-wide thing, or just something that is vexing Safari?

tell application "Usable Keychain Scripting"
	tell current keychain
		password of keychain item "www.paypal.com ([email protected])"
	end tell
end tell

The script works perfectly, first causing the system to ask permission to authorize “Usable Keychain Scripting” to access the keychain item, and then returning the expected password string. This got me thinking, is it possible I’ve somehow got Keychain Accessing refuse access only to Safari?

When I look at the “Access Controls” for the affected keychain item, it lists Safari as one of the permitted apps. What the hell, I think. I’ll remove it from the list, and then re-add it. To try to “dislodge” something. Confoundingly, everytime I try to add it, it just silently fails to appear in the list. I am able to add any other app without an issue.

AuthorizedApps

As a quick check, I change the setting to “Allow all applications to access this item,” and save the changes. When I return to Safari and type in the login name, it instantly fills in the password for me.

My system has a functional keychain but Safari seems unable to be authorized to access it, either on a one-time basis or as a “always allow” permission. I finally got the clever idea to look at /var/log/secure.log, which frankly, I should have done about 5 hours earlier. What’s this?

com.apple.SecurityServer[33]: suppressing keychain prompt
for invalidly signed client /Applications/Safari.app(2938)

Aha! So that would explain it. Funny, I don’t remember tweaking anything inside the Safari application bundle, but this is certainly a very real example of how a broken code signature on Mac OS X can cause extremely subtle, hard to track-down “bugs.” I re-signed the applicaton on my own:

codesign -f -s - /Applications/Safari.app

When I reopened the app, and went to PayPal’s site, voila! It prompted me for permission, I approved, and now everything is back to normal.

I examined the Safari.app bundle contents to try to remember what I might have tweaked. Then my memory was jogged. I had opened and edited Safari’s Info.plist file to play around with some settings. Don’t ask, it’s an even longer story than this.

I take full responsibility for getting myself into this mess. I’ll certainly be more careful in the future to consider the implications of breaking code signatures on apps. However, I do think that the failure behavior could have been more informative. That NSLog I found in the console about refusing to prompt the user because of a broken code signature, could have been presented as a dialog that would instantly inform the user something is fishy. If my copy of Safari actually had been compromised by a nefarious individual, I wouldn’t have thought twice about continuing to enter my passwords and trying my damnedest to get Keychain to share my passwords with the compromised application.

Usable Keychain Scripting For Lion

July 29th, 2011

I’m tracking down a mysterious behavior of Safari in Lion, where it seems to fail to enter my password for logins that I’ve saved to the keychain. In the process of looking into this, I noticed that “Keychain Scripting” has mysteriously disappeared from Lion. As far as I can tell you must copy Apple’s scripting addition from Snow Leopard in order to keep using it.

On the other hand, I wrote an alternative years ago, called Usable Keychain Scripting. Its main advantage over Apple’s implementation is that it is (or at least, was) enormously faster. Today I updated the app to be 64-bit compatible and to fix a pernicious bug in which the password value returned for a keychain item would sometimes have garbage appended to the end of it.

Download Usable Keychain Scripting 1.0b4

This is not a supported product, and your success with it may vary. But it has been very handy in the past for me, and hopefully it will come in handy for you if you need to script the keychain.