Use KWallet for any command, including SSH password

ksshaskpass is a KDE-based passphrase dialog for use with OpenSSH. It is intended to be called by the ssh-add(1) program and not invoked directly. It allows ssh-add(1) to obtain a passphrase from a user [...]

So this utility is useful if you want to store the passphrases to your SSH keys in the KDE Wallet (there are plenty of instructions on how to do that).

But all it really does is receive a string as an argument, tries to query KWallet for a password saved under this key string (or asks for this password in a dialog and stores it), then writes it to stdout. This means that ksshaskpass can be used to store any kind of password in KWallet for use in your Bash scripting.

We will be using Bash, ksshaskpass, sshpass.


For the first example we will need a SSH server that you connect to using a password (no key). localhost (with openssh-server installed) will do.

So you connect to the server, then get prompted to enter the password.

$ ssh blaxpirit@localhost
blaxpirit@localhost's password:
$

The program sshpass lets you supply the password non-interactively, as a command line argument. All it does is call the command passed to it and types in the password for you.

$ sshpass -p 'Pa$$word'  ssh blaxpirit@localhost
$

But we don't want to store the password as plain text, do we? So let's use KWallet and ksshaskpass.

$ sshpass -p "$(ksshaskpass 'SSH connection to blaxpirit@localhost')"  ssh blaxpirit@localhost
$

This will show a dialog prompt with the supplied message, and use the entered password to connect to SSH. The password will also be stored under this key message in KWallet/ksshaskpass.

Let's make this more general, to allow convenient connection to any kind of SSH server.

function sshp {
    sshpass -p "$(ksshaskpass "ssh $*")" ssh "$@"
}
$ sshp -p 22 blaxpirit@localhost
$

This will show the dialog prompt "ssh -p 22 blaxpirit@localhost", then issue this command, supplying the entered password.

Note that there is no smart matching. The password will be saved under this exact key "ssh -p 22 blaxpirit@localhost", and any rearrangements will make you have to re-enter the password.

So why stop here? We can make this even more generic! Make a way to put a password into any kind of command.

function kpass {
    command -- "${@/'{}'/"$(ksshaskpass -- "$*")"}"
}

alias sshp='kpass  sshpass -p {}  ssh'
$ sshp -p 22 blaxpirit@localhost
$

This function got complicated really quickly, didn't it? So, step by step:

  • ksshaskpass -- "$*" - this calls ksshaskpass with all arguments supplied to the function joined into one string.

  • "$(ksshaskpass -- "$*")" - just wrapping it into $() and quotes to obtain the password from stdout. The -- part marks the end of arguments like -h in case the key/prompt starts with a dash.

  • "$@" is, again, all arguments supplied to the function, but as an array. "${@}" is the same thing

  • "${@/'{}'/"$(ksshaskpass -- "$*")"}" - take $@ and replace the first occurence of {} in it with the result of the command. Like "${some_var/a/b}" takes $some_var, replacing 'a' with 'b'.

  • The command -- prefix is just a way to avoid strangeness and add some safety. Difficult to explain.

And the demonstration of how the function can be used follows right after. We reimplemented sshp based on it. Just calls sshpass ..., replacing {} with the entered password.

Created
Comments powered by Disqus