Any idea why
sftp is unable to read the temporary file descriptor?
<(pass foo) process substitution will cause
bash to create a pipe, run the
pass foo command asynchronously with its output connected to the writing end of the pipe and replace the
<(...) with a path of the form
63 is the file descriptor referring to the reading end of the pipe.
/dev/fd/63 is a special path which allows a process to
stat() and re-open the file referred by one of its file descriptors.
- the shell forks + execs
sftp itself forks and execs
ssh, causing the
63 file descriptor to be passed down via inheritance.
ssh will close all its file descriptors except 0, 1, 2 using the
closefrom() function. That will also close fd
63 is no longer an open file descriptor in the
ssh process, a
/dev/fd/63 will fail with the error from the OP.
How to fix it?
Temporarily store the key in a filesystem in memory. In my Debian
systemd provides me tmpfs under
/run/user/<myUID>. The mountpoint is inaccessible to anyone but me (and root, of course).
Note a rogue process running under your user (or root) can read the file. But such process could also read from
sshd's file descriptor
63 in your original approach.
Alternatively, when there is no safe tmpfs available:
Create a temporary fifo. Note
mktemp cannot do this directly. The safe way is to create a temporary private directory and then
mkfifo in it.
Make sure the permissions of the fifo itself are narrow, otherwise
ssh will complain.
sftp -i "/temp_dir/the_fifo" user@host
In parallel run
pass foo > "/temp_dir/the_fifo". A quirk: you need to do this twice; at least in my Debian
ssh reads the key twice. The following command seems to work in my tests:
cat ~/.ssh/id_rsa > "/temp_dir/the_fifo" && cat ~/.ssh/id_rsa > "/temp_dir/the_fifo". Probably a similar duplicated command will work for you:
pass foo > "/temp_dir/the_fifo" && pass foo > "/temp_dir/the_fifo"
You can run it in the background just before
pass is interactive, I'm not familiar with the tool at all).
At the end remove the fifo and the directory.
Still, a rogue process running under your user (or root) can read from the fifo before