Scripts using SSH and SSH_ASKPASS

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

I have seen this problem asked many times and had to dealt with it myself, but
no generic examples or clear explanations. I expect this post will help clear
out doubts and provide sample code for the future.

Quoted text here. Click to load it

I've been looking at the same issue for a long while, and finally found the time
to put my hands on it. Included you will find an script that a) does the job and
b) explains how to test it.

What you are seeing is that ssh detects that you have a TTY and writes to it
directly. redirecting stdin from /dev/null won't mislead it and will only
prevent you from entering the password.

To test SSH scripts you better destroy the control TTY. The easies way is to
use SSH itself: ssh -T (capital T) will run a command on the specified host
with NO TTY no matter what. The trick is to run YOUR script on YOUR local
    ssh -T localhost my-test-script

then it will be run with no TTY.

Now for SSH_ASKPASS. You don't need that DISPLAY makes sense at all if you are
not going to use it (i.e. the askpass script/command does not use X). You can
then set it to anything.

As for the password relaying command: this needs not be an X command. Anything
will do as long as it spits out one line containing the password.

And finally for a generic solution that allows running SSH with the password
on the command line (NEVER USE THIS: the password will be on the clear for
any 'ps' command by any user):

- - ----------------------------- 8< cut here 8< -------------------------
# To test, run as
#    ssh -T localhost user@host password
# this will run this script under NO TTY using ssh to invoke it.

# set environment, we only need DISPLAY to be valid for X apps.
export DISPLAY=none:0.0
export SSH_ASKPASS=./catp

# create auxiliary command:
# we read one line from a temporary pipe.
cat > ./catp << END
# cat $pipename # also works
head -1 $pipename
chmod 700 ./catp

# let's go!
# create the pipe
mknod $pipename p
# write the password on the pipe
#    NOTE: serious vulnerability: if this echo command
# is not a shell built-in (e.g. /bin/echo) it might show
# up on a well-timed 'ps' including the password. The time
# window is -nevertheless- slow. Just look out or test it
# step by step.
echo $2 > $pipename & # for password on the command line

ssh -x -t -t $1

rm $pipename

- - ---------------------------- 8< cut here 8< ------------------------

And off you go. You may read the password from standard input instead
(with no TTY) by using "read password" and then "echo $pasword" not
"echo $2"...

Many enhancements are possible, specially regarding the pipe creation
(use umask, ensure higher randomness, make it on a read-only dir...),
writing to it (e.g. do it with a separate command) reading from it
(to prevent someone opening it before we do), etc.. E.g. the 'catp'
script might receive as parameter a filename, or generate the pipe
itself, communicate its name to the writer and hang reading on it...

I know, this has several drawbacks, but it works, and illustrates well
the basic approach as well as its capabilities.


Jose R. Valverde

Site Timeline