Gerald Turner
2017-06-16 04:03:44 UTC
I've been upgrading various machines to Debian 9 ("stretch") which has
Emacs 25.1 and has made a transition from classic GnuPG 1.4 to modern
GnuPG 2.1 living in /usr/bin/gpg.
I have two environments where I habitually use Emacs together with
GnuPG:
* A desktop, usually running Debian "testing", and GNOME 3.
* A headless remote server, running Debian "stable", accessed over a
twisted mess of IPsec VPN, OpenSSH, mosh, and GNU screen.
Both these environments have been running systemd for the last few
years. Having an emacs-daemon.service in my systemd user session.
Interestingly Debian's GnuPG 2.1 transition installs gpg-agent.socket in
the user's session as well.
The desktop is fine, it pops up pinentry-gnome3, although sometimes I
think I'd prefer it if Emacs could handle the pinentry rather than block
the entire X11 display, so be it - operational security is probably
better this way. Occasionally I SSH into this desktop, run an
emacs-client, enjoy the bliss of sharing buffers that were opened
earlier, locally on the desktop, but sometimes mistakenly try to use
GnuPG and fail - forgetting that it's gpg-agent is tied to the graphical
desktop.
As for the remote server, prior to upgrading to Debian 9, my
understanding is that Emacs 24, gnus, mml2015, epa-file, etc., were all
calling /usr/bin/gpg (1.4) and prompting for passphrase in the
minibuffer, without any gpg-agent, and passphrase caching was handled
entirely in LISP.
Now that I've upgraded to Debian 9, GnuPG 2.1 spawns pinentry-curses.
While pinentry-curses works fine from the command-line, it's a quite
buggy when spawned under Emacs:
* Keystrokes lag terribly and are frequently ignored.
* Some keys pressed while entering the passhprase are leaked into the
Emacs buffer!
When pinentry-curses is running from an Emacs within a GNU screen it's
even buggier:
* Must C-l to repaint the buffer.
* Must C-z reset RET fg RET to fix some "exotic" keys (like Up, PgDn,
etc.) which send broken escape codes after pinentry-curses exits.
So I've endeavored to fix the Emacs and GnuPG 2.1 situation in this
remote server environment, ignoring the buggy interaction with
pinentry-curses, and seeking some way of having the passphrase entered
via the minibuffer.
There appears to have been work on net/pinentry.el and a specific
'allow-pinentry-emacs' gpg-agent option, however I couldn't get these to
work, and the features seem to have been disabled in Debian¹.
EasyPG Assistant gained support for supplying a --pinentry-mode=loopback
option to gpg:
(setq epa-pinentry-mode 'loopback)
This works wonderfully! Even that occasional mistake I had mentioned
earlier on the desktop environment now works. However this change only
pertains to the epa and epa-file libraries, and doesn't affect gnus,
mml-sec, mml2015, etc. whatsoever.
Following on the nice behavior found in epa-file, I wrote the following
horrendous init hack:
(defun my-epg-make-context (context)
; Make all EasyPG calls use --pinentry-mode=loopback
(setf (epg-context-pinentry-mode context) epa-pinentry-mode)
context)
(advice-add 'epg-make-context :filter-return #'my-epg-make-context)
For a while I basked in the glory of Emacs hackability, as this worked
with decrypting messages, but a day later, with an expired gpg-agent
cache, I found that encrypting or signing a message would still fail
with an obscure "Process epg not running" error, very much like this
backtrace discussed² in a thread last year.
I've tried stepping though mml-secure-epg-encrypt with Edebug, however
unwind-protect and condition-case seem to be inhibiting my ability to
trace these functions down to exactly where "Process epg not running" is
signaled. I've turned up logging, both in gpg-agent and in *epg-debug*
buffer. gpg-agent says "IPC call has been cancelled". At this point
I've given up on my brutal nadvice hack to epg-make-context.
Anyone have any suggestions on how to get Gnus to interact with
gpg-agent like EasyPG Assistant does when epa-pinentry-mode is set to
'loopback?
¹ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854797
² https://lists.gnu.org/archive/html/info-gnus-english/2016-03/msg00023.html
Emacs 25.1 and has made a transition from classic GnuPG 1.4 to modern
GnuPG 2.1 living in /usr/bin/gpg.
I have two environments where I habitually use Emacs together with
GnuPG:
* A desktop, usually running Debian "testing", and GNOME 3.
* A headless remote server, running Debian "stable", accessed over a
twisted mess of IPsec VPN, OpenSSH, mosh, and GNU screen.
Both these environments have been running systemd for the last few
years. Having an emacs-daemon.service in my systemd user session.
Interestingly Debian's GnuPG 2.1 transition installs gpg-agent.socket in
the user's session as well.
The desktop is fine, it pops up pinentry-gnome3, although sometimes I
think I'd prefer it if Emacs could handle the pinentry rather than block
the entire X11 display, so be it - operational security is probably
better this way. Occasionally I SSH into this desktop, run an
emacs-client, enjoy the bliss of sharing buffers that were opened
earlier, locally on the desktop, but sometimes mistakenly try to use
GnuPG and fail - forgetting that it's gpg-agent is tied to the graphical
desktop.
As for the remote server, prior to upgrading to Debian 9, my
understanding is that Emacs 24, gnus, mml2015, epa-file, etc., were all
calling /usr/bin/gpg (1.4) and prompting for passphrase in the
minibuffer, without any gpg-agent, and passphrase caching was handled
entirely in LISP.
Now that I've upgraded to Debian 9, GnuPG 2.1 spawns pinentry-curses.
While pinentry-curses works fine from the command-line, it's a quite
buggy when spawned under Emacs:
* Keystrokes lag terribly and are frequently ignored.
* Some keys pressed while entering the passhprase are leaked into the
Emacs buffer!
When pinentry-curses is running from an Emacs within a GNU screen it's
even buggier:
* Must C-l to repaint the buffer.
* Must C-z reset RET fg RET to fix some "exotic" keys (like Up, PgDn,
etc.) which send broken escape codes after pinentry-curses exits.
So I've endeavored to fix the Emacs and GnuPG 2.1 situation in this
remote server environment, ignoring the buggy interaction with
pinentry-curses, and seeking some way of having the passphrase entered
via the minibuffer.
There appears to have been work on net/pinentry.el and a specific
'allow-pinentry-emacs' gpg-agent option, however I couldn't get these to
work, and the features seem to have been disabled in Debian¹.
EasyPG Assistant gained support for supplying a --pinentry-mode=loopback
option to gpg:
(setq epa-pinentry-mode 'loopback)
This works wonderfully! Even that occasional mistake I had mentioned
earlier on the desktop environment now works. However this change only
pertains to the epa and epa-file libraries, and doesn't affect gnus,
mml-sec, mml2015, etc. whatsoever.
Following on the nice behavior found in epa-file, I wrote the following
horrendous init hack:
(defun my-epg-make-context (context)
; Make all EasyPG calls use --pinentry-mode=loopback
(setf (epg-context-pinentry-mode context) epa-pinentry-mode)
context)
(advice-add 'epg-make-context :filter-return #'my-epg-make-context)
For a while I basked in the glory of Emacs hackability, as this worked
with decrypting messages, but a day later, with an expired gpg-agent
cache, I found that encrypting or signing a message would still fail
with an obscure "Process epg not running" error, very much like this
backtrace discussed² in a thread last year.
I've tried stepping though mml-secure-epg-encrypt with Edebug, however
unwind-protect and condition-case seem to be inhibiting my ability to
trace these functions down to exactly where "Process epg not running" is
signaled. I've turned up logging, both in gpg-agent and in *epg-debug*
buffer. gpg-agent says "IPC call has been cancelled". At this point
I've given up on my brutal nadvice hack to epg-make-context.
Anyone have any suggestions on how to get Gnus to interact with
gpg-agent like EasyPG Assistant does when epa-pinentry-mode is set to
'loopback?
¹ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854797
² https://lists.gnu.org/archive/html/info-gnus-english/2016-03/msg00023.html
--
Gerald Turner <***@unzane.com> Encrypted mail preferred!
OpenPGP: 4096R / CA89 B27A 30FA 66C5 1B80 3858 EC94 2276 FDB8 716D
Gerald Turner <***@unzane.com> Encrypted mail preferred!
OpenPGP: 4096R / CA89 B27A 30FA 66C5 1B80 3858 EC94 2276 FDB8 716D