Reputation: 10280
TL;DR: expect
appears to be messing up named pipes in some obscure way, or not cleaning up on exit.
I'm trying to automate generation of ssh keys, without touching the disk with either the private key or the key encryption password. The output is a zip file containing the keys, on stdout
. The general principle is:
This works when generating keys with openssl
or puttygen
. However, ssh-keygen
makes this difficult, because it has to be run from a pty
. To handle this, I run ssh-keygen
under expect
. A test script is below; run as:
$ echo "password" | ./test.sh > test.zip
This correctly creates the new keys in two pipes (/tmp/foo
and /tmp/foo.pub
; see the 'debug' bit in the script). In principle, I can now create the zipfile in exactly the same way as for openssl
and puttygen
:
zip -j - --fifo /tmp/foo /tmp/foo.pub
However, this doesn't work when expect
is involved. If I pipe the script output to xxd
instead of writing it to test.zip
I can see that zip's output actually starts with the expect
data (spawn ssh-keygen ...
) before moving on to the PK
magic at the start of the correct zip output. zip
doesn't complain about this, but unzip
fails, saying that the file is invalid.
I can 'fix' the problem by running this as two separate scripts: the first one just cat
s the two FIFOs, and the second one just runs the zip
command, reading the two FIFOs. This works, producing a valid zip file, but obviously I don't want to do this.
Any suggestions? Is there some way to run expect
which doesn't add rubbish to the FIFO data? Or maybe I can do something in the script to flush everything before running zip
?
#!/bin/bash
export SSH_ASKPASS_REQUIRE=never
rm -f /tmp/foo /tmp/foo.pub
mkfifo /tmp/foo /tmp/foo.pub
passw=$(cat)
expect -c "
spawn ssh-keygen -q -t ed25519 -a100 -C '' -f /tmp/foo
expect \"Overwrite\"
send \"y\r\"
expect \"passphrase\"
send \"$passw\r\"
expect \"again\"
send \"$passw\r\"
expect eof
"&
# DEBUG: this creates valid keys
# cat /tmp/foo > id25519
# cat /tmp/foo.pub > id25519.pub
# BUT zip generates invalid output here, UNLESS you run this command
# outside of this script
zip -j - --fifo /tmp/foo /tmp/foo.pub
Upvotes: 1
Views: 48