MacOS – How to disable SSH KeychainIntegration in OS X Mavericks

keychainmacosssh

I'm having some issues with SSH KeychainIntegration in OS X Mavericks. I've tried poking around Apple's support site, but haven't seen anyone having my issue. I have seen lots of people who seemingly don't know how to use SSH that well, so I decided to try another community.

First, my configuration is working. I am able to use my key pair and ssh to hosts as I need to, with my credentials being cached in the agent. I am able to see my cached credentials via "ssh-add -l", as expected. I am prompted to input my password by an OS X-style dialog, with a checkbox that says "Remember password in my keychain". I usually ignore this checkbox, but when I check it, I do see my key stored in the keychain. This key stored in the keychain is seemingly never used, however, since I have a password on it. At least that's what I've gleaned from various things I've read. When I enter my password into the dialog, and the key is cached in the agent, I successfully connect, but not before being told "Saving password to keychain failed". Seeing this error message is what led me to investigate further; I don't like getting an error every time I connect.

Things get interesting when looking at the manpage SSH_CONFIG(5). Two options for dealing with the keychain exist, specific to Apple: AskPassGUI, and KeychainIntegration. You're able to toggle these in ~/.ssh/config, and doing so yields some interesting results.

Setting AskPassGUI to no, you'll no longer be prompted with an OS X-style dialog, instead an input text line in your terminal. No biggie. But if you do this, then ssh-agent will not cache your credentials. This is plainly broken, and frustrating because I could easily live with the text prompt if the credentials were cached.

Setting KeychainIntegration to no, ssh throws a hard error, as follows:

~/.ssh/config: line 11: Bad configuration option: KeychainIntegration
~/.ssh/config: terminating, 1 bad configuration options

My question, simply, is this: Is there a way to actually disable OS X Keychain Integration for SSH?

Best Answer

Based on the source code for the current version of SSH that's shipping with Mavericks (located here), it appears that the functionality of the config option KeychainIntegration has not yet been implemented. I'm making this assumption based on the contents of openssh/readconf.h, which does not reference the KeychainIntegration option. It does, however, reference the askpassgui option. Checking the "keywords" struct in that file does indeed show that the keychainintegration option is not present (which in turn implies that the oBadOption (NULL) op code would be returned).

Another clue implying that the functionality you desire is not implemented in the way the man page specifies is the file: openssh/keychain.c. The source code actually shows that the defaults system (i.e., Property List files) is being used to store settings related to KeychainIntegration. Specifically, lines from the store_in_keychain function reference KeychainIntegration:

/* Bail out if KeychainIntegration preference is -bool NO */
if (get_boolean_preference("KeychainIntegration", 1, 1) == 0) {
    fprintf(stderr, "Keychain integration is disabled.\n");
    goto err;
}

Here is the corresponding get_boolean_preference function. Note that it's using CFPreferencesCopyAppValue to obtain a boolean from the "org.openbsd.openssh" application identifier:

#if defined(__APPLE_KEYCHAIN__)

static int get_boolean_preference(const char *key, int default_value,
int foreground)
{
int value = default_value;
CFStringRef keyRef = NULL;
CFPropertyListRef valueRef = NULL;

keyRef = CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8);
if (keyRef != NULL)
    valueRef = CFPreferencesCopyAppValue(keyRef,
        CFSTR("org.openbsd.openssh"));
if (valueRef != NULL)
    if (CFGetTypeID(valueRef) == CFBooleanGetTypeID())
        value = CFBooleanGetValue(valueRef);
    else if (foreground)
        fprintf(stderr, "Ignoring nonboolean %s preference.\n", key);

if (keyRef)
    CFRelease(keyRef);
if (valueRef)
    CFRelease(valueRef);

return value;
}

#endif

This might imply that you can disable the KeychainIntegration functionality for yourself by performing this defaults command:

defaults write org.openbsd.openssh KeychainIntegration -bool NO

or to set it for all users:

sudo defaults write /Library/Preferences/org.openbsd.openssh KeychainIntegration -bool NO