Discussion:
[PATCH] gpg-agent: Enable socket activation
Shea Levy
2014-11-18 23:05:46 UTC
Permalink
Hi all,

I’ve attached a patch to enable the '--agent-fd' (and, similarly, '--ssh-agent-fd') flags to be used to specify a file descriptor to use as the agent listening socket. This allows service managers like launchd or systemd to enable on-demand activation of gpg-agent without potential races at initialization or termination time.

I’ve also attached an example launchd configuration and program that can be used with this patch to set up on-demand activation on OS X.

You can also pull the change directly from the 'socket-activate’ branch of git://github.com/shlevy/gnupg.git

Cheers,
Shea Levy
Werner Koch
2014-11-19 07:59:02 UTC
Permalink
Post by Shea Levy
as the agent listening socket. This allows service managers like
launchd or systemd to enable on-demand activation of gpg-agent without
potential races at initialization or termination time.
gpg-agent is started on demand by the modules which need gpg-agent.
There is no need for any init service to start gpg-agent in advance.
Even 2.0 may be build or runtime configured to be started on demand.


Shalom-Salam,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
s***@shealevy.com
2014-11-20 00:19:29 UTC
Permalink
Hi Werner,

There are three issues that using externally-managed socket activation
can bypass:

* With socket activation, external programs talking to the agent simply
need to try to connect to the socket. With on-demand activation as it
currently exists, they must try to connect and then spawn gpg-agent and
try again. This is more complicated and requires the external program to
run with gpg-agent in PATH or with a hard-coded path to the agent.
* With on-demand activation as it currently exists, two agent-using
programs spawned simultaneously may step on each other creating the
socket (this can theoretically be bypassed with file locks, perhaps this
is already done in which case this is a non-issue).
* User-level daemon managers like systemd --user and launchd know when
the user has logged out, and thus can kill the running agent and refuse
to spawn new instances upon new connections. With on-demand activations
as it currently exists, there's no easy way to kill the daemon on log
out, and even if you add a custom service that runs gpg-connect-agent
KILLAGENT on logout there is a race possible where another process tries
to connect after the kill goes through. I've actually hit this issue.

~Shea
Post by Werner Koch
Post by Shea Levy
as the agent listening socket. This allows service managers like
launchd or systemd to enable on-demand activation of gpg-agent without
potential races at initialization or termination time.
gpg-agent is started on demand by the modules which need gpg-agent.
There is no need for any init service to start gpg-agent in advance.
Even 2.0 may be build or runtime configured to be started on demand.
Shalom-Salam,
Werner
Werner Koch
2014-11-20 11:31:35 UTC
Permalink
Post by s***@shealevy.com
* With socket activation, external programs talking to the agent
simply need to try to connect to the socket. With on-demand activation
That would a very different program than we have now. The Hurd calls
this a translator and it is a nice technique. However, neither systemd
nor translators are established and portable methods and thus should be
avoided by portable software. But please save us a systemd discussion.

Actually, we do this for years on Windows and it works very reliable.
Post by s***@shealevy.com
socket (this can theoretically be bypassed with file locks, perhaps
this is already done in which case this is a non-issue).
Sure that is done. In addition gpg-agent checks that its socket has not
been reused by another aganet and termintes itself in this case.
Post by s***@shealevy.com
* User-level daemon managers like systemd --user and launchd know when
the user has logged out, and thus can kill the running agent and
Valid point. Hwoever I don't see a problem to not terminate the
gpg-agent on logout. After all most mechines today are single user and
the agent is supposed to run on your own desktop and not on a remote
machine. What one should put into the ~/.xession at exit is

gpgconf --reload gpg-agent

(or code to send a HUP) to flush the caches. This should also be done
before the system hibernates.
Post by s***@shealevy.com
daemon on log out, and even if you add a custom service that runs
gpg-connect-agent KILLAGENT on logout there is a race possible where
another process tries to connect after the kill goes through. I've
Well that would be hard to avoid unless one accespts a stale lock file.


Salam-Shalom,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Shea Levy
2014-11-20 13:20:16 UTC
Permalink
Hi Werner,
Post by Werner Koch
Post by s***@shealevy.com
* With socket activation, external programs talking to the agent
simply need to try to connect to the socket. With on-demand activation
That would a very different program than we have now. The Hurd calls
this a translator and it is a nice technique. However, neither systemd
nor translators are established and portable methods and thus should be
avoided by portable software. But please save us a systemd discussion.
Hm, I don’t understand this reasoning. Why is it bad to use non-portable methods in a completely optional feature? I’m not suggesting we abandon the current on-demand logic. And FWIW, both OS X and Linux have existing support for socket activation (I’m pretty sure systemd —user can be used even on hosts that don’t use systemd as init), and it is very easy to write a socket-activating wrapper around a program in POSIX C.

If all portable software avoided optional use of non-portable functionality, I doubt any functionality would gain enough prominence to become established.
Post by Werner Koch
Actually, we do this for years on Windows and it works very reliable.
Post by s***@shealevy.com
socket (this can theoretically be bypassed with file locks, perhaps
this is already done in which case this is a non-issue).
Sure that is done. In addition gpg-agent checks that its socket has not
been reused by another aganet and termintes itself in this case.
Ah, I’m glad to know :)
Post by Werner Koch
Post by s***@shealevy.com
* User-level daemon managers like systemd --user and launchd know when
the user has logged out, and thus can kill the running agent and
Valid point. Hwoever I don't see a problem to not terminate the
gpg-agent on logout. After all most mechines today are single user and
the agent is supposed to run on your own desktop and not on a remote
machine. What one should put into the ~/.xession at exit is
gpgconf --reload gpg-agent
(or code to send a HUP) to flush the caches. This should also be done
before the system hibernates.
Not everyone has the luxury of a personal single-user machine, and it’s IMO bad etiquette to leave software running unnecessarily after your session. But fair enough.
Post by Werner Koch
Post by s***@shealevy.com
daemon on log out, and even if you add a custom service that runs
gpg-connect-agent KILLAGENT on logout there is a race possible where
another process tries to connect after the kill goes through. I've
Well that would be hard to avoid unless one accespts a stale lock file.
Or, in the case where the socket is managed by a session-aware daemon, it can just refuse to spawn a new instance :)
Post by Werner Koch
Salam-Shalom,
Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
If socket activation isn’t an option, can we at least have a flag to not fork and set a new session? At least we still get some of the benefits of having the daemon manage lifetime easier in that scenario.

~Shea
Daniel Kahn Gillmor
2014-11-20 17:14:26 UTC
Permalink
Hm, I don’t understand this reasoning. Why is it bad to use non-portable methods in a completely optional feature? I’m not suggesting we abandon the current on-demand logic. And FWIW, both OS X and Linux have existing support for socket activation (I’m pretty sure systemd —user can be used even on hosts that don’t use systemd as init), and it is very easy to write a socket-activating wrapper around a program in POSIX C.
If all portable software avoided optional use of non-portable functionality, I doubt any functionality would gain enough prominence to become established.
I haven't tested this patch, but i do think that what shea aims to offer
here is a valuable feature for those operating systems which support it.

I would like to see the gpg-agent be able to start based on a passed-in
file descriptor and stay foregrounded.

What can we do to encourage you to reconsider this approach, Werner?

--dkg
Werner Koch
2014-11-20 18:34:45 UTC
Permalink
Post by Daniel Kahn Gillmor
I would like to see the gpg-agent be able to start based on a passed-in
file descriptor and stay foregrounded.
We had several ways to start gpg-agent in the past and am glad that most
of this mess could been removed. This makes maintenance and evaluating
bug reports much easier.


Salam-Shalom,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Daniel Kahn Gillmor
2014-11-20 23:50:00 UTC
Permalink
Post by Werner Koch
Post by Daniel Kahn Gillmor
I would like to see the gpg-agent be able to start based on a passed-in
file descriptor and stay foregrounded.
We had several ways to start gpg-agent in the past and am glad that most
of this mess could been removed. This makes maintenance and evaluating
bug reports much easier.
Shea's proposal would not affect the daemon-starting logic that
currently exists in other parts of the GnuPG suite. It just provides a
way that a supervised agent could be initialized (and therefore could be
cleanly torn down).

If any supervising process doesn't use this feature, then everything
behaves as normal. If a supervising process does use this feature, then
the daemon is already in place, and it works anyway (but the clients
never end up spawning the daemon).

I don't want to get into a tangential argument about what is "the Unix
way", but in many ways the tradition of composable tools that do "one
thing well" suggests that the triplet of <process supervision daemon,
socket-activated service, and simple client> is in some ways more
"unix-like" than having every potential client need to know how to spawn
every potential daemon that it might use.

Being able to use gpg-agent as part of such a composable environment
would be a very nice option to have.

Regards,

--dkg
Werner Koch
2014-11-20 18:59:04 UTC
Permalink
This post might be inappropriate. Click to display it.
Robert J. Hansen
2014-11-20 19:11:24 UTC
Permalink
<rant> ... </rant>
<joke> So when are we going to see GnuPG folded into systemd? </joke>
Post by Shea Levy
Not everyone has the luxury of a personal single-user machine, and
You shall not use private keys on a multi-user machine.
I think this is a little extreme. If the other users are all trusted,
the risk is manageable. For instance, over the Christmas holidays my
younger relatives will often use my laptop to do some of their
schoolwork. I'm pretty sure my nieces aren't putting malware or
keyloggers on my laptop, so I'm fine with my private key being on my
laptop even though I'm permitting others to use it.
Werner Koch
2014-11-20 20:18:07 UTC
Permalink
Post by Robert J. Hansen
I think this is a little extreme. If the other users are all trusted,
the risk is manageable. For instance, over the Christmas holidays my
younger relatives will often use my laptop to do some of their
Of course I was thinking of a machine with concurrent working users.
There are too many local root exploits and even a fully fixed box is
never safe from side-channel attacks.


Salam-Shalom,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Alex Elsayed
2014-11-20 23:37:05 UTC
Permalink
This post might be inappropriate. Click to display it.
Werner Koch
2014-11-21 13:12:05 UTC
Permalink
Post by Alex Elsayed
IMO, this is a _very convincing_ reason to deterministically kill off gpg-
agent on logout, which session-daemon control makes feasible.
Fine, do that. You only need to run

rm "$HOME"/.gnupg/S.gpg-agent || true


Shalom-Salam,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Shea Levy
2014-11-21 04:20:14 UTC
Permalink
Post by Werner Koch
Post by Robert J. Hansen
I think this is a little extreme. If the other users are all trusted,
the risk is manageable. For instance, over the Christmas holidays my
younger relatives will often use my laptop to do some of their
Of course I was thinking of a machine with concurrent working users.
There are too many local root exploits and even a fully fixed box is
never safe from side-channel attacks.
Even in the case of a multi-user machine with only one working user at a time, surely it’s still good practice to kill all unnecessary processes after logout? If you accept this use case then my argument still holds.
Post by Werner Koch
Salam-Shalom,
Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
_______________________________________________
Gnupg-devel mailing list
http://lists.gnupg.org/mailman/listinfo/gnupg-devel
Shea Levy
2014-11-21 04:19:00 UTC
Permalink
Post by Werner Koch
Post by Shea Levy
Hm, I don’t understand this reasoning. Why is it bad to use
non-portable methods in a completely optional feature? I’m not
For maintenance reasons and to reduce code complexity.
Fair enough, but that has nothing to do with portability :)
Post by Werner Koch
Post by Shea Levy
If all portable software avoided optional use of non-portable
functionality, I doubt any functionality would gain enough prominence
to become established.
True if that would solve any real problem. <rant>systemd is the
Windowization of Unix and such the opposite of portable and modularized
software. It is sad to see how WindowsNT moved over the last 15 years
towards a system more similar to Unix while Linux as the spearhead of
the Unix standardization is splitting up into the non-interoperable Unix
world we had reached 25 years ago. Time to reconsider FreeBSD</>
Hey, I dislike a lot of what systemd is doing/has done to the Linux community too. But just because one of the main implementors of socket activation has some bad qualities doesn’t mean socket activation itself isn’t a useful tool :) I’ve pointed out the specific problems socket activation solves, and as I’ve said I’ve hit some of these problems in practice.
Post by Werner Koch
Post by Shea Levy
Not everyone has the luxury of a personal single-user machine, and
You shall not use private keys on a multi-user machine.
Some people have no other option, and while of course it’s not ideal I’d prefer that they have access to some measure of privacy (as I’m sure you would too).
Post by Werner Koch
Post by Shea Levy
If socket activation isn’t an option, can we at least have a flag to
not fork and set a new session? At least we still get some of the
--no-detach already exists but it is mostly useless. Yes we can
probably add an option to run without a fork but I see no use case for
that except for starting gpg-agent from inittab (or whatever you guys do
on your not-anymore-Unix boxes these days).
Yes, starting it from inittab (or the user-level version of it) is exactly the use case.
Post by Werner Koch
The main point is: gpg-agent shall be started on demand and not by any
session control daemon.
If that is final then I guess there’s nothing more I can say.
Post by Werner Koch
Post by Shea Levy
benefits of having the daemon manage lifetime easier in that scenario.
BTW, having a session logoff script remove the socket file is an easy
4 - 19:57:49 gpg-agent[563]: can't connect my own socket: IPC connect call failed
4 - 19:57:49 gpg-agent[563]: this process is useless - shutting down
4 - 19:57:51 gpg-agent[563]: gpg-agent (GnuPG) 2.1.1-beta19 stopped
and by using rm(1) this is race free.
This is not race free, some process still running after the logoff script can try to connect, see there’s no socket, and spawn a new agent.
Post by Werner Koch
Shalom-Salam,
Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Werner Koch
2014-11-21 13:17:57 UTC
Permalink
Post by Shea Levy
activation has some bad qualities doesn’t mean socket activation
itself isn’t a useful tool :) I’ve pointed out the specific problems
It definititely is a nice feature. However, for gpg-agent it is not
required. gpg-agent shall only be started by the GnuPG tools. If you
need to start it advance (e.g. for ssh support) run

gpgconf --launch gpg-agent

no need to mess around with init systems.
Post by Shea Levy
This is not race free, some process still running after the logoff script can try to connect, see there’s no socket, and spawn a new agent.
You need to run it last of course ;-)


Salam-Shalom,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Shea Levy
2014-11-21 13:25:11 UTC
Permalink
Post by Werner Koch
gpg-agent shall only be started by the GnuPG tools.
Hmm, so is there any stable interface to gnupg then?
Post by Werner Koch
You need to run it last of course ;-)
Avoiding explicit dependency ordering specifications is one of the main benefits of socket activation ;) But I suspect we’re going in circles at this point.

~Shea
Werner Koch
2014-11-21 15:22:12 UTC
Permalink
Post by Shea Levy
Hmm, so is there any stable interface to gnupg then?
Sorry, I don't understand. In case you want to know how to start
gpg-agent for use by ssh, tehre are two ways:

gpgconf --launch gpg-agent

which is the modern one. And the old one which also works for 2.0 if
build or configured to use a standard socket is

gpg-connect-agent NUP /bye


Shalom-Salam,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Shea Levy
2014-11-21 15:50:26 UTC
Permalink
Post by Werner Koch
Sorry, I don't understand. In case you want to know how to start
gpgconf --launch gpg-agent
Hm then I’m confused, what did you mean by "gpg-agent shall only be started by the GnuPG tools” if there’s a well-defined way to start gpg-agent directly?
Werner Koch
2014-11-21 19:21:28 UTC
Permalink
Post by Shea Levy
Hm then I’m confused, what did you mean by "gpg-agent shall only be
started by the GnuPG tools” if there’s a well-defined way to start
gpg-agent directly?
gpg-connect-agent is a GnuPG tool
gpgconf is a GnuPG tool.

They both start gpg-agent if the need it. As do gpg, gpgsm, and g13.


Salam-Shalom,

Werner
--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.
Charles Diza
2014-11-22 15:47:14 UTC
Permalink
FWIW, it is perfectly possible to auto-kill gpg-agent upon user logout on
Mac OSX. I've been doing this for years, and it still works on Yosemite.

Make a shell script that does "killall -u $1 gpg-agent". Then do this in
your terminal:

sudo defaults write com.apple.loginwindow LogoutHook "path-to-your-script"

Now whenever any user logs out, that script gets executed and only kills
the gpg-agent instance associated with that user.

Cheers,
Charles

Loading...