pipe passphrase to unlock key
Ciprian Dorin Craciun
ciprian.craciun at gmail.com
Mon Jul 30 21:15:55 CEST 2012
On Wed, Jun 27, 2012 at 8:42 PM, Face <falazemi at gmail.com> wrote:
> Hell all,
>
> I am trying to pipe my passphrase to unlock the key. my problem is
> like this, when I use git
> to sign a tag gnupg ask for the passphrase and i need to pipe the passphrase.
>
> I try
> echo "my long passphrase" | git tag -s 1.0.0.42 -m 'version 1.0.0.1'
>
> however it did not work.
>
>
> is there is any workaround for my problem ?
>
>
> Any help would be much appreciated.
>
> Sincerely,
> falazemi
>
> note: using pinentry-curses
Hope my feedback is not too late... But either way I don't think
it would help too much as neither solution is straight-forward...
So the only workaround -- that I know of, but I'm not a GnuPG
developer -- is to either:
* implement your own "fake" `gpg-agent` which I have no ideea what
actually implies;
* implement your own "fake" `pinentry` which would be much simpler
as it only has to implement the assuan protocol; but you'll have to
start a separate instance of `gpg-agent` just for this situation,
which unfortunately will background and you'll have to "hunt it down"
once your done, or you could use that to start your command as a child
of `gpg-agent` which is a horrible hack;
* (preferably) implement a fake `gpg` which does the following:
opens a pipe as you have done in your example, writes the password and
then calls the real `gpg` with an additional argument
`--passphrase-fd`; (this works only as long as Git uses the `gpg` tool
and not the library... fortunately this is true today and I guess it's
unlikely to change...)
Related to this last option, and assuming you are on Linux and are
using a recent BASH version (mine is 4.x), you could do what you want
as bellow (code not tested):
~~~~
password=...
env \
GPG_PASSPHRASE_FD=<( printf -- "${password}" ) \
PATH="a-folder-where-your-gpg-wrapper-is:${PATH}" \
git ...
~~~~
Notes:
* the syntax <( ... ) replaces the token with the path of a pipe
ready to read from the sub-command in the parenthesis; (see the Bash
manual);
* as you can't send arguments to `gpg` via Git you use environment
variables;
* the password is not visible in the environment of the `git` or
its children, but could be read from that descriptor;
* depending on Bash it could actually be stored on the file system
thus maybe leaked to permanent storage...
Where your `gpg` wrapper would be (not tested but adapted from
another script of mine):
~~~~
#!/bin/bash
# see Bash manual for the magic in the following line... :)
set -e -E -u -o pipefail || exit 1
_self_path="$( readlink -e "${0}" )"
_self_name="$( basename "${0}" )"
# this would contain each resolved file in the path
# if we are a wrapper then the first is the wrapper
# and the second must be the real one
_paths="$( which -a -- "${_self_name}" )"
_next=
while read _path
do
_path="$( readlink -e "${_path}" )"
test "${_path}" != "${_self_path}" || continue
_next="${_path}"
break
done <<<"${_paths}"
# it will silently fail if we haven't found the real gpg
test -n "${_next}"
# we assume that someone has exported the `GPG_PASSPHRASE_FD`
# and that there we have a path to a pipe to read from
# we also assume that we have at least another argument
exec "${_next}" --passphrase-fd "${GPG_PASSPHRASE_FD}" "${@}"
exit 1
~~~~
Hope this helps you (one moth later) although it is a crude hack... :(
But the real problems is still open and should be solved by
extending both Git and GnuPG...
Ciprian.
P.S.: If you don't like the Bash script I have an neat idea on how
to simply implement it in C, in a similar fashion, which would
guarantee you zero file system exposure.
More information about the Gnupg-users
mailing list