Page MenuHome GnuPG

Password is _never_ prompted in an X session but is in a bare tty
Closed, ResolvedPublic

Description

This is more of a behavior change / regression rather then a bug that I haven't experienced in previous versions. IMO the old behavior is better and safer. It's kind of hard to explain the difference, so I'll list the steps to reproduce and I'll point out how previous gnupg2 versions behaved and how the current version does.

  1. Login to a bare tty.
  2. Run gpg --decrypt <file> and be prompted for a password.
  3. Note with top that gpg-agent is running.
  4. Run gpg-connect-agent reloadagent /bye
  5. Run gpg --decrypt <file> and be prompted for a password again.

This behavior is OK IMO and is identical with both older and newer versions of GnuPG2.

Here's what happens if I run at a certain point startx and what happens inside the X session.

  1. Login to a bare tty.
  2. Run gpg --decrypt <file> and be prompted for a password.
  3. Run startx.
  4. Inside the X session, run gpg-connect-agent reloadagent /bye or any other command that should reload the agent.
  5. Run gpg --decrypt <file> and you wouldn't be prompted for a password - the contents of <file> will be printed even if you kill the gpg-agent process.

In older versions, even inside an X session these agent controlling commands have enabled me to "lock" my key and thus protect my encrypted files when e.g my screensaver locks my computer. Unfortunatly, I don't remember which version exactly caused the regression - I just update everything with my distro's package manager and it took me a while to notice it and realize this is not an issue with my setup, but an upstream issue.

Other info

I use NixOS. and I don't use the gpg-agent systemd units, trying to enable/start them doesn't make a difference.

Details

Version
2.2.17

Event Timeline

Please add

log-file /somewhere/gpg-agent.log
verbose
debug ipc

into ~./.gnupg/gpg-agent.conf. This will log all commands send to gpg-agent and thus also the reload command. It will also show when a SIGHUP is send. My guess is that there are different gpg-agent processes; the log should give you the pids. Please also do a "ps axu | grep gpg-agen[t]" to see which gpg-agent processes are running.

BTW, "gpgconf --reload gpg-agent" is the suggested way to reload the agent and flush the cache.

So my gpg-agent.conf file looks like this now:

pinentry-program /home/doron/.bin/pinentry
allow-loopback-pinentry
enable-ssh-support
default-cache-ttl 7200
log-file /home/doron/desktop/gpg-agent.log
verbose
debug ipc

My pinentry program is this script:

#!/bin/sh
# BASED ON https://unix.stackexchange.com/a/236747/135796
# choose pinentry depending on PINENTRY_USER_DATA
# requires pinentry-curses and pinentry-gtk2
# this *only works* with gpg 2
# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802020

case $PINENTRY_USER_DATA in
	"")
		exec pinentry-tty "$@"
		;;
	curses|emacs|gnome3|gtk-2|qt|tty)
		exec pinentry-${PINENTRY_USER_DATA} "$@"
		;;
	*)
		echo there is no such pinentry program: pinentry-"${PINENTRY_USER_DATA}" >&2
		exit 1
esac

The log is available here: https://gist.github.com/doronbehar/6974f735e3382d613692d2a381202200

During all of my tests, there was only 1 gpg-agent process running, I've verified that through the whole time with htop. Interestingly, in that debug log, I couldn't find anything interesting but the systemd's journal contains:

Nov 09 11:43:56 NUX gpg-agent[12823]: Failed to lookup password for key n/A85E4FC6C29CD42DB9DACBB14871FBABAAC9BC95 with secret service: Cannot autolaunch D-Bus without X11 $DISPLAY

BTW, since I start my X session with startx, these are the relevant parts I have in my .xinitrc:

#!/bin/sh
export PINENTRY_USER_DATA=gtk-2
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
	eval $(dbus-launch --exit-with-session --sh-syntax)
fi
systemctl --user import-environment DISPLAY XAUTHORITY

if command -v dbus-update-activation-environment >/dev/null 2>&1; then
        dbus-update-activation-environment DISPLAY XAUTHORITY
fi

I've also tried using this dbus command instead:

	dbus-update-activation-environment --all --systemd --verbose

But the same error in systemd's journal is present.

Could you try to put no-allow-external-cache in your gpg-agent.conf?
If it changes the behavior, it is your desktop environment which caches your input, I suppose.

doronbehar claimed this task.

Works! I still wonder though: How come my system / gpg agent has all of a sudden started using the external cache? Is this a new feature of gpg-agent? And what is the meaning of this message:

Nov 09 11:43:56 NUX gpg-agent[12823]: Failed to lookup password for key n/A85E4FC6C29CD42DB9DACBB14871FBABAAC9BC95 with secret service: Cannot autolaunch D-Bus without X11 $DISPLAY

?

Sorry in advance for long explanation. :-) Well, let me show my stand point at first (to avoid confusion): I don't like the concept of "desktop integration" when it makes difficult for a user to control his environment.

Before that, the message in your log is non-issue for your use case. It means that libsecret had a trouble about D-Bus (which offers access to services by background processes).
Reference: https://stackoverflow.com/questions/53628122/git-libsecret-throws-cannot-autolaunch-d-bus-without-x11-display
(In Debian, we have a package named dbus-user-session, which initializes DBUS_SESSION_BUS_ADDRESS. You should have similar package in NixOS.)

We had bad experience around 2014 until 2015. In GNOME desktop, gnome-keyring tried to provide the service of gpg-agent (as a replacement, hopefully upward compatible). The purpose is desktop integration, I suppose, not only for gpg, but also for other use cases for passphrase input. Unfortunately, it was done in a way of very unfriendly to GnuPG, and gnome-keyring was never upward compatible. gpg-agent, at that time, had a use case to relay cryptographic operation to scdaemon for smartcard. And, gpg-agent also was in heavy changes for GnuPG 2.2, which consolidates private key operations into gpg-agent (also support SSH). The replacement version only was capable of password management. It is not designed as private key service including smartcard. The consequence was that, many early user of GnuPG 2.1 (for alpha of 2.2) encountered problem, all smartcard users for GnuPG encountered problem. We had to have this: rGffa39be5ebfc: gpg: Print a warning if GKR has hijacked gpg-agent.

In 2015, we somehow settled down to agreement/compromise. Our pinentry-gnome3 should use libsecret (instead of what we do in pinentry-gtk2), so that user experience is just same in GNOME.

Since then, gpg-agent allows pinentry-gnome3 to cache passphrase by libsecret. I think that it is intentional to offer consistent "user experience".

Wow thanks for the great explanation! I've always wondered what is the relationship between gnupg and other secrets services. Personally, although Gnome's / KDE's secrets services offer better UX out of the box, I've always preferred gpg's agent because I can control it better from the command line and hence customize it's behavior. The only use I have for gnome-secrets service is for a few passwords I always want them to be cached (because I obtain them in systemd timers+services). Do you think Gnome / KDE will ever plan to _use_ gpg-agent, instead of reimplementing it?

In my own opinion, it will be good when desktop environments support GnuPG as one of first class citizens, to protect user's data.
For example, currently, libscret stores secret data (such as WiFi shared secret, etc.) by its own cipher preference and method (and it is symmetric cipher by user's password). I don't think it is secure enough.
For me, it will be good if it is protected by user's gpg key using asymmetric crypto.