Tell SSH to use a graphical prompt for key passphrase

#1 - Missing package?

You're probably missing the package that contains ssh-askpass. Try installing it.

Fedora/CentOS/RHEL:

$ sudo yum install openssh-askpass

Debian/Ubuntu:

$ sudo apt-get install ssh-askpass-gnome ssh-askpass

Finding missing utilities

You can search for missing tools using these commands:

Fedora/CentOS/RHEL:

$ yum search ssh-askpass
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
======================================================= Matched: ssh-askpass =======================================================
x11-ssh-askpass.x86_64 : A passphrase dialog for X and not only for OpenSSH
ksshaskpass.x86_64 : A KDE version of ssh-askpass with KWallet support
connect-proxy.x86_64 : SSH Proxy command helper
openssh-askpass.x86_64 : A passphrase dialog for OpenSSH and X

Debian/Ubuntu:

$ apt-file -l search ssh-askpass
app-install-data
cruft
git-cola
luckybackup-data
pssh
sdm-terminal
seahorse
ssh-askpass
ssh-askpass-fullscreen
ssh-askpass-gnome

#2 - Disconnected terminal?

I missed this initially but after further reading up I noticed this comment in the man page of ssh regarding the SSH_ASKPASS environment variable.

excerpt

SSH_ASKPASS    If ssh needs a passphrase, it will read the passphrase from the 
               current terminal if it was run from a terminal.  If ssh does not
               have a terminal associated with it but DISPLAY and SSH_ASKPASS 
               are set, it will execute the program specified by SSH_ASKPASS 
               and open an X11 window to read the passphrase. This is particularly
               useful when calling ssh from a .xsession or related script.  
               (Note that on some machines it may be necessary to redirect the 
               input from /dev/null to make this work.)

If you notice in the comment, it states that ssh "doesn't have a terminal associated" AND DISPLAY & SSH_ASKPASS are set. Noticing this is key. So to get ssh to use SSH_ASKPASS we need to get ssh to not have a terminal (aka. STDIN & STDOUT) attached to it.

One way to do this by making use of the command setsid. Don't feel bad. I never heard of this tool either. From the man page:

setsid - run a program in a new session

So if we run ssh as the "program" to setsid we can detach ssh from our terminal meeting the criteria mentioned in ssh's man page. The other criteria are set as follows:

$ echo $DISPLAY; echo $SSH_ASKPASS
:0.0
/usr/libexec/openssh/ssh-askpass

So if we put this all together:

$ setsid ssh user@remotehost

For example:

$ setsid ssh user@skinner

                                       ss of ask gui

A solution

If you'd like to make it so that the setsid is "built-in" you can create an aliases like so:

$ alias ssh="setsid ssh"

Now when you ssh you'll get the GUI popping up asking for your password:

$ ssh user@skinner

References

  • reading SSH password from stdin – the openssh 5.6p1 compatible way

It cannot be done in current OpenSSH: there is a issue open in the OpenSSH Bugzilla asking for this feature as of 2013-07: Generalize SSH_ASKPASS.


There is a way to close the terminal for a single command, and that is using file redirection:

ssh-add > /dev/null < /dev/null 2>&1

This will run the command ssh-add with the terminal closed. Which is fine and dandy, except for the its complexity. But now that you know the correct command, simply make it an alias and append it to ~/.bash_aliases:

alias ssh-add="/usr/bin/ssh-add > /dev/null < /dev/null 2>&1"

And you should be set. Simply typing ssh-add will now invoke the alias which will invoke the real command with all the redirection in place.

The ssh-add now correctly asks you the password with a dialog box... Provided that you have one of these packages installed (in Ubuntu or derivatives, they may have other names elsewhere):

  • ssh-askpass
  • ssh-askpass-fullscreen
  • ssh-askpass-gnome
  • ksshaskpath
  • kwalletcli
  • lxqt-openssh-askpass
  • razorqt-openssh-askpasss

Now, what do all those things mean?

The 2>&1 means redirect file descriptor #2 (standard error) to the same place file descriptor #1 (standard output) is directed to.

The > /dev/null means redirect standard output to /dev/null, which is a special file that discards all data written to it.

The < /dev/null means redirect standard input to /dev/null (idem).

As a side note, and an off topic but related note, if you ever want to program a service in bash, you must remember what a service actually is, a process with standard input, output, and error closed that is in the background:

service > /dev/null < /dev/null 2>&1 &

Notice that the only difference is the & added at the end (plus the fact that I changed the command ssh-add for a theoretical service. Those commands will correctly put a service on the background.

Tags:

Ssh