Can I automatically login to ssh using passwords from OS X keychain?

9

8

I need to login to an ssh server which doesn't support key based authentication. And I don't want to type the passwords every time.

I am using OS X Lion (10.7.2). I have added the passwords to the OS X keychain[1]. Now I can retrieve the password automatically from the keychain using /usr/bin/security, however I can't find a way to send this password to the ssh prompt.

I also tried sshpass. However when I try to run it ssh exits with the following error:

ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory
Permission denied (publickey,password).

Is there anyway I can login to this server without having to enter the password every time?

Notes

  1. The scheme I use in keychain looks like this
    • Kind: Internet password
    • Account: username
    • Where: ssh://server-name

Chaitanya Gupta

Posted 2012-02-24T06:58:24.813

Reputation: 601

Answers

7

I found a solution (thanks to Daniel Beck for providing the key info needed for this). Note that I have only tested this with OS X Lion 10.7.2. If this doesn't work for you, try Daniel's solution.

First we need to set the SSH_ASKPASS environment variable -- its value should be the path to a program which prints the password to standard output. To get the password from the keychain, this is what it needs to look like (I call it get-ssh-password.sh):

#!/bin/bash

/usr/bin/security find-internet-password -a "$SSH_PASSWORD_USER" -s "$SSH_PASSWORD_HOSTNAME" -r "ssh " -g 2>&1 1>/dev/null | cut -d\" -f2

A couple of points to note:

  1. This assumes that you have stored the password in the keychain in the way I have described in the question

  2. The program given in SSH_ASKPASS will be called without any arguments; so we use environment variables to pass the user and hostname to it.

Now we can set SSH_PASSWORD_USER and SSH_PASSWORD_HOSTNAME and run sshpass to login to our server.

I created another script, ssh-kcpass, to do this:

#!/bin/bash

export SSH_ASKPASS=~/bin/get-ssh-password.sh
export SSH_PASSWORD_USER=$(echo "$1" | cut -d@ -f1)
export SSH_PASSWORD_HOSTNAME=$(echo "$1" | cut -d@ -f2)

sshpass ssh "$1"

To login to the ssh server without typing any password, you just need to run ssh-kcpass user@hostname.

Chaitanya Gupta

Posted 2012-02-24T06:58:24.813

Reputation: 601

How to make this to work in macOS >= 10.13 – nbari – 2018-05-22T15:48:47.887

11

Non-interactive SSH sessions

If you don't need to have an interactive session on the remote server, you can execute ssh in an environment without tty, e.g. as part of a Run Shell Script action in Automator.

You need to create a program that when called prints the password to standard out, e.g. the following bash script you need to make executable using chmod +x pwd.sh:

#!/usr/bin/env bash
echo "password"

Then, set the SSH_ASKPASS environment variable to the path to this program, and then run ssh in the Automator action, like this:

export SSH_ASKPASS=/Users/danielbeck/pwd.sh
ssh user@hostname ls

When there is no tty, but SSH_ASKPASS and DISPLAY (for X11, set by default) are set, SSH executes the program specified by SSH_ASKPASS and uses its output as password. This is intended to be used in graphical environments, so that a window can pop up asking for your password. In this case, we just skipped the window, returning the password from our program. You can use security to read from your keychain instead, like this:

#!/usr/bin/env bash
security find-generic-password -l password-item-label -g 2>&1 1>/dev/null | cut -d'"' -f2

ls (on the ssh command line) is the command executed when ssh has logged in, and its output is printed in Automator. You can, of course, redirect it to a file to log output of the program you start.


Interactive SSH sessions using sshpass

I downloaded, compiled and installed sshpass and it worked perfectly. Here's what I did:

  1. Get the Apple developer tools
  2. Download and open sshpass-1.05.tar.gz
  3. Open a shell to the directory sshpass-1.05
  4. Run ./configure
  5. Run make
  6. Run make install (you might need sudo for it)

Now the program is installed to /usr/local/bin/sshpass. Execute using a line like the following:

sshpass -pYourPassword ssh username@hostname

You can read the password from security just before doing that, and use it like this:

SSHPASSWORD=$( security find-generic-password -l password-item-label -g 2>&1 1>/dev/null | cut -d'"' -f2 )
sshpass -p"$SSHPASSWORD" ssh username@hostname

Wrap this in a shell function and you can just type e.g. ssh-yourhostname to connect, having it retrieve and enter the password automatically.

Daniel Beck

Posted 2012-02-24T06:58:24.813

Reputation: 98 421

@DanielBeck any Idea how to make this to work in macOs >= 10.13 – nbari – 2018-05-22T15:47:34.500

great solution, but your means of parsing out just the password from the security utility is now a bit out of date. The -w option will just return the password directly. So you can replace all of -g 2>&1 1>/dev/null | cut -d'"' -f2 with -w. Here's the full example using this:

SSHPASSWORD=$( security find-generic-password -l password-item-label -w ); sshpass -p"$SSHPASSWORD" ssh username@hostname – Chris – 2019-03-04T02:08:37.900

@Chris To clarify, it works as written, but has more text than necessary to copy & paste? I'm fine with that if there's a chance it's more compatible. – Daniel Beck – 2019-03-04T09:27:33.870

Hi, I have upvoted your answer since it led me to the solution. However, what you described here didn't exactly work (this might be specific to Lion's version of ssh) 1) For non-interactive sessions, ssh still asked me for a password, and after I entered it, I got STDIN is not a terminal. 2) For interactive sessions with sshpass, the -p option apparently doesn't do anything. But running sshpass while SSH_ASKPASS is set does work! – Chaitanya Gupta – 2012-02-28T04:34:37.100

@ChaitanyaGupta Odd. It worked for me non-interactively from within Automator on Lion. Regarding that second issue, it's possible I had a dirty shell session at that point, I'm not sure anymore. +1 to you, and thanks for adding your solution to the site. – Daniel Beck – 2012-02-28T07:53:48.750

My bad (regarding 1) -- I was trying to run the non-interactive session in the terminal and not Automator. I tried it in Automator now, and I still get STDIN is not a terminal error. However, I wasn't prompted for any password this time; I do believe SSH_ASKPASS is working in the Automator since, if I make the file in SSH_ASKPASS return the wrong password, I get a Permission denied, please try again. error. – Chaitanya Gupta – 2012-02-28T08:40:59.430

1For the last examples note that under Unix like OSes command line arguments and environment variables can be visible to other users on the system, so this is not secure in a sensitive multi user environment. – Jürgen Strobel – 2014-03-27T15:39:57.270

-3

Hi there people I came across this topic looking for some other thing but ... Don’t know if I’m missing something here... but your approach seems odd to me. why not just use public key authentication... Generate an rsa key $ ssh-keygen -t rsa -b 2048 -C ‘email/id’

Ideally you’d use once the ssh-copy-id user@host and authenticate with password once to install the key on the other server, or use any kind of script or authomation tool to deploy the key to ~/.ssh/authorized_keys on the other host (for the user you want to login to) If done with the command manually you then have to edit /etc/ssh/sshd_config accordingly and w automation (chef, ansible) you’d push the full condiga for desired state.

The key that matters to distribute is id_rsa.pub, keep the private key secure

To use keychain to authenticate to hosts in an automatic straightforward fashion edit on your machine the ~/.ssh/config and add:

Host * UseKeychain yes

Look for more info on ssh config file options hope any of this comes handy

Ricardo Mendes

Posted 2012-02-24T06:58:24.813

Reputation: 1

1Read the first sentence of the question body: ‘‘I need to login to an ssh server which doesn't support key based authentication.’’ – Scott – 2019-02-23T01:15:08.967

Hi Scott I think you also missed the part where he says he doesn’t want to type the password everytime, which means he is doing it. – Ricardo Mendes – 2019-02-23T16:01:46.327

No, I didn’t miss that. Why would you believe that I did? – Scott – 2019-02-23T19:16:56.903

Bc you’re still talking – Ricardo Mendes – 2019-02-24T20:07:49.073