Reliably determining that the agent is available and starting it if not
Craig Ringer
craig at 2ndquadrant.com
Fri Feb 22 01:21:19 CET 2013
Hi all
I'm scripting gpg to batch re-encrypt some files, and I've run into a
surprising problem I was hoping for some advice on.
I expected it to be simple to make sure that the a GPG agent (either the
"gpg-agent" program or something like Gnome's built-in agent) were
available and usable by gpg before proceeding, so the user doesn't get
buried in repeated password prompts. It's turned out to be anything but,
to the point where I feel I must be missing something.
The root of the problem is that the `gpg-agent' command tests for the
existence of an agent a different way to how `gpg' its self does - and
gpg offers no command line test for agent availability, since
--use-agent is simply ignored if the agent can't be used.
gpg-agent looks for an existing agent socket at $HOME/.gnupg/S.gpg-agent
. If one exists it connects to it to check that the agent is alive. It
does this even if no GPG_AGENT_INFO env var is set. If gpg-agent finds a
running agent it will not write the env file or print the definitions
for GPG_AGENT_INFO to stdout, so you cannot invoke gpg-agent to discover
the details of an already-running agent.
gpg, however, looks only at GPG_AGENT_INFO. If it is not set but
--use-agent is passed, gpg will print the local translation of the
message "gpg-agent is not available in this session" and then continue.
It offers no command line flag like --require-agent. --use-agent --batch
has a similar effect, but cannot be used to add the user's key to the
agent if it's not already cached. There doesn't seem to be an equivalent
of "gpg-add" like ssh's "ssh-add".
What all this means is that there doesn't seem to be a reliable way to
determine how to connect to a running agent if there is one, or start
one if there isn't. This seems like such a basic thing that I'm really
hoping I'm missing something really obvious.
The closest I've come so far is this horror:
if ! test -v GPG_AGENT_INFO; then
if gpg-agent 2>/dev/null; then
if test -e /tmp/.gpg-agent-$USER/env; then
. /tmp/.gpg-agent-$USER/env
elif test -e ~/.gpg-agent-info; then
. ~/.gpg-agent-info
else
echo 'A gpg agent is running, but we cannot find its socket
info because'
echo 'the GPG_AGENT_INFO env var is not set and gpg agent
info has not been'
echo 'written to any expected location. Cannot continue.
Please report this'
echo 'issue for investigation.'
exit 5
fi
else
mkdir /tmp/.gpg-agent-$USER
chmod 700 /tmp/.gpg-agent-$USER
gpg-agent --daemon --write-env-file /tmp/.gpg-agent-$USER/env
. /tmp/.gpg-agent-$USER/env
fi
# The env file doesn't include an export statement
export GPG_AGENT_INFO
else
if ! gpg-agent 2>/dev/null; then
echo 'GPG_AGENT_INFO is set, but cannot connect to the agent.'
echo 'Unsure how to proceed, so aborting execution. Please
report this'
echo 'issue for investigation.'
exit 5
fi
fi
This is neither reliable, clean, nor user-friendly. The only real
solution would require that I patch gpg to fall back on the well known
agent socket location if GPG_AGENT_INFO is unset but use-agent is
enabled, or patch gpg-agent to query the existing agent and print
GPG_AGENT_INFO value for it if it's run and an agent already exists.
--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/attachments/20130222/53a6db20/attachment-0001.htm>
More information about the Gnupg-users
mailing list