Bug#778657: [Pkg-gnupg-maint] Bug#778657: gnupg-agent: Test for existing gpg-agent in /etc/X11/Xsession.d/90gpg-agent is always true
Control: severity 778657 normal Control: done 778657 2.0.26-4 Hi Brian-- Sorry to take a while to get back to you on this. I don't think these changes are appropriate for the /etc/X11/Xsession.d/90gpg-agent and i think some of your analysis of the (admittedly baroque) code is mistaken (see discussion below), so i'm closing this bug because i think there's nothing to do for it. If you think my analysis below is mistaken, please reopen the bug and explain what you think should happen next! On Tue 2015-02-17 19:40:45 -0500, Brian C. Duggan wrote: The gpg-agent Xsession.d script looks as if it wants to test for an existing, usable gpg-agent. It looks as if it is supposed to skip starting a new one for the X session if it finds an existing gpg-agent process. That's right. If an existing process provides gpg-agent (and indicates it with the $GPG_AGENT_INFO environment variable), the Xsession.d script should avoid starting up a new agent. I wanted to use this functionality to run gpg-agent as a user service under systemd as the sole gpg-agent process for all my sessions. I set up and enabled the service. systemd starts all enabled user services on the first user login. I logged in on a virtual console and verified that gpg-agent was running and I could connect to it. Then I logged in to an X session and noticed that X had still started its own gpg-agent. We don't currently recommend running gpg-agent as a systemd user service, for a number of reasons. * gpg-agent is likely to change over to --use-standard-socket by default. This is probably incompatible with multiple systemd user sessions running concurrently. * gpg2 and related tools that need to talk to the agent will also soon start auto-launching the daemon when it is needed but not present. I can understand the desire to have all of this session-oriented stuff managed by a real distinct session manager, but that's not where gnupg is at right now. (btw, if you want to work on getting gpg-agent to function as a systemd service, i'd be keen to see that happen. But i think there may be some tricky issues with it, like the ones described above. Please come talk to us at pkg-gnupg-ma...@lists.alioth.debian.org or on #debian-gnupg about it.) The code that looks like it should check for gpg-agent is here: /etc/X11/Xsession.d/90gpg-agent: 6: if grep -qs '^[[:space:]]*use-agent' $GNUPGHOME/gpg.conf $GNUPGHOME/options 7:test -x $GPGAGENT 8:{ test -z $GPG_AGENT_INFO || ! $GPGAGENT 2/dev/null; }; then GPGAGENT=/usr/bin/gpg-agent When run without arguments, gpg-agent's exit status will be 0 if it can connect to an existing gpg-agent process, a positive value if it cannot. Regardless of exit status, gpg-agent run without arguments writes all output to stderr. So, the second part of the expression in line 8 is alwys true. The output of '$GPAGENT 2/dev/null' is always an empty string because gpg-agent sends all output to stderr. [ ! ] is true. but we're not in [ (test) here. the test invocation applies to: -z $GPG_AGENT_INFO then || is a shell conjunction which splits the test from the second half, which is just looking at the return value of an invocation of $GPGAGENT. So, the entire expression on line 8 is always true. But in my testing, I also couldn't configure X so that it passed environment variables to the X session. I wrote a .xsession file like this: #!/bin/sh export MYTESTVAR=test eval startxfce4 and then added 'echo $MYTESTVAR /tmp/mytestvar' to 90gpg-agent. But the corresponding echo-to-file statement in 90gpg-agent never wrote anything. Am I missing an obvious method of passing $GPG_AGENT_INFO to 90gpg-agent? This would normally be done by an earlier stage of the Xsession.d directory, or by pam hooks that were triggered during gdm login. by the time your .xsession is invoked, the rest of Xsession.d/ has already been sourced. Lastly, i think ~/.gnupg/.gpg-agent-info is deprecated upstream, so changing the Xsession.d/ script to depend more heavily on it would be problematic, even if the rest of the analysis were correct. Let me know if you have any more questions. Regards, --dkg signature.asc Description: PGP signature
Bug#778657: gnupg-agent: Test for existing gpg-agent in /etc/X11/Xsession.d/90gpg-agent is always true
Package: gnupg-agent Version: 2.0.26-4 Severity: important Tags: patch Dear Maintainer, The gpg-agent Xsession.d script looks as if it wants to test for an existing, usable gpg-agent. It looks as if it is supposed to skip starting a new one for the X session if it finds an existing gpg-agent process. I wanted to use this functionality to run gpg-agent as a user service under systemd as the sole gpg-agent process for all my sessions. I set up and enabled the service. systemd starts all enabled user services on the first user login. I logged in on a virtual console and verified that gpg-agent was running and I could connect to it. Then I logged in to an X session and noticed that X had still started its own gpg-agent. The code that looks like it should check for gpg-agent is here: /etc/X11/Xsession.d/90gpg-agent: 6: if grep -qs '^[[:space:]]*use-agent' $GNUPGHOME/gpg.conf $GNUPGHOME/options 7:test -x $GPGAGENT 8:{ test -z $GPG_AGENT_INFO || ! $GPGAGENT 2/dev/null; }; then GPGAGENT=/usr/bin/gpg-agent When run without arguments, gpg-agent's exit status will be 0 if it can connect to an existing gpg-agent process, a positive value if it cannot. Regardless of exit status, gpg-agent run without arguments writes all output to stderr. So, the second part of the expression in line 8 is alwys true. The output of '$GPAGENT 2/dev/null' is always an empty string because gpg-agent sends all output to stderr. [ ! ] is true. So, the entire expression on line 8 is always true. But in my testing, I also couldn't configure X so that it passed environment variables to the X session. I wrote a .xsession file like this: #!/bin/sh export MYTESTVAR=test eval startxfce4 and then added 'echo $MYTESTVAR /tmp/mytestvar' to 90gpg-agent. But the corresponding echo-to-file statement in 90gpg-agent never wrote anything. Am I missing an obvious method of passing $GPG_AGENT_INFO to 90gpg-agent? If the intent of line 8 is to keep each X session from starting its own gpg-agent if another gpg-agent is running and connectable, then the script should test the return value of gpg-agent without arguments, not the output. If there are no ways to pass environment to startx or startxfce4, then 90gpg-agent will also have to attempt to load $HOME/.gpg-agent-info. I made those changes my 90gpg-agent file, inline. I also attached the changes as a patch to gnupg2/debian/gnupg-agent.xsession. Thanks, Brian -- System Information: Debian Release: 8.0 APT prefers testing-updates APT policy: (500, 'testing-updates'), (500, 'testing') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages gnupg-agent depends on: ii libassuan02.1.2-2 ii libc6 2.19-13 ii libgcrypt20 1.6.2-4+b1 ii libgpg-error0 1.17-3 ii libpth20 2.0.7-20 ii libreadline6 6.3-8+b3 ii pinentry-gtk2 [pinentry] 0.8.3-2 Versions of packages gnupg-agent recommends: ii gnupg 1.4.18-6 ii gnupg2 2.0.26-4 gnupg-agent suggests no packages. -- Configuration Files: /etc/X11/Xsession.d/90gpg-agent changed: : ${GNUPGHOME=$HOME/.gnupg} GPGAGENT=/usr/bin/gpg-agent PID_FILE=$GNUPGHOME/gpg-agent-info-$(hostname) INFO_FILE=$HOME/.gpg-agent-info if test -f $INFO_FILE; then eval $(cat $INFO_FILE) # Exports GPG_AGENT_INFO, SSH_AUTH_SOCK, etc. eval $(cut -d= -f 1 $INFO_FILE | xargs echo export) fi if test -x $GPGAGENT; then # Invoking gpg-agent with no arguments exits successfully if the agent # is already running as pointed by $GPG_AGENT_INFO $GPGAGENT 2/dev/null GPGAGENT_RUNNING=$? else GPGAGENT_RUNNING=1 fi if grep -qs '^[[:space:]]*use-agent' $GNUPGHOME/gpg.conf $GNUPGHOME/options ( test -z $GPG_AGENT_INFO || $GPGAGENT_RUNNING -gt 0 ); then if [ -r $PID_FILE ]; then . $PID_FILE fi STARTUP=$GPGAGENT --daemon --sh --write-env-file=$PID_FILE $STARTUP fi -- no debconf information diff --git a/debian/gnupg-agent.xsession b/debian/gnupg-agent.xsession index eb8c5847..7ecaefe2 100644 --- a/debian/gnupg-agent.xsession +++ b/debian/gnupg-agent.xsession @@ -2,18 +2,29 @@ GPGAGENT=/usr/bin/gpg-agent PID_FILE=$GNUPGHOME/gpg-agent-info-$(hostname) +INFO_FILE=$HOME/.gpg-agent-info + +if test -f $INFO_FILE; then + eval $(cat $INFO_FILE) + # Exports GPG_AGENT_INFO, SSH_AUTH_SOCK, etc. + eval $(cut -d= -f 1 $INFO_FILE | xargs echo export) +fi + +if test -x $GPGAGENT; then + # Invoking gpg-agent with no arguments exits successfully if the agent + # is already running as pointed by $GPG_AGENT_INFO + $GPGAGENT 2/dev/null + GPGAGENT_RUNNING=$? +else + GPGAGENT_RUNNING=1 +fi if grep -qs '^[[:space:]]*use-agent' $GNUPGHOME/gpg.conf $GNUPGHOME/options - test -x $GPGAGENT - { test -z $GPG_AGENT_INFO