[pkg-gnupg-maint] Bug#840669: Bug#840669: Need way to avoid agent, or reliable way to kill agent

Ian Jackson ijackson at chiark.greenend.org.uk
Fri Oct 14 11:10:29 UTC 2016


Daniel Kahn Gillmor writes ("Re: [pkg-gnupg-maint] Bug#840669: Need way to avoid agent,	or reliable way to kill agent"):
> Does your test suite delete its test homedirs after it is finished?  If
> not, would you be willing to include removal of the test homedirs as
> part of the tests, or as a final post-test cleanup phase?

No.  It does not do anything after it is finished.

Each script mentioned in debian/tests/control simply exits zero and
then (according to DEP-8) it's the responsibility of the test runner
to delete the tree if it cares.

When run under adt-run with a filesystem snapshotting virt server,
there is to need (of course) to delete the temporary area, since it's
in a filesystem a snapshot which is going to be deleted.

> One thing worth observing is that if the agent's socket is deleted, it
> will eventually terminate itself after a minute or two anyway.  This
> will happen even without inotify (but obviously the inotify trigger
> should really work to automate cleanup on platforms that support inotify)

That's not really fast enough.

> > IMO: there should be a way to get gnupg2 to do everything synchronously;
> > that is, if it needs an agent, to spawn one which does not listen on a
> > socket, but rather just has an existing connection to its parent and
> > which will die when the parent does.
> 
> This could potentially complicate the agent -- at the moment, i think
> the agent expects to be the only process dealing with
> $GNUPGHOME/private-keys-v1.d/, and that means that two gpg processes
> using this approach could potentially trample on each other.

Then perhaps it should take a lock.  I assume there must be some kind
of locking anyway, or concurrent startups would occasionally fail.

I propose a design something like this:

 * When GNUPG_AGENT_LIFETIME_FD is set:
    - gpg-agent does not create a rendezvous socket.  Instead,
      it selects/polls this fd for reading.
    - When the fd is readable, gpg-agent expect to receive one end
      of an AF_UNIX socketpair over it by fd passing.  That
      received fd is treated the same way the answer from accept()
      would be.
    - If the master fd signals EOF, gpg-agent exits.
    - gpg-agent should nevertheless take out a lock on a common
      name in $GNUPGHOME.

 * When gpg needs an agent but none is running discoverable in the
   current global way [1]:
   If GNUPG_AGENT_LIFETIME_FD is not already set,
    - gpg creates an AF_UNIX anonymous socketpair.  One end will
      become the "agent" fd and is set ~CLOEXEC.  The other end
      becomes gpg's and is set CLOEXEC.
    - gpg sets GNUPG_AGENT_LIFETIME_FD to the "agent" end of
      the socketpair
    - gpg spawns the agent
    - Now GNUPG_AGENT_LIFETIME_FD is set.
   When gpg wants to connect to the agent, it creates a new
   socketpair and uses sendmsg to pass one end to the agent;
   it then closes that end and uses the other end as if it had just
   been connect()ed.

 * Creating a socketpair and setting GNUPG_AGENT_LIFETIME_FD should be
   documented as a way to get a privately-scoped gnupg.  For example,
   dgit might like to do this so that it can make its three signatures
   with one user authorisation and then terminate the authorisation
   when it is done.  The document should say that:
     - Programs must not set GNUPG_AGENT_LIFETIME_FD if it is already
       set, so they must check it first.  (Otherwise deadlock will
       occur.)
     - Programs need not check for the existence of an `ambient' gnupg
       agent in the user's account/session/environment; if there is
       one, the GNUPG_AGENT_LIFETIME_FD setting will be ignored.

 * The result is that the scope of an auto-spawned agent is a single
   GNUPG_AGENT_LIFETIME_FD (normally, a single gnupg2 gpg program).
   Other concurrent calls to gpg will block.

 * [1] If you don't think this behaviour is good by default, it could
   be a config option.  But I would argue that it ought to be the
   default is the environment has not provided an agent, because it
   provides the same authorisation lifetime as was implemented in
   gnupg1.

> > In particular, `gpgconf --kill gpg-agent' should be documented.
> 
> Where would you like it documented?  it's in gpgconf(1):

In gpg-agent(1) !

> If you're not willing to do *anything* (including deletion of the
> temporary $GNUPGHOME or some sort of session termination event) upon
> completing the test suite, but before tearing down your builder
> instance, then i don't know if there's a solution.  But at the moment i
> suspect getting the inotify stuff fixed is the sanest and simplest
> approach on the platform you and i probably care most about :)

For now I have bodged this with a new schroot script
/etc/schroot/setup.d/71killagent.  Attached.

This doesn't solve the problem when the test scripts are run ad-hoc.
It won't solve the problem for other programs which set HOME (or
GNUPGHOME) as part of test suites or whatever.

Thanks for your attention.

Ian.

-- 
Ian Jackson <ijackson at chiark.greenend.org.uk>   These opinions are my own.

If I emailed you from an address @fyvzl.net or @evade.org.uk, that is
a private address which bypasses my fierce spamfilter.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 71killagent
URL: <http://lists.alioth.debian.org/pipermail/pkg-gnupg-maint/attachments/20161014/289b4954/attachment.ksh>


More information about the pkg-gnupg-maint mailing list