chiark / gitweb /
Import gnupg2_2.1.18-8~deb9u1.debian.tar.bz2
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Mon, 18 Sep 2017 20:41:12 +0000 (21:41 +0100)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Mon, 18 Sep 2017 20:41:12 +0000 (21:41 +0100)
[dgit import tarball gnupg2 2.1.18-8~deb9u1 gnupg2_2.1.18-8~deb9u1.debian.tar.bz2]

140 files changed:
NEWS [new file with mode: 0644]
Xsession.d/90gpg-agent [new file with mode: 0644]
changelog [new file with mode: 0644]
clean [new file with mode: 0644]
compat [new file with mode: 0644]
control [new file with mode: 0644]
copyright [new file with mode: 0644]
dirmngr.NEWS [new file with mode: 0644]
dirmngr.README.Debian [new file with mode: 0644]
dirmngr.docs [new file with mode: 0644]
dirmngr.install [new file with mode: 0644]
dirmngr.links [new file with mode: 0644]
dirmngr.maintscript [new file with mode: 0644]
dirmngr.manpages [new file with mode: 0644]
gbp.conf [new file with mode: 0644]
gnupg-agent.NEWS [new file with mode: 0644]
gnupg-agent.README.Debian [new file with mode: 0644]
gnupg-agent.examples [new file with mode: 0644]
gnupg-agent.install [new file with mode: 0644]
gnupg-agent.links [new file with mode: 0644]
gnupg-agent.manpages [new file with mode: 0644]
gnupg-l10n.install [new file with mode: 0644]
gnupg.README.Debian [new file with mode: 0644]
gnupg.docs [new file with mode: 0644]
gnupg.examples [new file with mode: 0644]
gnupg.info [new file with mode: 0644]
gnupg.install [new file with mode: 0644]
gnupg.manpages [new file with mode: 0644]
gnupg2.links [new file with mode: 0644]
gpg-check-pattern.1 [new file with mode: 0644]
gpg-zip.1 [new file with mode: 0644]
gpgsm.install [new file with mode: 0644]
gpgsm.manpages [new file with mode: 0644]
gpgsplit.1 [new file with mode: 0644]
gpgv-static.1 [new file with mode: 0644]
gpgv-static.install [new file with mode: 0644]
gpgv-static.lintian-overrides [new file with mode: 0644]
gpgv-static.manpages [new file with mode: 0644]
gpgv-udeb.install [new file with mode: 0644]
gpgv-win32.install [new file with mode: 0644]
gpgv.install [new file with mode: 0644]
gpgv.manpages [new file with mode: 0644]
gpgv2.links [new file with mode: 0644]
kbxutil.1 [new file with mode: 0644]
lspgpot.1 [new file with mode: 0644]
migrate-pubring-from-classic-gpg [new file with mode: 0755]
migrate-pubring-from-classic-gpg.1 [new file with mode: 0644]
patches/0012-tools-Fix-memory-leak.patch [new file with mode: 0644]
patches/0013-tools-Improve-error-handling.patch [new file with mode: 0644]
patches/0014-dirmngr-New-option-disable-ipv4.patch [new file with mode: 0644]
patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch [new file with mode: 0644]
patches/0016-gpg-Print-a-warning-on-Tor-problems.patch [new file with mode: 0644]
patches/0017-agent-Fix-double-free.patch [new file with mode: 0644]
patches/0018-gpg-Fix-searching-for-mail-addresses-in-keyrings.patch [new file with mode: 0644]
patches/0019-dirmngr-New-option-no-use-tor-and-internal-changes.patch [new file with mode: 0644]
patches/0020-gpg-Remove-period-at-end-of-warning.patch [new file with mode: 0644]
patches/0021-gpg-Add-newline-to-output.patch [new file with mode: 0644]
patches/0022-gpg-Only-print-out-TOFU-statistics-for-conflicts-in-.patch [new file with mode: 0644]
patches/0023-gpg-If-there-is-a-TOFU-conflict-elide-the-too-few-me.patch [new file with mode: 0644]
patches/0024-gpg-Ensure-TOFU-bindings-associated-with-UTKs-are-re.patch [new file with mode: 0644]
patches/0025-gpg-Don-t-assume-that-strtoul-interprets-as-0.patch [new file with mode: 0644]
patches/0026-gpg-More-diagnostics-for-a-launched-pinentry.patch [new file with mode: 0644]
patches/0027-doc-Clarify-abbreviation-of-help.patch [new file with mode: 0644]
patches/0028-scd-Backport-two-fixes-from-master.patch [new file with mode: 0644]
patches/0029-scd-Fix-use-case-of-PC-SC.patch [new file with mode: 0644]
patches/0030-scd-Fix-factory-reset.patch [new file with mode: 0644]
patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch [new file with mode: 0644]
patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch [new file with mode: 0644]
patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch [new file with mode: 0644]
patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch [new file with mode: 0644]
patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch [new file with mode: 0644]
patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch [new file with mode: 0644]
patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch [new file with mode: 0644]
patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch [new file with mode: 0644]
patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch [new file with mode: 0644]
patches/0040-gpgv-w32-Fix-status-fd.patch [new file with mode: 0644]
patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch [new file with mode: 0644]
patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch [new file with mode: 0644]
patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch [new file with mode: 0644]
patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch [new file with mode: 0644]
patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch [new file with mode: 0644]
patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch [new file with mode: 0644]
patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch [new file with mode: 0644]
patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch [new file with mode: 0644]
patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch [new file with mode: 0644]
patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch [new file with mode: 0644]
patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch [new file with mode: 0644]
patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch [new file with mode: 0644]
patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch [new file with mode: 0644]
patches/0054-dirmngr-Fix-error-handling.patch [new file with mode: 0644]
patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch [new file with mode: 0644]
patches/0056-common-Fix-connecting-to-the-agent.patch [new file with mode: 0644]
patches/0057-g10-Fix-memory-leak.patch [new file with mode: 0644]
patches/0058-common-Avoid-undefined-behavior.patch [new file with mode: 0644]
patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch [new file with mode: 0644]
patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch [new file with mode: 0644]
patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch [new file with mode: 0644]
patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch [new file with mode: 0644]
patches/0063-dirmngr-New-option-disable-ipv6.patch [new file with mode: 0644]
patches/0064-agent-Serialize-access-to-passphrase-cache.patch [new file with mode: 0644]
patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch [new file with mode: 0644]
patches/0066-doc-Explain-the-in-a-key-listing.patch [new file with mode: 0644]
patches/0067-dirmngr-Fix-possible-null-reference.patch [new file with mode: 0644]
patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch [new file with mode: 0644]
patches/0069-dirmngr-Fix-alignment-of-ADDR.patch [new file with mode: 0644]
patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch [new file with mode: 0644]
patches/0071-g10-Fix-import-export-filter-property-match.patch [new file with mode: 0644]
patches/0072-g10-Minor-fixes.patch [new file with mode: 0644]
patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch [new file with mode: 0644]
patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch [new file with mode: 0644]
patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch [new file with mode: 0644]
patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch [new file with mode: 0644]
patches/block-ptrace-on-agent/0002-Avoid-simple-memory-dumps-via-ptrace.patch [new file with mode: 0644]
patches/debian-packaging/0001-avoid-beta-warning.patch [new file with mode: 0644]
patches/debian-packaging/0003-avoid-regenerating-defsincdate-use-shipped-file.patch [new file with mode: 0644]
patches/dirmngr-idling/0001-dirmngr-hkp-Avoid-potential-race-condition-when-some.patch [new file with mode: 0644]
patches/dirmngr-idling/0002-dimrngr-Avoid-need-for-hkp-housekeeping.patch [new file with mode: 0644]
patches/dirmngr-idling/0004-dirmngr-Avoid-automatically-checking-upstream-swdb.patch [new file with mode: 0644]
patches/dirmngr-idling/0005-dirmngr-Drop-useless-housekeeping.patch [new file with mode: 0644]
patches/gpg-agent-idling/0001-agent-Create-framework-of-scheduled-timers.patch [new file with mode: 0644]
patches/gpg-agent-idling/0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch [new file with mode: 0644]
patches/gpg-agent-idling/0003-agent-Avoid-tight-timer-tick-when-possible.patch [new file with mode: 0644]
patches/gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch [new file with mode: 0644]
patches/series [new file with mode: 0644]
patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch [new file with mode: 0644]
patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch [new file with mode: 0644]
rules [new file with mode: 0755]
scdaemon.examples [new file with mode: 0644]
scdaemon.install [new file with mode: 0644]
scdaemon.lintian-overrides [new file with mode: 0644]
scdaemon.manpages [new file with mode: 0644]
scdaemon.udev [new file with mode: 0644]
source/format [new file with mode: 0644]
source/lintian-overrides [new file with mode: 0644]
source/options [new file with mode: 0644]
systemd-user/gpg-agent-browser.socket [new file with mode: 0644]
tests/control [new file with mode: 0644]
tests/gpgv-win32 [new file with mode: 0755]
upstream/signing-key.asc [new file with mode: 0644]
watch [new file with mode: 0644]

diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..0a6a744
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,8 @@
+gnupg2 (2.1.11-7+exp1) experimental; urgency=medium
+
+  The gnupg package now provides the "modern" version of GnuPG.
+
+  Please read /usr/share/doc/gnupg/README.Debian for details about the
+  transition from "classic" to "modern"
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 30 Mar 2016 09:59:35 -0400
diff --git a/Xsession.d/90gpg-agent b/Xsession.d/90gpg-agent
new file mode 100644 (file)
index 0000000..8b45b05
--- /dev/null
@@ -0,0 +1,22 @@
+# On systems with systemd running, we expect the agent to be launched
+# via systemd's user mode (see
+# /usr/lib/systemd/user/gpg-agent.{socket,service} and
+# systemd.unit(5)).  This allows systemd to clean up the agent
+# automatically at logout.
+
+# If systemd is absent from your system, or you do not permit it to
+# run in user mode, then you may need to manually launch gpg-agent
+# from your session initialization with something like "gpgconf
+# --launch gpg-agent"
+
+# Nonetheless, ssh and older versions of gpg require environment
+# variables to be set in order to find the agent, so we will set those
+# here.
+
+agent_sock=$(gpgconf --list-dirs agent-socket)
+export GPG_AGENT_INFO=${agent_sock}:0:1
+if [ -n "$(gpgconf --list-options gpg-agent | \
+      awk -F: '/^enable-ssh-support:/{ print $10 }')" ]; then
+    export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
+fi
+
diff --git a/changelog b/changelog
new file mode 100644 (file)
index 0000000..5696d2a
--- /dev/null
+++ b/changelog
@@ -0,0 +1,1987 @@
+gnupg2 (2.1.18-8~deb9u1) stretch; urgency=medium
+
+  * Bugfix update for debian stretch point release.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 18 Sep 2017 16:41:12 -0400
+
+gnupg2 (2.1.18-8) unstable; urgency=medium
+
+  * updated scdaemon fix from gniibe (Closes: #862032)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 08 May 2017 19:20:45 -0400
+
+gnupg2 (2.1.18-7) unstable; urgency=medium
+
+  * scdaemon fixes from gniibe
+  * more upstream fixes (Closes: #854359, #854829)
+  * skip over missing signing keys (Closes: #834922)
+  * drop all skel files (Closes: #858082)
+  * Avoid spurious warnings when sharing a keybox with gpg >= 2.1.20
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 05 May 2017 23:06:48 -0400
+
+gnupg2 (2.1.18-6) unstable; urgency=medium
+
+  [ NIIBE Yutaka ]
+  * scdaemon: Fix duplicated entries (Closes: #855056).
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 13 Feb 2017 19:29:34 -0500
+
+gnupg2 (2.1.18-5) unstable; urgency=medium
+
+  [ Daniel Kahn Gillmor ]
+  * Xsession.d/90gpg-agent: use simpler and more direct gpgconf
+    invocations for socket names.
+
+  [ NIIBE Yutaka ]
+  * scdaemon.udev: Add Yubikey and Nitrokey (Closes: #648331, 734889).
+  * scdaemon fix for PC/SC (Closes: #852702, #854005, #854595, #854616).
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 13 Feb 2017 09:15:07 -0500
+
+gnupg2 (2.1.18-4) unstable; urgency=medium
+
+  [ Daniel Kahn Gillmor ]
+  * document that debian disables --allow-version-check
+  * docs, debugging, and bugfix patches from upstream (Closes: #852979)
+
+  [ NIIBE Yutaka ]
+  * scdaemon bugfixes
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 04 Feb 2017 22:03:26 -0500
+
+gnupg2 (2.1.18-3) unstable; urgency=medium
+
+  * fix searches for keys with raw addr-spec
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 25 Jan 2017 16:58:56 -0500
+
+gnupg2 (2.1.18-2) unstable; urgency=medium
+
+  * pull fixes from upstream (including a double-free in gpg-agent)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 25 Jan 2017 09:29:25 -0500
+
+gnupg2 (2.1.18-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 23 Jan 2017 23:12:35 -0500
+
+gnupg2 (2.1.17-6) unstable; urgency=medium
+
+  * Upstream patches, fixing unnecessary delay in gpg-agent (Closes: #851298)
+  * gpg-agent: avoid race in shutdown (Closes: #841143)
+  * improve dirmngr, gpg-agent README.Debian (Closes: #850982)
+  * clean up gpg-agent-idling patch
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 18 Jan 2017 14:40:41 -0500
+
+gnupg2 (2.1.17-5) unstable; urgency=medium
+
+  * more fixes from upstream (improving but not yet closing: #849845)
+  * gpg-agent: actively poll when shutdown is pending.  Thanks, NIIBE
+    Yutaka! (addresses but does not close #841143)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 11 Jan 2017 15:44:57 -0500
+
+gnupg2 (2.1.17-4) unstable; urgency=medium
+
+  * more patches from upstream, including dirmngr debugging
+    improvements
+  * resolve ambiguity in aliased options and commands (Closes: #850475)
+  * auto-enable gpg-agent and dirmngr for systemd user sessions
+  * enable easy reloads from systemd
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 10 Jan 2017 17:30:08 -0500
+
+gnupg2 (2.1.17-3) unstable; urgency=medium
+
+  * more bugfixes from upstream (improving but not yet closing: #849845)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 03 Jan 2017 15:39:52 -0500
+
+gnupg2 (2.1.17-2) unstable; urgency=medium
+
+  * include patches from upstream to avoid build failures on 32-bit
+    arches.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 24 Dec 2016 18:11:51 -0500
+
+gnupg2 (2.1.17-1) unstable; urgency=medium
+
+  * new upstream release.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 24 Dec 2016 15:39:04 -0500
+
+gnupg2 (2.1.16-3) unstable; urgency=medium
+
+  * remove -pie from hppa, kfreebsd-amd64, and x32 builds of
+    gpgv-static (Closes: #846889)
+  * import several upstream bugfix patches (Closes: #846834, #846168)
+  * link gnupg-agent and scdaemon with Enhances/Suggests (Closes: #833518)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 05 Dec 2016 15:34:49 -0500
+
+gnupg2 (2.1.16-2) unstable; urgency=medium
+
+  * avoid using adns, due to lack of security support (Closes: #845078)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 21 Nov 2016 09:57:26 -0500
+
+gnupg2 (2.1.16-1) unstable; urgency=medium
+
+  * New upstream version
+  * dropped many patches already incorporated upstream
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sun, 20 Nov 2016 23:22:49 -0500
+
+gnupg2 (2.1.15-9) unstable; urgency=medium
+
+  * Introduce gpgv-static package (Closes: #806940)
+  * more patches from upstream
+  * use adns for better DNS resolution in dirmngr
+  * add some import-options to
+    migrate-pubring-from-classic-gpg for better migration
+  * reorganize patches to distinguish debian variations from upstream
+  * set simple and easy defaults for keyservers
+  * help dirmngr and gpg-agent idle better in the default case
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 10 Nov 2016 07:28:16 -0800
+
+gnupg2 (2.1.15-8) unstable; urgency=medium
+
+  * rename gpg-agent-restricted.socket to gpg-agent-extra.socket
+    (for symmetry with option names and actual sockets created)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 27 Oct 2016 13:54:53 -0400
+
+gnupg2 (2.1.15-7) unstable; urgency=medium
+
+  * more upstream patches
+  * dirmngr systemd user service is now socket-activated.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 27 Oct 2016 12:48:15 -0400
+
+gnupg2 (2.1.15-6) unstable; urgency=medium
+
+  * more upstream patches (Closes: #841437, #840680)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 26 Oct 2016 17:44:20 -0400
+
+gnupg2 (2.1.15-5) unstable; urgency=medium
+
+  * added udev rules for Fujitsu Siemens cardreader (Closes: #840312)
+  * mark transitional packages Multi-Arch: Foreign (closes: #840258)
+  * make gnupg2 binNMU-safe
+  * more patches from upstream
+  * track upstream decision-making about gpg-agent socket names
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 25 Oct 2016 21:30:06 -0400
+
+gnupg2 (2.1.15-4) unstable; urgency=medium
+
+  * update debian/tests/gpgv-win32
+  * more patches from upstream (Closes: #838153)
+  * tighten dependencies between gnupg and dirmngr (Closes: #834602)
+  * updated systemd user gpg-agent units for socket activation
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 04 Oct 2016 17:22:30 -0400
+
+gnupg2 (2.1.15-3) unstable; urgency=medium
+
+  * Use upstream fix to avoid touching homedir during test suite
+  * backward compatibility for preset-passphrase and protect-tool
+  * add Breaks: for python3-apt too (thanks, Harald Jenny!)
+  * Avoid network access during tests (Closes: #836259)
+  * more patches from upstream
+   - gpgv --output now works
+   - fingerprint display doesn't vary with --keyid-format
+   - minor cleanup to scdaemon dealing with removed cards
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 14 Sep 2016 17:08:58 -0400
+
+gnupg2 (2.1.15-2) unstable; urgency=medium
+
+  * restore keyid output in gpgv (Closes: #836144)
+  * avoid test suite failures when HOME does not exist
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 31 Aug 2016 12:37:48 -0400
+
+gnupg2 (2.1.15-1) unstable; urgency=medium
+
+  * new upstream release
+   - blocks signals during keyring updates (Closes: #293556)
+  * avoid libusb on hurd.  Thanks, Pino Toscano! (Closes: #834533)
+  * permissions on test suite are already fixed
+  * drop patches applied upstream and refresh remaining patches
+  * make gnupg2 reproducible by not regenerating documentation date
+  * make autopkgtest work with modern wine (Closes: #835976)
+  * wrap-and-sort -ast for cleaner diffs
+  * add versioned Breaks: for affected packages (Closes: #835349)
+   - gpgv Breaks: python-debian << 0.1.29 (addresses: #782904)
+   - gnupg Breaks: php-crypt-gpg <= 1.4.1-1 (addresses #835592)
+   - gnupg Breaks: python-apt <= 1.1.0~beta4 (addresses: #835465)
+   - gnupg Breaks: python-gnupg << 0.3.8-3 (addresses: #834514, #834600)
+   - gnupg Breaks: libgnupg-interface-perl << 0.52-3 (addresses: #834281)
+   - gnupg Breaks: libmail-gnupg-perl <= 0.22-1 (addresses: #835075)
+   - gnupg Breaks: libgnupg-perl << 0.19-1 (addresses: #834522)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 30 Aug 2016 13:19:23 -0400
+
+gnupg2 (2.1.14-5) unstable; urgency=medium
+
+  * actually ship /usr/share/doc/gnupg/README.Debian
+  * Release to unstable.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 12 Aug 2016 16:27:22 -0400
+
+gnupg2 (2.1.14-4) experimental; urgency=medium
+
+  * add ZeitControl card (Closes: #814584)
+  * three more fixes from upstream
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 08 Aug 2016 12:54:21 -0400
+
+gnupg2 (2.1.14-3) experimental; urgency=medium
+
+  * cleanup debian/copyright
+  * update debian/watch
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 03 Aug 2016 11:09:05 -0400
+
+gnupg2 (2.1.14-2) experimental; urgency=medium
+
+  * mark the gpgv binary as Priority: important, since apt depends on it
+  * import a bunch of fixes from upstream
+  * include permissioning on patched-in tests
+  * Breaks: some packages that expect old gpg behavior (Closes: #831500)
+  * remove scdaemon.service; it will be managed by gpg-agent.service
+  * avoid bulleted items in debian/NEWS (thanks, Lintian!)
+  * debian/copyright: cleanup, fix URLs
+  * debian/control: use standard URL for Vcs-Browser
+  * fix spelling and grammar noticed by lintian
+  * avoid lintian notes about a misspelled "written"
+  * clean up gpgv2 Description
+  * break out arch-indep localization files into new gnupg-l10n package
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 01 Aug 2016 17:54:59 -0400
+
+gnupg2 (2.1.14-1) experimental; urgency=medium
+
+  * New upstream release
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 15 Jul 2016 01:39:25 +0200
+
+gnupg2 (2.1.13-5) experimental; urgency=medium
+
+  * dependency cleanup!
+   - make Recommends: strictly versioned between gnupg and {gpg-agent,dirmngr}
+   - make gnupg Provide: gpg and mention it in the package description
+   - drop mention of newpg, which has not been in debian for many releases
+   - gnupg2 2.0.18 predates debian wheezy, which is oldstable; drop mention
+     in debian/control
+   - drop Suggests: gnupg-doc, which does not appear to be maintained
+   - drop all references to gpg-idea, which has not been in debian for
+     several releases
+   - removed dependency on "dpkg (>= 1.15.4) | install-info", since that
+     dpkg version predates oldstable (wheezy)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 04 Jul 2016 10:13:42 -0400
+
+gnupg2 (2.1.13-4) experimental; urgency=medium
+
+  * add binutils-multiarch [!amd64 !i386] to Build-Depends-Indep: so that
+    we can generate win32 packages on non-x86 platforms.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 01 Jul 2016 11:30:28 -0400
+
+gnupg2 (2.1.13-3) experimental; urgency=medium
+
+  * pull bugfixes from upstream (Closes: #828109, #814584)
+  * should also allow for reproducible builds, with fix to
+    timestamps in tofu.test
+  * provide supervised dirmngr, gpg-agent, and scdaemon services from
+    systemd's user sessioniif the user wants to enable them.  These
+    services should terminate at logout (Closes: #825911)
+  * avoid launching gpg-agent from Xsession.d since we have more robust
+    session management available (added NEWS entry about this change)
+  * gnupg-agent now Provides: gpg-agent to mitigate common confusion.
+  * updated dirmngr package description.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 28 Jun 2016 13:46:36 -0400
+
+gnupg2 (2.1.13-2) experimental; urgency=medium
+
+  * brown paper bag time: fix build-dep from libusb-1.0.0-dev to
+    libusb-1.0-0-dev
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 17 Jun 2016 23:07:43 -0400
+
+gnupg2 (2.1.13-1) experimental; urgency=medium
+
+  * New upstream release
+   - new keyid-format "none", used by default (Closes: #826273)
+  * Build-depend on libusb-1.0.0-dev to ensure smartcards work (Thanks,
+    gniibe!)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 16 Jun 2016 18:30:36 -0400
+
+gnupg2 (2.1.12-1) experimental; urgency=medium
+
+  * New upstream release
+  
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 10 May 2016 20:58:06 -0400
+
+gnupg2 (2.1.11-7+exp1) experimental; urgency=medium
+
+  * switching over binary package names in experimental -- gnupg2 source
+    package now provides gnupg and gpgv
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 18 Apr 2016 19:17:19 -0400
+
+gnupg2 (2.1.11-7) unstable; urgency=medium
+
+  * move to unstable
+  * re-enable test suites on mips and mipsel since #730846 is resolved
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 18 Apr 2016 07:45:16 -0400
+
+gnupg2 (2.1.11-6+exp4) experimental; urgency=medium
+
+  * stop using help2man to fix cross-building
+  * ensure gpgv-win32 is properly stripped
+  * enable autopkgtest to run without root on systems that already have
+    wine32 installed
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 01 Apr 2016 13:08:07 -0300
+
+gnupg2 (2.1.11-6+exp3) experimental; urgency=medium
+
+  * more cleanup on arch-dependent packages.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 30 Mar 2016 03:36:18 -0400
+
+gnupg2 (2.1.11-6+exp2) experimental; urgency=medium
+
+  * avoid build failures when building only arch-dependent or only
+    arch-independent packages.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 30 Mar 2016 02:59:18 -0400
+
+gnupg2 (2.1.11-6+exp1) experimental; urgency=medium
+
+  * take over gpgv-win32 from gnupg 1.4 packaging
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 28 Mar 2016 23:27:43 -0400
+
+gnupg2 (2.1.11-6) unstable; urgency=medium
+
+  * avoid FTBFS with patch from upstream (Closes: #814842)
+  * bumped standards-version to 3.9.7 (no changes needed)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 01 Mar 2016 09:36:41 +0100
+
+gnupg2 (2.1.11-5) unstable; urgency=medium
+
+  * taking over gpgv-udeb from gnupg 1.4 packaging
+  * debian/control: use secure transport for Vcs-* and Homepage
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 04 Feb 2016 17:17:47 -0500
+
+gnupg2 (2.1.11-4) unstable; urgency=medium
+
+  * disable gpgtar, since it is causing unpredictable testsuite failures
+    and we don't ship it anyway.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 03 Feb 2016 11:57:57 -0500
+
+gnupg2 (2.1.11-3) unstable; urgency=medium
+
+  * trying again to get a proper dump of the gpgtar.test.log. sigh.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 28 Jan 2016 08:34:22 -0500
+
+gnupg2 (2.1.11-2) unstable; urgency=medium
+
+  * added temporary hook to view failing gpgtar test output on build
+    daemons since i can't replicate the failures on my own build systems.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 28 Jan 2016 00:53:29 -0500
+
+gnupg2 (2.1.11-1) unstable; urgency=medium
+
+  * new upstream release
+    - drops buggy attempt to detect duplicate keys (Closes: #807819)
+  * removed -dbg package, since we have automatic -dbgsym packages now
+  * removed undocumented gpgkey2ssh; use gpg --export-ssh-key instead
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 25 Jan 2016 15:29:25 -0500
+
+gnupg2 (2.1.10-3) unstable; urgency=medium
+
+  * avoid infinite loop when doing --gen-revoke by fingerprint
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 12 Dec 2015 16:53:40 -0500
+
+gnupg2 (2.1.10-2) unstable; urgency=medium
+
+  * actually use sks-keyservers CA by default if the user asks for
+    hkps://hkps.pool.sks-keyservers.net
+  * move ownership of some files in /usr/share/gnupg2/ to more appropriate
+    owners like gpgsm and dirmngr.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 11 Dec 2015 17:06:10 -0500
+
+gnupg2 (2.1.10-1) unstable; urgency=medium
+
+  * new upstream release
+  * ship sks-keyservers.netCA.pem in dirmngr to make it easier to use hkps.
+  * avoid shipping Changelog-2011, use upstream ChangeLog (Closes:
+    #803225)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 09 Dec 2015 12:05:42 -0500
+
+gnupg2 (2.1.9-1) unstable; urgency=medium
+
+  * New upstream release
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 13 Oct 2015 10:04:33 -0400
+
+gnupg2 (2.1.8-2) UNRELEASED; urgency=medium
+
+  [ NIIBE Yutaka ]
+  * update scdaemon dependencies
+
+  [ Daniel Kahn Gillmor ]
+  * correct ssh fingerprint for ECDSA nistp384 (Closes: #795636)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 17 Sep 2015 00:00:28 -0400
+
+gnupg2 (2.1.8-1) unstable; urgency=medium
+
+  * New upstream release
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 10 Sep 2015 17:00:06 -0400
+
+gnupg2 (2.1.7-2) unstable; urgency=medium
+
+  * upload to unstable
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 11 Aug 2015 21:24:18 -0400
+
+gnupg2 (2.1.7-1) experimental; urgency=medium
+
+  * new upstream release
+  * block ptrace connections to gpg-agent
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 11 Aug 2015 20:05:38 -0400
+
+gnupg2 (2.1.6-1) experimental; urgency=medium
+
+  * new upstream release
+  * drop deprecated gpgsm-gencert.sh
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 07 Jul 2015 14:27:23 -0400
+
+gnupg2 (2.1.5-2) experimental; urgency=medium
+
+  [ Daniel Kahn Gillmor ]
+  * pass DBUS_SESSION_BUS_ADDRESS through to the agent so that
+    pinentry-gnome3 can work across sessions.
+  * ensure that l10n files are rebuilt.
+
+  [ Eric Dorland ]
+  * debian/patches/0003-Include-defs.inc-in-BUILT_SOURCES.patch: Fix for
+    build failure when rebuilding info docs.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 30 Jun 2015 18:13:58 -0400
+
+gnupg2 (2.1.5-1) experimental; urgency=medium
+
+  * New upstream release
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 11 Jun 2015 13:18:56 -0400
+
+gnupg2 (2.1.4-2) experimental; urgency=medium
+
+  * avoid excess dependencies on headless servers (Closes: #753163)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 03 Jun 2015 14:12:49 -0400
+
+gnupg2 (2.1.4-1) experimental; urgency=medium
+
+  * New upstream release.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 28 May 2015 00:25:55 -0400
+
+gnupg2 (2.1.3-1) experimental; urgency=medium
+
+  * New upstream version.
+  * Add gnupg2-dbg (Closes: #781631)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 01 Apr 2015 12:10:38 -0400
+
+gnupg2 (2.1.2-2) experimental; urgency=medium
+
+  * Fix segv due to NULL value stored as opaque MPI.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 21 Feb 2015 10:26:50 -0500
+
+gnupg2 (2.1.2-1) experimental; urgency=medium
+
+  * New upstream version
+  * move from automake1.11 to plain automake (upstream uses 1.14 now)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 12 Feb 2015 20:10:43 -0500
+
+gnupg2 (2.1.1-1) experimental; urgency=medium
+
+  * New upstream version (closes: #772654)
+  * gnupg2 now Breaks: older versions of dirmngr (closes: #769460)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 16 Dec 2014 14:58:06 -0500
+
+gnupg2 (2.1.0-1) experimental; urgency=medium
+
+  * import upstream 2.1.0 release.
+  * drop debian/patches/speed-up-test-suite.patch -- included upstream.
+  * avoid self-reporting as a beta now that this is a release
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 06 Nov 2014 12:31:06 -0500
+
+gnupg2 (2.1.0~beta895-3) experimental; urgency=medium
+
+  * update gnupg-agent.xsession to export ssh-agent where
+    configured. (Closes: #767341)
+  * use cheap/fast entropy for the test suite so that builds on
+    low-entropy machines go faster.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 30 Oct 2014 13:37:08 -0400
+
+gnupg2 (2.1.0~beta895-2) experimental; urgency=medium
+
+  * added pkg-config to Build-Depends.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 29 Oct 2014 18:36:27 -0400
+
+gnupg2 (2.1.0~beta895-1) experimental; urgency=medium
+
+  * new upstream version in experimental (Closes: #762844, #751266, #762844)
+  * ship /usr/bin/gpgparsemail (Closes: #760575)
+  * document that doc/OpenPGP is not actually an RFC, but just refers to
+    one (closes: #745410)
+  * Bump Standards-Version to 3.9.6 (no changes needed)
+  * --enable-large-secmem to ensure that gpg2 works with pre-generated
+    oversized RSA keys
+  * updated /etc/X11/Xsession.d/90gpg-agent to export $GPG_AGENT_INFO
+    about the standard socket.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Wed, 29 Oct 2014 17:53:06 -0400
+
+gnupg2 (2.0.28-3) unstable; urgency=medium
+
+  * pass DBUS_SESION_BUS_ADDRESS to the agent for gnome3.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 04 Jul 2015 14:21:41 -0400
+
+gnupg2 (2.0.28-2) unstable; urgency=medium
+
+  * d/clean: drop stamp-po to rebuild l10n (Closes: #788989)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 30 Jun 2015 17:17:11 -0400
+
+gnupg2 (2.0.28-1) unstable; urgency=medium
+
+  * new upstream release
+  * really address excess dependencies on headless server (thanks Raphaël
+    Halimi for noticing) (Closes: #753163)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 02 Jun 2015 12:16:57 -0400
+
+gnupg2 (2.0.27-2) unstable; urgency=medium
+
+  * import upstream fix to avoid replicating unknown subkey
+    packets. (Closes: #787045) (Thanks, NIIBE Yutaka)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 28 May 2015 00:55:51 -0400
+
+gnupg2 (2.0.27-1) unstable; urgency=medium
+
+  * New upstream release.
+  * Provide a simple way for users to avoid gpg-agent hijacking,
+    working around: #760102 (Closes: #753163)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 08 May 2015 18:15:15 -0400
+
+gnupg2 (2.0.26-6) unstable; urgency=medium
+
+  * Avoid NULL dereference with opaque MPI.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 21 Feb 2015 18:01:40 -0500
+
+gnupg2 (2.0.26-5) unstable; urgency=medium
+
+  * import bug-fixes from upstream
+    (Closes: #773415, #773469, #773471, #773472, #773423)
+  * Fixes CVE-2015-1606 "Use after free, resulting from failure to skip
+    invalid packets", CVE-2015-1607 "memcpy with overlapping ranges,
+    resulting from incorrect bitwise left shifts" (Closes: #778577)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 16 Feb 2015 17:45:06 -0500
+
+gnupg2 (2.0.26-4) unstable; urgency=medium
+
+  [ David Prévot ]
+  * Update POT and PO files, and ensure the translations get rebuild
+  * Update French translation (Closes: #769574)
+  * Update Ukrainian translation, thanks to Yuri Chornoivan
+  * Update German translation, thanks to Werner Koch
+  * Update Danish translation, thanks to Joe Hansen
+  * Update Japanese translation, thanks to NIIBE Yutaka
+  * Update Chinese (traditional) translation, thanks to Jedi Lin
+  * Update Russian translation, thanks to Ineiev
+  * Update Polish translation, thanks to Jakub Bogusz
+  * Update Spanish translation, thanks to Manuel "Venturi" Porras Peralta
+    (Closes: #770727)
+  * New Dutch translation, thanks to Frans Spiesschaert (Closes: #770981)
+
+  [ Daniel Kahn Gillmor ]
+  * bugfix and cryptographic safety changes imported from upstream:
+   - Avoid regression when adding subkeys with strong s2k algorithms
+     (Closes: #772780) Thanks, NIIBE Yutaka
+   - Allow french translation to work when prompting for passphrase.
+   - add build and runtime support for larger RSA keys (Closes: #739424)
+   - fix runtime errors on bad input (Closes: #771987)
+   - deprecate insecure one-argument variant for gpg --verify of detached
+     signatures (Closes: #771992)
+   - initialize trustdb before trying to clear it (Closes: #735363)
+   - default to issuing SHA256 signatures for RSA
+   - avoid relying on MD5 signatures
+   - show v3 key fingerprints as all zero (OpenPGPv3 is deprecated)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sun, 04 Jan 2015 17:17:00 -0500
+
+gnupg2 (2.0.26-3) unstable; urgency=medium
+
+  * fix typo in gpg.info (closes: #760273)
+  * drop versioned Build-Conflicts on automake by setting environment
+    variables in debian/rules
+  * ship /usr/bin/gpgparsemail (closes: #760575)
+  * warn but don't fail when scdaemon options are in ~/.gnupg/gpg.conf
+    (closes: #762844)
+  * do not break on --trust-model=always (closes: #751266)
+  * document that doc/OpenPGP is not actually an RFC, but just refers to
+    one (closes: #745410)
+  * Bump Standards-Version to 3.9.6 (no changes needed)
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 30 Sep 2014 23:39:15 -0400
+
+gnupg2 (2.0.26-2) unstable; urgency=medium
+
+  * ignore emacs turds in debian/
+  * update Vcs fields
+  * move package to group maintenance
+  * wrap-and-sort cleanup of debian/*
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 28 Aug 2014 11:42:18 -0700
+
+gnupg2 (2.0.26-1) unstable; urgency=medium
+
+  * New upstream release.
+  * debian/control: Suggest parcimonie. Thanks ilf. (Closes: #752261)
+
+ -- Eric Dorland <eric@debian.org>  Tue, 19 Aug 2014 18:09:08 -0400
+
+gnupg2 (2.0.25-2) unstable; urgency=medium
+
+  * debian/control: Switch to libgcrypt20-dev (aka 1.6 release).
+
+ -- Eric Dorland <eric@debian.org>  Fri, 08 Aug 2014 14:12:05 -0400
+
+gnupg2 (2.0.25-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Eric Dorland <eric@debian.org>  Mon, 30 Jun 2014 13:10:04 -0400
+
+gnupg2 (2.0.24-1) unstable; urgency=high
+
+  * New upstream release. Fixes CVE-2014-4617 "infinite loop when
+    decompressing data packets". (Closes: #752498)
+  * debian/patches/02-gpgv2-dont-link-libassuan.diff: Drop, now
+    upstreamed.
+
+ -- Eric Dorland <eric@debian.org>  Wed, 25 Jun 2014 00:11:19 -0400
+
+gnupg2 (2.0.23-1) unstable; urgency=medium
+
+  * New upstream release.
+  * debian/upstream/signing-key.asc: Rename upstream-signing-key.pgp to
+    the new, supported name.
+  * debian/control: Restore versioned conflict against gpg-idea. (Closes:
+    #733984)
+  * debian/control: Add Recommends on dirmngr for gpgsm. (Closes: #683579)
+
+ -- Eric Dorland <eric@debian.org>  Sun, 08 Jun 2014 19:20:17 -0400
+
+gnupg2 (2.0.22-3) unstable; urgency=low
+
+  * debian/watch, debian/upstream-signing-key.pgp: Add upstream signing
+    key for uscan verification.
+  * debian/kbxutil.1, debian/rules: Add better description and regenerate
+    the manpage.
+  * debian/control: Remove version on gpg-idea conflict, add missing
+    Breaks for gpgsm and convert Conflicts to Breaks for gpgv2.
+  * debian/control: Move gnupg-agent to Depends for gpgsm instead of
+    Replaces (which in turn should have been Recommends).
+  * debian/control: Standards-Version to 3.9.5.
+  * debian/copyright: Switch to a shiny DEP-5 copyright file.
+
+ -- Eric Dorland <eric@debian.org>  Wed, 01 Jan 2014 22:56:56 -0500
+
+gnupg2 (2.0.22-2) unstable; urgency=low
+
+  * debian/control: Fix Build-Conflicts on newer automakes. Thanks Chris
+    Boot. (Closes: #726015)
+  * debian/control: IDEA is no longer patented, drop its metion from the
+    description. Thanks brian m. carlson. (Closes: #726139)
+  * debian/rules: Disable the test suite on mips and mipsel to work around
+    Bug:#730846.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 30 Nov 2013 23:47:56 -0500
+
+gnupg2 (2.0.22-1) unstable; urgency=low
+
+  * New upstream version. Fixes CVE-2013-4402 and CVE-2013-4351. (Closes:
+    #725433, #722724)
+  * debian/gnupg2.install: Install gnupg-card-architecture.png for the
+    info file.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 05 Oct 2013 17:45:28 -0400
+
+gnupg2 (2.0.21-2) unstable; urgency=low
+
+  * debian/rules, debian/gnupg2.install: Switch libexecdir to
+    /usr/lib/gnupg2 to install helper binaries to a non-multiarch specific
+    location. (Closes: #717303)
+  * debian/control, debian/gpgv2.install: Split out gpgv2 into its own
+    package.
+  * debian/control, debian/gnupg2.install, debian/kbxutil.1: Add rule and
+    manpage for kbxutil using help2man. (Closes: #323494)
+  * debian/patches/02-gpgv2-dont-link-libassuan.diff: Don't link gpgv2
+    against libassuan as it's not used.
+  * debian/rules: Install changelog for gpgv2.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 01 Sep 2013 00:42:16 -0400
+
+gnupg2 (2.0.21-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #613465, #720369)
+  * debian/patches/01-gnupg2-rename.diff: Refresh patch.
+  * debian/control: Fix Vcs-Git path.
+  * debian/control: Now depends on libgpg-error >= 1.11.
+  * debian/control: Build-Depends on automake1.11 since the test suite
+    fails on newer versions. (Closes: #713287)
+  * debian/control: Also need a Build-Conflicts on automake (<= 1.12).
+
+ -- Eric Dorland <eric@debian.org>  Sat, 24 Aug 2013 20:33:19 -0400
+
+gnupg2 (2.0.20-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #691237, #583893)
+  * debian/patches/02-cve-2012-6085.diff: Remove, merged upstream.
+  * debian/control: Upgrade Standards-Version to 3.9.4.
+  * debian/compat, debian/control: Upgrade to debhelper v9.
+  * debian/control, debian/rules: Drop hardening-wrapper, now that we use
+    debhelper v9.
+  * debian/scdaemon.install: scdaemon has moved under $libexecdir.
+  * debian/control: Tighten dependency on scdaemon.
+  * debian/rules: Turn on all hardening options.
+  * debian/patches/01-gnupg2-rename.diff: Refresh patch.
+  * debian/gnupg-agent.install, debian/gnupg2.install,
+    debian/scdaemon.install: Fix /usr/lib paths for multi-arch.
+  * debian/rules: Pass ${pkglibdir} to --libexecdir since dh v9 passes
+    ${libdir} by default.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 11 May 2013 18:28:57 -0400
+
+gnupg2 (2.0.19-2) unstable; urgency=high
+
+  * debian/patches/02-cve-2012-6085.diff: Patch from upstream to fix
+    CVE-2012-6085, "gnupg key import memory corruption". (Closes: #697251)
+  * debian/control: Use canonical addresses for VCS.
+  * debian/control: Fix scdaemon short description.
+
+ -- Eric Dorland <eric@debian.org>  Fri, 04 Jan 2013 00:56:52 -0500
+
+gnupg2 (2.0.19-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #666092)
+  * debian/control: Add Multi-Arch: foreign to all packages.
+  * debian/rules: Update ChangeLog locations.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 31 Mar 2012 01:06:02 -0400
+
+gnupg2 (2.0.18-2) unstable; urgency=low
+
+  * debian/control, debian/gpgsm.install, debian/scdaemon.install: Add a
+    separate package for the scdaemon. (Closes: #416129)
+  * debian/control, debian/gpgsm.install, debian/gnupg2.install,
+    gnupg-agent.install: Move gpg-preset-passphrase and gpg-protect-tool
+    into the gnupg-agent.
+  * debian/control: Upgrade Standards-Version to 3.9.2.
+  * debian/rules: Install ChangeLog for new scdaemon package.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 15 Oct 2011 20:21:35 -0400
+
+gnupg2 (2.0.18-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #635206)
+  * debian/copyright: Update ftp location. (Closes: #624404)
+  * debian/patches/01-gnupg2-rename.diff: Refresh patch.
+
+ -- Eric Dorland <eric@debian.org>  Tue, 30 Aug 2011 03:43:20 -0400
+
+gnupg2 (2.0.17-3) unstable; urgency=low
+
+  * debian/rules: Convert the rules file to use the lovely dh format.
+  * debian/gnupg2.dirs, debian/gnupg-agent.dirs, debian/gpgsm.dirs: Remove
+    unless dirs files.
+  * debian/gnupg-agent.lintian-overrides, debian/gnupg2.lintian-overrides,
+    debian/gpgsm.lintian-overrides: Remove unneeded lintian-overrides files.
+
+ -- Eric Dorland <eric@debian.org>  Mon, 14 Feb 2011 03:17:39 -0500
+
+gnupg2 (2.0.17-2) unstable; urgency=low
+
+  * debian/control: Add dependency on dpkg (>= 1.15.4) | install-info for
+    info install trigger.
+  * debian/control, debian/rules: Use debian build hardening.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 13 Feb 2011 16:33:17 -0500
+
+gnupg2 (2.0.17-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #584316, #603985, #603983, #603984)
+  * debian/patches/02-encode-s2k.diff,
+    debian/patches/03-gpgsm-realloc.diff, debian/patches/series: Drop now
+    unneeded security patches.
+  * debian/rules, debian/patches/01-gnupg2-rename.diff,
+    debian/gnupg2.info, debian/gnupg2.install: No need to rename the info
+    file anymore.
+  * debian/patches/01-gnupg2-rename.diff: Rename the autoconf package for
+    better renaming of pkg directories. (Closes: #579006)
+  * debian/control, debian/compat: Upgrade to debhelper level 8.
+  * debian/control:
+    - Upgrade Standards-Version to 3.9.1.
+    - Update Build-Depends versions for the latest release.
+  * debian/gnupg2.install: Add the applygnupgdefaults command. (Closes:
+    #567537)
+  * debian/gnupg2.docs: doc/faq.html no longer exists.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 13 Feb 2011 16:06:41 -0500
+
+gnupg2 (2.0.14-2) unstable; urgency=low
+
+  * debian/*.lintian, debian/*.lintian-overrides, debian/rules: Rename
+    lintian files and use dh_lintian instead of shell snippets.
+  * debian/source/patch-header, debian/source/options: Delete patch header
+    and remove single-debian-patch option.
+  * debian/patches/01-gnupg2-rename.diff: Move patch to do the necessary
+    renaming of gnupg -> gnupg2 in a quilt patch.
+  * debian/patches/02-encode-s2k.diff: Added patch to fix passphrase
+    problem in gpgsm. Thanks Martijn van Brummelen for the NMU to fix this
+    problem in 2.0.14-1.1.
+  * debian/patches/03-gpgsm-realloc.diff: Fix for "Realloc Bug with X.509
+    certificates" for gpgsm. (Closes: #590122)
+  * debian/rules, debian/control: Use dh-autoreconf and autopoint to
+    regenerate autotools files at build time.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 25 Jul 2010 02:16:42 -0400
+
+gnupg2 (2.0.14-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/control: Build depend on libreadline-dev instead of
+    libreadline5-dev, since libreadline6-dev is out. (Closes: #548922)
+  * debian/source/format, debian/source/options,
+    debian/source/patch-header: Convert to v3 quilt format, with
+    single-debian-patch.
+  * debian/control: Tighten dependency on gnupg-agent. (Closes: #551792)
+
+ -- Eric Dorland <eric@debian.org>  Sat, 09 Jan 2010 21:15:18 -0500
+
+gnupg2 (2.0.13-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/control: Depend instead of Recommend gnupg-agent. (Closes:
+    #538947)
+
+ -- Eric Dorland <eric@debian.org>  Mon, 07 Sep 2009 20:38:23 -0400
+
+gnupg2 (2.0.12-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #499569, #463270, #446494, #314068, 
+    #519375, #514587)
+  * debian/control: Change build dependency on gs to ghoscript, since
+    ghoscript has been replaced.
+  * debian/compat: Use debhelper v7.
+  * debian/control: Update Standards-Version to 3.8.2.
+  * debian/control: Use ${misc:Depends}.
+  * configure.ac: Override pkgdatadir so that it points to
+    /usr/share/gnupg2. (Closes: #528734)
+  * debian/rules: No longer need to specify pkgdatadir at make install
+    time.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 23 Aug 2009 20:48:11 -0400
+
+gnupg2 (2.0.11-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #496663)
+  * debian/control: Make the description a little more distinctive than
+    gnupg v1's. Thanks Jari Aalto. (Closes: #496323)
+
+ -- Eric Dorland <eric@debian.org>  Sun, 08 Mar 2009 22:46:47 -0400
+
+gnupg2 (2.0.9-3) unstable; urgency=medium
+
+  * Urgency medium to try to beat the release.
+  * tools/gpgkey2ssh.c: Patch from Daniel Kahn Gillmor to fix broken ssh
+    key generation. (Closes: #473841)
+
+ -- Eric Dorland <eric@debian.org>  Mon, 21 Jul 2008 03:48:11 -0400
+
+gnupg2 (2.0.9-2) unstable; urgency=low
+
+  * The "I've neglected you too long" release.
+  
+  * debian/control: 
+    - Add recommends on gnupg-agent for gpgsm and gnupg2, since they need 
+      it under most circumstances. (Closes: #459462, #477691)
+    - Depend on pinentry instead of recommend, and move pinentry-gtk2 to the 
+      front of the alternatives list. (Closes: #462951)
+  * keyserver/gpgkeys_curl.c, keyserver/gpgkeys_hkp.c: Fix FTBFS with gcc
+    4.3 strictness on bitfields combined with curl. (Closes: #476999)
+
+ -- Eric Dorland <eric@debian.org>  Mon, 28 Apr 2008 03:22:20 -0400
+
+gnupg2 (2.0.9-1) unstable; urgency=low
+
+  * New upstream release. Fixes CVE-2008-1530, Key import memory corruption. 
+    (Closes: #472928)
+  * debian/rules: Don't ignore status of make distclean, just check for
+    the existance of the Makefile.
+
+ -- Eric Dorland <eric@debian.org>  Sat, 29 Mar 2008 03:21:21 -0400
+
+gnupg2 (2.0.8-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #428635)
+  * debian/watch: Use passive ftp, ftp.gnupg.org doesn't seem happy
+    otherwise. (Closes: #456467)
+  * debian/control:
+    - Requires libassuan >= 1.0.4 now.
+    - Remove the XS- prefix from the Vcs-* headers.
+    - Add Homepage header.
+    - Upgrade Standards-Version to 3.7.3.0.
+    - Make gnupg2 optional rather than extra.
+    - Remove unnecessary conflict on suidmanager.
+  
+ -- Eric Dorland <eric@debian.org>  Sat, 22 Dec 2007 02:06:42 -0500
+
+gnupg2 (2.0.7-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/rules:
+    - Remove unnecessary deletion of the .gmo files. (Closes: #442583)
+    - Clean out some old comments
+  * gnupg-agent.xsession: Remove the quotes around --write-env-file
+    argument. Not ideal, but fine for now. Thanks Luis Rodrigo Gallardo
+    Cruz. (Closes: #443580)
+
+ -- Eric Dorland <eric@debian.org>  Sun, 30 Sep 2007 02:50:40 -0400
+
+gnupg2 (2.0.6-1) unstable; urgency=low
+
+  * New upstream release. (Closes: #437289)
+  * debian/gnupg-agent.xsession: Run the Xsession under the gpg-agent, so
+    it exits properly when the session dies. (Closes: #401843)
+  * debian/control: Add XS-Vcs headers for its new git home.
+
+ -- Eric Dorland <eric@debian.org>  Mon, 03 Sep 2007 23:29:11 -0400
+
+gnupg2 (2.0.5-2) unstable; urgency=low
+
+  * The "Ubuntu, I would have done it had you only asked" release.
+  
+  * debian/copyright: Fix download location. Thanks Ubuntu.
+  * debian/README.Debian: Remove, doesn't contain any relevant info.
+  * debian/rules:
+    - Build with --sysconfdir=/etc, thanks Bernhard Herzog. (Closes: #434790)
+    - Run dh_installexamples.
+    - Don't list the docs to install in here.
+  * debian/gnupg2.examples: New file, install gpgconf.conf as an example
+    into /usr/share/doc. Hope this is a good compromise Bernhard. (Closes:
+    #434878)
+  * debian/control:
+    - Remove opensc and pcsc-lite build dependencies, they're not used anymore.
+    - Add libcurl4-gnutls-dev build dep, to use the real curl.
+  * g10/call-agent.c: set DBG_ASSUAN to 0 to suppress a debug
+    message. Thanks Ubuntu.
+  * debian/gnupg2.docs, debian/gpgsm.docs: Move installed docs in here,
+    add some new docs. Thanks Ubuntu.
+  * debian/rules, debian/gnupg-agent.install: Build symcryptrun and install it
+    in the gnupg-agent package. Thanks Bernhard Herzog. (Closes: #434787)
+  * debian/rules, debian/control: Only recommend libldap, don't depend on
+    it.Thanks Riku. (Closes: #435138)
+
+ -- Eric Dorland <eric@debian.org>  Thu, 16 Aug 2007 22:24:16 -0400
+
+gnupg2 (2.0.5-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/watch: Add watch file.
+  * debian/control: 
+    - Require libassuan 1.0.2 or greater.
+    - Require libksba 1.0.2 or greater.
+    - Don't recommend plain gpg anymore.
+  * debian/copyright: Update copyright text for GPL v3 relicensing.
+  * docs/scdaemon.texi: Remove old --print-atr documentation. Thanks
+    Ludovic Rousseau. (Closes: #404128)
+
+ -- Eric Dorland <eric@debian.org>  Sun, 22 Jul 2007 16:03:32 -0400
+
+gnupg2 (2.0.4-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Eric Dorland <eric@debian.org>  Fri, 11 May 2007 00:41:01 -0400
+
+gnupg2 (2.0.3-1) unstable; urgency=high
+
+  * New upstream release.
+    - Fixes multoiple messages problem aka CVE-2007-1263.
+
+ -- Eric Dorland <eric@debian.org>  Fri,  9 Mar 2007 03:28:53 -0500
+
+gnupg2 (2.0.2-1) unstable; urgency=high
+
+  * New upstream release. (Closes: #409559)
+  * Thanks Andreas Barth for NMUs. (Closes: #400777, #401895, #401913)
+  * debian/gpgsm.install: pcsc-wrapper renamed to gnupg-pcsc-wrapper. 
+
+ -- Eric Dorland <eric@debian.org>  Mon, 19 Feb 2007 20:34:52 -0500
+
+gnupg2 (2.0.0-5) unstable; urgency=high
+
+  * debian/control: Remove unnecessary dependencies on makedev and
+    udev. Thanks Marco d'Itri.
+  * doc/gnupg.texi, debian/gnupg2.info, debian/rules: Set the output file
+    to gnupg2.info, and use that for the index. (Closes: #398493)
+
+ -- Eric Dorland <eric@debian.org>  Fri, 24 Nov 2006 02:23:35 -0500
+
+gnupg2 (2.0.0-4) unstable; urgency=medium
+
+  * debian/control: Update forgotten replaces for pcsc-wrapper move. 
+
+ -- Eric Dorland <eric@debian.org>  Mon, 20 Nov 2006 23:02:25 -0500
+
+gnupg2 (2.0.0-3) unstable; urgency=medium
+
+  * debian/control: Remove warning about development, thanks Gonzalo
+    HIGUERA DIAZ. (Closes: #399551)
+
+ -- Eric Dorland <eric@debian.org>  Mon, 20 Nov 2006 14:32:33 -0500
+
+gnupg2 (2.0.0-2) unstable; urgency=medium
+
+  * All packaging fixes, so urgency medium to beat the freeze.
+  * debian/distfiles, debian/lintian.override, debian/point-to-info.1:
+    Remove unused files.
+  * debian/gnupg2.info, debian/rules, gnupg2.files: Install all the info
+    files properly. (Closes: #398493)
+  * debian/rules: 
+    - Remove some unnecessary autotools build rules.
+    - Move some of make install targets more correctly to the
+      configure line.
+  * debian/*.files, debian/rules: Rename *.files to .install and use
+    dh_install nstead of dh_movefiles.
+  * debian/gnupg-agent.xsession: Account for spaces in the configuration
+    file, thanks Artem Zolochevskiy. (Closes: #352326)
+  * debian/control: 
+    - Adjust build-dependency versions slightly to match what the 
+      configure scipt requires.
+    - Update Standards-Version to 3.7.2.2.
+  * debian/gpgsm.install, debian/gnupg2.install: Install the pcsc-wrapper
+    in gpgsm. (Closes: #353232)
+  * debian/gpgsm.install, debian/rules: Install gpg-protect-tool into
+    /usr/libb/gnupg2.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 19 Nov 2006 18:03:39 -0500
+
+gnupg2 (2.0.0-1) unstable; urgency=medium
+
+  * New upstream release. (Closes: #398215)
+  * common/estream.c: #define PTH_SYSCALL_SOFT 0 as suggested by Daniel Hess.
+
+ -- Eric Dorland <eric@debian.org>  Sun, 12 Nov 2006 23:52:59 -0500
+
+gnupg2 (1.9.94-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Eric Dorland <eric@debian.org>  Thu,  2 Nov 2006 16:06:30 -0500
+
+gnupg2 (1.9.93-1) unstable; urgency=medium
+
+  * New upstream release. Urgency medium to try to beat the freeze. Thanks
+    to Andreas Metzler for getting this package into shape. 
+
+ -- Eric Dorland <eric@debian.org>  Wed, 25 Oct 2006 00:41:15 -0400
+
+gnupg2 (1.9.91-0.1) unstable; urgency=low
+
+  * New upstream version, built against clean upstream tarball.
+    (Closes: #378489,#388257)
+  * bump Build-Depends:
+    - libgpg-error-dev 0.6 -> 1.4
+    - libassuan-dev 0.6.10 -> 0.9.1
+    - libksba-dev 0.9.13 -> 1.0.0 (closes: #368552)
+  * Add libreadline5-dev to Build-Depends.
+  * Pass proper --build and --host args to ./configure.
+  * configure with --mandir='$${prefix}/share/man'.
+  * Add $(LIBINTL) to gpgsplit_LDADD in tools/Makefile.am.
+  * New upstream includes a lot more manpages, ship them.
+    (Closes: #300129,#300677)
+    gpg-agent(1) documents ~/gpg-agent.conf.  (Closes: #300676)
+  * Update debian/copyright.
+  * Drop gnupg2.postinst gnupg2.postrm postinst postrm. They all only consited
+    of calls to suidregister for /usr/bin/gpg" or "chmod 4755 /usr/bin/gpg".
+    suidregister has been obsolete for a long time and /usr/bin/gpg is not
+    part of these packages. - If /usr/bin/gpg(v)2 was supposed to be installed
+    suid it should be shipped with these permissions in the deb instead
+    using chmod in postinst anyway.
+  * Drop preinst (ending up as gnupg-agent's preinst), which only showed
+    a warning on upgrades from <<0.3.2-1. - There never was a gnupg-agent
+    0.3.2-1.
+  * Add (noop) binary-indep target as required by policy 4.9.
+
+ -- Andreas Metzler <ametzler@debian.org>  Sun,  8 Oct 2006 07:51:44 +0000
+
+gnupg2 (1.9.20-2) unstable; urgency=high
+
+  * debian/control: Make myself the maintainer with Matthias' permission.
+  * Acknowledge NMU. (Closes: #375053, #376755)
+  * g10/parse-packet.c: Patch from Martin Schulze to backport security fix
+    for CVE-2006-3746, crash when receiving overly long comments.
+
+ -- Eric Dorland <eric@debian.org>  Fri,  4 Aug 2006 18:11:43 -0400
+
+gnupg2 (1.9.20-1.1) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * Adapt patch from upstream CVS, fixing buffer overflow leading to remote
+    DoS/crash (CVE-2006-3082). (Closes: #375053)
+
+ -- Steinar H. Gunderson <sesse@debian.org>  Tue,  4 Jul 2006 20:37:43 +0200
+
+gnupg2 (1.9.20-1) unstable; urgency=low
+
+  * New Upstream version. Closes:#306890,#344530
+    * Closes:#320490: gpg-protect-tool fails to decrypt PKCS-12 files 
+  * Depend on libopensc2-dev, not -1-. Closes:#348106
+
+ -- Matthias Urlichs <smurf@debian.org>  Tue, 24 Jan 2006 04:31:42 +0100
+
+gnupg2 (1.9.19-2) unstable; urgency=low
+
+  * Convert debian/changelog to UTF-8.
+  * Put gnupg-agent and gpgsm lintian overrides in the respectively
+    right package.  Closes: #335066
+  * Added debhelper tokens to maintainer scripts.
+  * xsession fixes:
+    o Added host name to gpg-agent PID file name.  Closes: #312717
+    o Fixed xsession script to be able to run under zsh.  Closes: #308516
+    o Don't run gpg-agent if one is already running.  Closes: #336480
+  * debian/control:
+    o Fixed package description of gpgsm package.  Closes: #299842
+    o Added mention of gpg-agent to description of gnupg-agent package.
+      Closes: #304355
+  * Thanks to Peter Eisentraut <petere@debian.org> for all of the above.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu,  8 Dec 2005 22:13:21 +0100
+
+gnupg2 (1.9.19-1) unstable; urgency=low
+
+  * Merged with 1.9.19.
+  * Re-enable gpgv2 package.
+
+ -- Matthias Urlichs <smurf@debian.org>  Sat, 22 Oct 2005 14:33:33 +0200
+
+gnupg2 (1.9.17-1) unstable; urgency=low
+
+  * Merged with Upstream 1.9.17.
+
+ -- Matthias Urlichs <smurf@debian.org>  Mon,  4 Jul 2005 01:56:43 +0200
+
+gnupg2 (1.9.15-6) unstable; urgency=high
+
+  * Move gpg-protect-tool to the gpgsm package.
+    Closes: #303492.
+    High urgency because this renders gpgsm unuseable for some people.
+  * gpg-agent: Override max-cache-ttl if a higher default is set.
+    Closes: #302692.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu,  7 Apr 2005 10:13:19 +0200
+
+gnupg2 (1.9.15-5) unstable; urgency=low
+
+  * Add /etc/X11/Xsession.d/90gpg-agent script.  Closes: #300128.
+  * Emphasize that gnupg2 is NOT useful at the moment.
+  * Conflict+replace gpg-agent with newpg.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu, 10 Mar 2005 22:46:10 +0100
+
+gnupg2 (1.9.15-4) unstable; urgency=low
+
+  * Incorporated Ubuntu changes from Andreas Mueller.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu, 10 Mar 2005 21:41:59 +0100
+
+gnupg2 (1.9.15-3ubuntu3) hoary; urgency=low
+
+  * removed info file
+
+ -- Andreas Mueller <amu@ubuntu.com>  Tue,  8 Mar 2005 01:58:39 +0100
+
+gnupg2 (1.9.15-3ubuntu2) hoary; urgency=low
+
+  * changed rules file, part cp gnupg.info to mv
+    and added dh_installinfo. 
+  * changed Standards Version to 3.6.1
+
+ -- Andreas Mueller <amu@ubuntu.com>  Tue,  8 Mar 2005 00:53:31 +0100
+
+gnupg2 (1.9.15-3ubuntu1) hoary; urgency=low
+
+  * added missing build depends texinfo
+
+ -- Andreas Mueller <amu@ubuntu.com>  Mon,  7 Mar 2005 22:47:56 +0100
+
+gnupg2 (1.9.15-2) hoary; urgency=low
+
+  * Initial checkin
+
+ -- Andreas Mueller <amu@ubuntu.com>  Mon,  7 Mar 2005 21:13:32 +0100
+
+gnupg2 (1.9.15-1) experimental; urgency=low
+
+  * New Upstream release.
+  * Removed -doc package:
+    - The package itself is too smal to merit being packaged separately.
+    - Interim solution: Documentation is included in the gnupg2 package.
+    - Goal: ask Upstream to split the .info file.
+  * Removed suidness.
+  * Update debian/copyright.
+  * Require libassuan >= 0.6.9.
+
+ -- Matthias Urlichs <smurf@debian.org>  Tue, 25 Jan 2005 08:19:15 +0100
+
+gnupg2 (1.9.11+cvs20040924-5) experimental; urgency=low
+
+  * Rebuild to depend on opensc1.
+  * Split -doc into its own package.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu, 16 Dec 2004 10:30:44 +0100
+
+gnupg2 (1.9.11+cvs20040924-4) experimental; urgency=low
+
+  * Turn on setuid-ness.
+    - Added Lintian overrides.
+  * Install all "standard" message files.
+    - Makefile.in: The package name for gettext is in the macro PACKAGE_GT,
+      not PACKAGE.
+  * Fix shebang line of addgnupghome script.
+  * Install info file in the correct place.
+  * Build cleanups.
+
+ -- Matthias Urlichs <smurf@debian.org>  Tue,  5 Oct 2004 10:59:56 +0200
+
+gnupg2 (1.9.11+cvs20040924-3) experimental; urgency=low
+
+  * rename gnupg-agent's changelog file
+  * Fix gnupg-agent's dependencies
+
+ -- Matthias Urlichs <smurf@debian.org>  Sun,  3 Oct 2004 20:14:30 +0200
+
+gnupg2 (1.9.11+cvs20040924-2) experimental; urgency=low
+
+  * Shipped a /usr/share/locale.alias file. Ouch.
+  * Split off gpgsm.
+
+ -- Matthias Urlichs <smurf@debian.org>  Wed, 29 Sep 2004 10:25:51 +0200
+
+gnupg2 (1.9.11+cvs20040924-1) experimental; urgency=low
+
+  * New Upstream.
+
+ -- Matthias Urlichs <smurf@debian.org>  Sat, 25 Sep 2004 11:05:44 +0200
+
+gnupg2 (1.9.10+cvs-1) experimental; urgency=low
+
+  * Packaged latest Upstream version.
+  * Split gpg-agent into its own .deb.
+  * Bit the bullet and started using debhelper.
+
+ -- Matthias Urlichs <smurf@debian.org>  Thu, 19 Aug 2004 11:43:34 +0200
+
+gnupg2 (1.9.9-1) experimental; urgency=low
+
+  * Packaged latest Upstream version.
+
+ -- Matthias Urlichs <smurf@debian.org>  Mon, 14 Jun 2004 17:18:18 +0200
+
+gnupg2 (1.9.5-1) experimental; urgency=low
+
+  * Packaged Upstream development version.
+    Closes:#187548
+
+ -- Matthias Urlichs <smurf@debian.org>  Mon,  8 Mar 2004 05:30:35 +0100
+
+gnupg (1.2.4-4) unstable; urgency=low
+
+  * 12_zero_length_header.dpatch: update patch from David Shaw
+    <dshaw@jabberwocky.com> to fix the fix of crashing on certain
+    keys. Closes: #234289
+
+ -- James Troup <james@nocrew.org>  Mon, 23 Feb 2004 18:02:20 +0000
+
+gnupg (1.2.4-3) unstable; urgency=low
+
+  * Move to dpatch; existing non-debian/ change split into
+    10_hppa_unaligned_constant.dpatch.
+
+  * debian/rules: include /usr/share/dpatch/dpatch.make.
+  * debian/rules (build): depend on patch-stamp.
+  * debian/rules (clean): depend on unpatch.  Remove debian/patched.
+  * debian/control (Build-Depends): add dpatch.
+
+  * debian/rules: update version number and use install_foo convenience
+    variables.
+  * debian/rules (clean): remove emacs backup files from any directory.
+  
+  * 11_fi_po_update.dpatch: new patch from Tommi Vainikainen
+    <thv+debian@iki.fi> to update Finnish translation as the current one
+    renders gnupg unusable.  Closes: #232030, #222951, #192582
+  * debian/rules (clean): remove po/fi.gmo to avoid dpkg-source errors
+    over unrepresentable changes to source.
+
+  * 12_zero_length_header.dpatch: new patch from David Shaw
+    <dshaw@jabberwocky.com> to fix cases where importing certain keys
+    makes the keyring unuseable.  Closes: #232714
+
+  * 13_revoked_keys.dpatch: new patch from David Shaw
+    <dshaw@jabberwocky.com> to list revoked keys as revoked.  Closes: #231814
+
+  * 14_getkey_not_found_fix.dpatch: new patch from David Shaw
+    <dshaw@jabberwocky.com> to fix --list-sigs incorrectly claiming "User
+    id not found".  Closes: #229549
+
+ -- James Troup <james@nocrew.org>  Fri, 20 Feb 2004 16:38:12 +0000
+  
+gnupg (1.2.4-2) unstable; urgency=low
+
+  * mpi/hppa1.1/udiv-qrnnd.S: patch from LaMont Jones <lamont@debian.org>
+    to fix unaligned constant.  Closes: #228456
+  * debian/copyright: update year and version number.
+
+ -- James Troup <james@nocrew.org>  Tue, 20 Jan 2004 17:19:58 +0000
+
+gnupg (1.2.4-1) unstable; urgency=medium
+
+  * New upstream release.
+   * Most support for ElGamal Sign+Encrypt keys has been removed. Closes: #222293
+   * No longer miss-identifies GNU/KFreeBSD as GNU/Hurd. Closes: #216957
+   * Fixes build error on GNU/KFreeBSD (and Glibc-based GNU/KNetBSD). Closes: #221079
+   * Fixes segmentation fault in prime generator. Closes: #213989
+   * Fixes trustdb not updating without ultimately trusted keys. Closes: #222368
+
+  * debian/control (Build-Depends): add libbz2-dev.
+
+ -- James Troup <james@nocrew.org>  Wed, 31 Dec 2003 17:57:52 +0000
+
+gnupg (1.2.3-1) unstable; urgency=low
+
+  * New upstream release (Closes: #207340).
+   * gpg no longer kills keyrings by importing broken keys.  Closes: #196505
+   * options.skel uses subkeys.pgp.net instead of pgp.mit.edu. Closes: #206092
+   * --import now closes files when it's done. Closes: #196643
+   * A key listing speed regression has been fixed. Closes: #192083
+  * debian/copyright: update URL and date.
+  * debian/rules: update dates and version.
+
+  * debian/control (Standards-Version): bump to 3.6.0.
+
+  * debian/Upgrading_From_PGP.txt: new file from to Richard Braakman
+    <dark@xs4all.nl>.  Closes: #173233
+  * debian/rules (binary-arch): install it.
+
+  * debian/rules (build): correct libexecdir passed to configure; patch
+    from Matthias Cramer <cramer@freestone.net>.  Fixes invocation of
+    gpgkeys_ldap.  Closes: #168486
+
+ -- James Troup <james@nocrew.org>  Thu, 28 Aug 2003 14:08:50 +0100
+
+gnupg (1.2.2-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/control (Standards-Version): bump to 3.5.9.0.
+  * debian/rules (binary-arch): install convert-from-106 as
+    gpg-convert-from-106 and fix the path to gpg.
+  * debian/control: remove trailing full stop from short description.
+  * debian/control: remove out-dated and contradictory information about
+    RSA.
+
+ -- James Troup <james@nocrew.org>  Mon,  5 May 2003 03:08:58 +0100
+
+gnupg (1.2.1-2) unstable; urgency=low
+
+  * Update config.guess (to 2002-10-21) and config.sub (to 2002-09-05).
+    Thanks to Ryan Murray.  Closes: #166696
+
+ -- James Troup <james@nocrew.org>  Mon, 28 Oct 2002 01:47:26 +0000
+
+gnupg (1.2.1-1) unstable; urgency=low
+
+  * New upstream version.
+   * An inifinte loop in --update-trustdb has been fixed.  Closes: #162039
+   * The polish translation is now correctly specified as UTF-8.  Closes: #162885
+   * --refresh-keys is now documented in the manpage.  Closes: #165566
+  * debian/control (Conflicts): add gpg-idea <= 2.2 since gnupg >= 1.2 is
+    incompatible with that version of gpg-idea.  Closes: #162314
+
+ -- James Troup <james@nocrew.org>  Fri, 25 Oct 2002 18:18:43 +0100
+
+gnupg (1.2.0-1) unstable; urgency=low
+
+  * New upstream version.  Closes: #161817.
+   * --options no longer mis-handles a directory as an argument.  Closes: #151973
+   * gpg now prompts before sending all keys to the keyserver.  Closes: #64607
+   * There is now a gnupg(7) manpage.  Closes: #157750
+   * The permission checking has been sanitized and handles non-home-dir
+     keyrings better.  Closes: #147760
+   * notation data longer than 5 characters is now handled.  Closes: #156871
+   * an abort when setting trust levels in a czech locale has been fixed.
+     Closes: #149212
+  * debian/rules (binary-arch): there are no more modules, adjust
+    accordingly.
+  * debian/postinst, debian/prerm: remove; no longer do /usr/doc symlinks.
+  * debian/rules (binary-arch): don't install obsolete postinst or prerm.
+  * debian/rules (binary-arch): gzip gnupg.7 too.
+  * debian/rules (build): pass --libexecdir=/usr/lib/gnupg to configure.
+  * debian/rules (binary-arch): likewise, pass suitable libexcedir
+    argument to make install.
+  * debian/control (Standards-Version): update to 3.5.7.0.
+  * debian/copyright: update URL and date.
+  * debian/rules: update dates and version.
+
+ -- James Troup <james@nocrew.org>  Sun, 22 Sep 2002 22:26:25 +0100
+
+gnupg (1.0.7-2) unstable; urgency=low
+
+  * debian/control (Suggests): add xloadimage since that's what gpg uses
+    by default to view photo IDs.  Thanks to Julien Danjou
+    <acid@debian.org> for the suggestion.  Closes: #156245
+  * debian/control (Depends): add "hurd" to the alternatives to
+    makedev. Thanks to Michal Suchanek <hramrach_l@centrum.cz> for
+    noticing.  Closes: #158492
+  * po/it.po: patch to fix typos from Marco Bodrato
+    <bodrato@gulp.linux.it.  Closes: #149462
+  * g10/g10.c (main): remove the bogus undef of USE_SHM_COPROCESSING to
+    match upstream and fix gabber and libgnupg-perl.  Closes: #147679, #151969
+
+ -- James Troup <james@nocrew.org>  Thu, 29 Aug 2002 01:42:58 +0100
+
+gnupg (1.0.7-1) unstable; urgency=low
+
+  * New upstream version.  Closes: #145477.
+    * GDBM support has been removed.  Closes: #33009.
+    * Now adds the default keyring when a keyring is specified.
+      Closes: #50616, #65260.
+    * Now does the Right Thing when receiving a key from the keyserver and
+      the key in question is in both a read-only and writable keyring.
+      Closes: #63297.
+    * Automatic key retrieval is now configurable.  Closes: #64940.
+    * --no-options supresses ~/.gnupg creation again.  Closes: #95486.
+    * duplicate trust entries are no longer treated as an error. Closes: #96480.
+    * There's now no comment line in ascii armours. Closes: #100088.
+    * Handle secret keyring given as keyring better.  Closes: #100581, #106670.
+    * It's now documented that --with-colons unconditionally uses UTF8.
+      Closes: #101446, 101454.
+    * s/now/knows/ typo in manpage fixed.  Closes: #107471.
+    * There's now support for a primary UID.  Closes: #106567, #108155.
+    * Handles errors in uncompression layer beter. Closes: #112392.
+    * Key selection has been entirely revamped.  Closes: #136170.
+    * Handles empty encrypt-to. Closes: #138378
+
+  * debian/rules (binary-arch): remove empty /usr/info directory, thanks
+    to Joey Hess <joeyh@debian.org>.  Closes: #121864.
+  * debian/control: remove duplicated word from long description, thanks
+    to Nicolas Boulenguez <nicolas.boulenguez@free.fr>.  Closes: #144786.
+  * README: correct URL to GPH and other docs, thanks to Mark Brown
+    <broonie@sirena.org.uk>.  Closes: #100277.
+  * debian/control (Standards-Version): updated to 3.5.6.1.
+  * debian/rules (binary-arch): only strip ELF binaries.  es_ES -> es hack
+    no longer needed as fixed upstream.
+  * debian/control (Build-Depends): remove libgdbmg1-dev; no longer used.
+  * debian/README.Debian: remove note about gdbm support which was finally
+    removed.  Update note on old versions of gnupg to reflect the
+    pre-historic nature of those versions.
+  * debian/control (Build-Depends): add libldap2-dev.
+  * debian/rules (binary-arch): call dpkg-shlibdeps for all ELF binaries.
+  * debian/control (Build-Depends): add file.
+  * debian/control (Priority): increase to standard to match overrides.
+
+ -- James Troup <james@nocrew.org>  Sat, 11 May 2002 15:08:02 +0100
+
+gnupg (1.0.6-3) unstable; urgency=low
+
+  * moved into main.
+
+ -- James Troup <james@nocrew.org>  Tue, 19 Mar 2002 16:17:09 +0000
+
+gnupg (1.0.6-2) unstable; urgency=high
+
+  * debian/rules (binary-arch): remove the erroneous
+    /usr/share/locale/locale.alias that 'make install' adds; closes:
+    #99293.
+
+ -- James Troup <james@nocrew.org>  Wed, 30 May 2001 20:40:59 +0100
+
+gnupg (1.0.6-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Tue, 29 May 2001 20:59:49 +0100
+
+gnupg (1.0.5-4) unstable; urgency=low
+
+  * Patch from Werner.
+
+ -- James Troup <james@nocrew.org>  Sun, 27 May 2001 09:34:50 +0100
+
+gnupg (1.0.5-3) unstable; urgency=low
+
+  * Apply patch from Matthew Wilcox <matthew@wil.cx> to fix assembly on
+    hppa.
+
+ -- James Troup <james@nocrew.org>  Sun, 13 May 2001 02:36:45 +0100
+
+gnupg (1.0.5-2) unstable; urgency=medium
+
+  * util/http.c: patch from Werner that fixes --send-key, closes: #96277.
+  * debian/control (Depends): accept devfsd in place of makedev, closes:
+    #96307.
+
+ -- James Troup <james@nocrew.org>  Mon,  7 May 2001 00:13:51 +0100
+
+gnupg (1.0.5-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/README.Debian: fix spelling and update URL.
+  * debian/rules (binary): remove the new info files.
+  * scripts/config.{guess,sub}: sync with subversions, closes: #95729.
+
+ -- James Troup <james@nocrew.org>  Mon, 30 Apr 2001 02:12:38 +0100
+
+gnupg (1.0.4-4) unstable; urgency=low
+
+  * po/ru.po: patch by Ilya Martynov <m_ilya@agava.com> to replace German
+    entries and add missing translations, closes: #93987.
+  * g10/revoke.c (ask_revocation_reason): typo fix (s/non longer/no
+    longer/g); noticed by Colin Watson <cjw44@flatline.org.uk>, closes:
+    #93664.
+
+  * Deprecated depreciated; noticed by Vincent Broman
+    <broman@spawar.navy.mil>.
+
+  * Following two patches are from Vincent Broman.
+  * g10/mainproc.c (proc_tree): use iobuf_get_real_fname() in preference
+    to iobuf_get_fname().
+  * g10/openfile.c (open_sigfile): handle .sign prefixed files correctly.
+
+ -- James Troup <james@nocrew.org>  Fri, 20 Apr 2001 23:32:44 +0100
+
+gnupg (1.0.4-3) unstable; urgency=medium
+
+  * debian/rules (binary): make gpg binary suid, closes: #86433.
+  * debian/postinst: don't use suidregister.
+  * debian/postrm: removed (only called suidunregister).
+  * debian/control: conflict with suidmanager << 0.50.
+  * mpi/longlong.h: apply fix for ARM long long artimetic from Philip
+    Blundell <philb@gnu.org>, closes: #87487.
+  * debian/preinst: the old GnuPG debs have moved to people.debian.org.
+  * cipher/random.c: #include <time.h> as well as <sys/time.h>
+  * g10/misc.c: likewise.
+  * debian/rules: define a strip alias which removes the .comment and
+    .note sections.
+  * debian/rules (binary-arch): use it.
+  * debian/lintian.override: new file; override the SUID warning from
+    lintian.
+  * debian/rules (binary-arch): install it.
+
+ -- James Troup <james@nocrew.org>  Sun, 25 Feb 2001 05:24:58 +0000
+
+gnupg (1.0.4-2) stable unstable; urgency=high
+
+  * Apply security fix patch from Werner.
+  * Apply another patch from Werner to fix bogus warning on Rijndael
+    usage.
+  * Change section to 'non-US'.
+
+ -- James Troup <james@nocrew.org>  Mon, 12 Feb 2001 07:47:02 +0000
+
+gnupg (1.0.4-1) stable unstable; urgency=high
+
+  * New upstream version.
+  * Fixes a serious bug which could lead to false signature verification
+    results when more than one signature is fed to gpg.
+
+ -- James Troup <james@nocrew.org>  Tue, 17 Oct 2000 17:26:17 +0100
+
+gnupg (1.0.3b-1) unstable; urgency=low
+
+  * New upstream snapshot version.
+
+ -- James Troup <james@nocrew.org>  Fri, 13 Oct 2000 18:08:14 +0100
+
+gnupg (1.0.3-2) unstable; urgency=low
+
+  * debian/control: Conflict, Replace and Provide gpg-rsa & gpg-rsaref.
+    Fix long description to reflect the fact that RSA is no longer
+    patented and now included. [#72177]
+  * debian/rules: move faq.html to /usr/share/doc/gnupg/ and remove FAQ
+    from /usr/share/gnupg/.  Thanks to Robert Luberda
+    <robert@pingu.ii.uj.edu.pl> for noticing. [#72151]
+  * debian/control: Suggest new package gnupg-doc. [#64323, #65560]
+  * utils/secmem.c (lock_pool): don't bomb out if mlock() returns ENOMEM,
+    as Linux will do this if resource limits (or other reasons) prevent
+    memory from being locked, instead treat it like permission was denied
+    and warn but continue.  Thanks to Topi Miettinen
+    <Topi.Miettinen@nic.fi>. [#70446]
+  * g10/hkp.c (not_implemented): s/ist/is/ in error message.
+  * debian/README.Debian: add a note about GDBM support and why it is
+    disabled.  Upstream already fixed the manpage.  [#65913]
+  * debian/rules (binary-arch): fix the Spanish translation to be 'es' not
+    'es_ES' at Nicolás Lichtmaier <nick@debian.org>'s request. [#57314]
+
+ -- James Troup <james@nocrew.org>  Sun,  1 Oct 2000 14:55:03 +0100
+
+gnupg (1.0.3-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Mon, 18 Sep 2000 15:56:54 +0100
+
+gnupg (1.0.2-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Thu, 13 Jul 2000 20:26:50 +0100
+
+gnupg (1.0.1-2) unstable; urgency=low
+
+  * debian/control (Build-Depends): added.
+  * debian/copyright: corrected location of copyright file.  Removed
+    references to Linux.  Removed warnings about beta nature of GnuPG.
+  * debian/rules (binary-arch): install documentation into
+    /usr/share/doc/gnupg/ and pass mandir to make install to ensure the
+    manpages go to /usr/share/man/.
+  * debian/postinst: create /usr/doc/gnupg symlink.
+  * debian/prerm: new file; remove /usr/doc/gnupg symlink.
+  * debian/rules (binary-arch): install prerm.
+  * debian/control (Standards-Version): updated to 3.1.1.1.
+
+ -- James Troup <james@nocrew.org>  Thu, 30 Dec 1999 16:16:49 +0000
+
+gnupg (1.0.1-1) unstable; urgency=low
+
+  * New upstream version.
+  * doc/gpg.1: updated to something usable from
+    ftp://ftp.gnupg.org/pub/gcrypt/gnupg/gpg.1.gz.
+
+ -- James Troup <james@nocrew.org>  Sun, 19 Dec 1999 23:47:10 +0000
+
+gnupg (1.0.0-3) unstable; urgency=low
+
+  * debian/rules (build): remove the stunningly ill-advised --host option
+    to configure.  [#44698, #48212, #48281]
+
+ -- James Troup <james@nocrew.org>  Tue, 26 Oct 1999 01:12:59 +0100
+
+gnupg (1.0.0-2) unstable; urgency=low
+
+  * debian/rules (binary-arch): fix the permissions on the
+    modules. [#47280]
+  * debian/postinst, debian/postrm: fix the package name passed to
+    suidregister. [#45013]
+  * debian/control: update long description. [#44636]
+  * debian/rules (build): pass the host explicitly to configure to avoid
+    problems on sparc64. [(Should fix) #44698].
+
+ -- James Troup <james@nocrew.org>  Wed, 20 Oct 1999 23:39:05 +0100
+
+gnupg (1.0.0-1) unstable; urgency=low
+
+  * New upstream release. [#44545]
+
+ -- James Troup <james@nocrew.org>  Wed,  8 Sep 1999 00:53:02 +0100
+
+gnupg (0.9.10-2) unstable; urgency=low
+
+  * debian/rules (binary-arch): install lspgpot.  Requested by Kai
+    Henningsen <kai@khms.westfalen.de>. [#42288]
+  * debian/rules (binary-arch): correct the path where modules are looked
+    for.  Reported by Karl M. Hegbloom <karlheg@odin.cc.pdx.edu>. [#40881]
+  * debian/postinst, debian/postrm: under protest, register gpg the
+    package with suidmanager and make it suid by default.
+    [#29780,#32590,#40391]
+
+ -- James Troup <james@nocrew.org>  Tue, 10 Aug 1999 00:12:40 +0100
+
+gnupg (0.9.10-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Fri,  6 Aug 1999 01:16:21 +0100
+
+gnupg (0.9.9-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Sun, 25 Jul 1999 01:06:31 +0100
+
+gnupg (0.9.8-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/rules (binary-arch): don't create a gpgm manpage as the binary
+    no longer exists.  Noticed by Wichert Akkerman
+    <wichert@cs.leidenuniv.nl>. [#38864]
+
+ -- James Troup <james@nocrew.org>  Sun, 27 Jun 1999 01:07:58 +0100
+
+gnupg (0.9.7-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Tue, 25 May 1999 13:23:24 +0100
+
+gnupg (0.9.6-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/copyright: update version number, noticed by Lazarus Long
+    <lazarus@frontiernet.net>.
+  * debian/control (Depends): depend on makedev (>= 2.3.1-13) to ensure
+    that /dev/urandom exists; reported by Steffen Markert
+    <smort@rz.tu-ilmenau.de>. [#32076]
+
+ -- James Troup <james@nocrew.org>  Tue, 11 May 1999 21:06:27 +0100
+
+gnupg (0.9.5-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control (Description): no tabs.  [Lintian]
+
+ -- James Troup <james@nocrew.org>  Wed, 24 Mar 1999 22:37:40 +0000
+
+gnupg (0.9.4-1) unstable; urgency=low
+
+  * New version.
+  * debian/control: s/GNUPG/GnuPG/
+
+ -- Werner Koch <wk@isil.d.suttle.de>  Mon, 8 Mar 1999 19:58:28 +0100
+
+gnupg (0.9.3-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Mon, 22 Feb 1999 22:55:04 +0000
+
+gnupg (0.9.2-1) unstable; urgency=low
+
+  * New version.
+  * debian/rules (build): Removed CFLAGS as the default is now sufficient.
+  * debian/rules (clean): remove special handling cleanup in intl.
+
+ -- Werner Koch <wk@isil.d.suttle.de>  Wed, 20 Jan 1999 21:23:11 +0100
+
+gnupg (0.9.1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Sat,  9 Jan 1999 22:29:11 +0000
+
+gnupg (0.9.0-1) unstable; urgency=low
+
+  * New upstream version.
+  * g10/armor.c (armor_filter): add missing new line in comment string; as
+    noticed by Stainless Steel Rat <ratinox@peorth.gweep.net>.
+
+ -- James Troup <james@nocrew.org>  Tue, 29 Dec 1998 20:22:43 +0000
+
+gnupg (0.4.5-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/rules (clean): force removal of intl/libintl.h which the
+    Makefiles fail to remove properly.
+
+ -- James Troup <james@nocrew.org>  Tue,  8 Dec 1998 22:40:23 +0000
+
+gnupg (0.4.4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Sat, 21 Nov 1998 01:34:29 +0000
+
+gnupg (0.4.3-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/README.Debian: new file; contains same information as is in the
+    preinst.  Suggested by Wichert Akkerman <wichert@cs.leidenuniv.nl>.
+  * debian/rules (binary-arch): install `README.Debian'
+  * debian/control (Standards-Version): updated to 2.5.0.0.
+
+ -- James Troup <james@nocrew.org>  Sun,  8 Nov 1998 19:08:12 +0000
+
+gnupg (0.4.2-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/preinst: improve message about the NEWS file which isn't
+    actually installed when it's referred to, thanks to Martin Mitchell
+    <martin@debian.org>.
+  * debian/rules (binary-arch): don't install the now non-existent `rfcs',
+    but do install `OpenPGP'.
+
+ -- James Troup <james@nocrew.org>  Sun, 18 Oct 1998 22:48:34 +0100
+
+gnupg (0.4.1-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/rules (binary-arch): fix the gpgm manpage symlink now installed
+    by `make install'.
+
+ -- James Troup <james@nocrew.org>  Sun, 11 Oct 1998 17:01:21 +0100
+
+gnupg (0.4.0-1) unstable; urgency=high
+
+  * New upstream version. [#26717]
+  * debian/copyright: tone down warning about alpha nature of gnupg.
+  * debian/copyright: new maintainer address.
+  * debian/control: update extended description.
+  * debian/rules (binary-arch): install FAQ and all ChangeLogs.
+  * debian/preinst: new; check for upgrade from (<= 0.3.2-1) and warn about
+    incompatibilities in keyring format and offer to move old copy out of
+    gpg out of the way for transition strategy and inform the user about
+    the old copies of gnupg available on my web page.
+  * debian/rules (binary-arch) install preinst.
+  * debian/rules (binary-arch): don't depend on the test target as it is
+    now partially interactive (tries to generate a key, which requires
+    someone else to be using the computer).
+
+ -- James Troup <james@nocrew.org>  Thu,  8 Oct 1998 00:47:07 +0100
+
+gnupg (0.3.2-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control (Maintainer): new address.
+  * debian/copyright: updated list of changes.
+
+ -- James Troup <james@nocrew.org>  Thu,  9 Jul 1998 21:06:07 +0200
+
+gnupg (0.3.1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <james@nocrew.org>  Tue,  7 Jul 1998 00:26:21 +0200
+
+gnupg (0.3.0-2) unstable; urgency=low
+
+  * Applied bug-fix patch from Werner.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Fri, 26 Jun 1998 12:18:29 +0200
+
+gnupg (0.3.0-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control: rewrote short and long description.
+  * cipher/Makefile.am: link tiger with -lc.
+  * debian/rules (binary-arch): strip loadable modules.
+  * util/secmem.c (lock_pool): get rid of errant test code; fix from
+    Werner Koch <wk@isil.d.shuttle.de>.
+  * debian/rules (test): new target which runs gnupg's test suite.
+    binary-arch depends on it, to ensure it's run whenever the package is
+    built.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Thu, 25 Jun 1998 16:04:57 +0200
+
+gnupg (0.2.19-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control: Updated long description.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Sat, 30 May 1998 12:12:35 +0200
+
+gnupg (0.2.18-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <J.J.Troup@comp.brad.ac.uk>  Sat, 16 May 1998 11:52:47 +0200
+
+gnupg (0.2.17-1) unstable; urgency=high
+
+  * New upstream version.
+  * debian/control (Standards-Version): updated to 2.4.1.0.
+  * debian/control: tone down warning about alpha nature of gnupg, as per
+    README.
+  * debian/copyright: ditto.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Mon,  4 May 1998 22:36:51 +0200
+
+gnupg (0.2.15-1) unstable; urgency=high
+
+  * New upstream version.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Fri, 10 Apr 1998 01:12:20 +0100
+
+gnupg (0.2.13-1) unstable; urgency=high
+
+  * New upstream version.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Wed, 11 Mar 1998 01:52:51 +0000
+
+gnupg (0.2.12-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Sat,  7 Mar 1998 13:52:40 +0000
+
+gnupg (0.2.11-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Wed,  4 Mar 1998 01:32:12 +0000
+
+gnupg (0.2.10-1) unstable; urgency=low
+
+  * New upstream version.
+  * Name changed upstream.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Mon,  2 Mar 1998 07:32:05 +0000
+
+g10 (0.2.7-1) unstable; urgency=low
+
+  * Initial release.
+
+ -- James Troup <jjtroup@comp.brad.ac.uk>  Fri, 20 Feb 1998 02:05:34 +0000
diff --git a/clean b/clean
new file mode 100644 (file)
index 0000000..922f2c9
--- /dev/null
+++ b/clean
@@ -0,0 +1,8 @@
+po/*.gmo
+po/stamp-po
+build-gpgv-static/
+build-gpgv-udeb/
+build-gpgv-win32/
+doc/gnupg.info
+doc/gnupg.info-1
+doc/gnupg.info-2
diff --git a/compat b/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
+++ b/compat
@@ -0,0 +1 @@
+9
diff --git a/control b/control
new file mode 100644 (file)
index 0000000..d13718d
--- /dev/null
+++ b/control
@@ -0,0 +1,329 @@
+Source: gnupg2
+Section: utils
+Priority: optional
+Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
+Uploaders:
+ Eric Dorland <eric@debian.org>,
+ Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
+Standards-Version: 3.9.8
+Build-Depends:
+ automake,
+ autopoint,
+ debhelper (>= 9),
+ dh-autoreconf,
+ file,
+ gettext,
+ ghostscript,
+ imagemagick,
+ libassuan-dev (>= 2.4.3),
+ libbz2-dev,
+ libcurl4-gnutls-dev,
+ libgcrypt20-dev (>= 1.7.0),
+ libgnutls28-dev (>= 3.0),
+ libgpg-error-dev (>= 1.26-2~),
+ libksba-dev (>= 1.3.4),
+ libldap2-dev,
+ libnpth0-dev (>= 1.2),
+ libreadline-dev,
+ librsvg2-bin,
+ libsqlite3-dev,
+ libusb-1.0-0-dev [!hurd-any],
+ pkg-config,
+ texinfo,
+ transfig,
+ zlib1g-dev | libz-dev,
+Build-Depends-Indep:
+ binutils-multiarch [!amd64 !i386],
+ libassuan-mingw-w64-dev,
+ libgcrypt-mingw-w64-dev,
+ libgpg-error-mingw-w64-dev,
+ libksba-mingw-w64-dev,
+ libnpth-mingw-w64-dev,
+ libz-mingw-w64-dev,
+ mingw-w64,
+Vcs-Git: https://anonscm.debian.org/git/pkg-gnupg/gnupg2.git -b stretch
+Vcs-Browser: https://anonscm.debian.org/git/pkg-gnupg/gnupg2.git
+Homepage: https://www.gnupg.org/
+
+Package: gnupg-agent
+Architecture: any
+Multi-Arch: foreign
+Depends:
+ pinentry-curses | pinentry,
+ ${misc:Depends},
+ ${shlibs:Depends},
+Recommends:
+ gnupg (= ${binary:Version}) | gpgsm,
+Suggests:
+ dbus-user-session,
+ libpam-systemd,
+ pinentry-gnome3,
+ scdaemon,
+Provides:
+ gpg-agent,
+Description: GNU privacy guard - cryptographic agent
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC4880.
+ .
+ This package contains the agent program gpg-agent which handles all
+ secret key material for OpenPGP and S/MIME use.  The agent also
+ provides a passphrase cache, which is used by pre-2.1 versions of
+ GnuPG for OpenPGP operations.
+
+Package: scdaemon
+Architecture: any
+Multi-Arch: foreign
+Depends:
+ gnupg-agent (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Enhances:
+ gnupg-agent,
+Description: GNU privacy guard - smart card support
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC4880.
+ .
+ This package contains the smart card program scdaemon, which is used
+ by gnupg-agent to access OpenPGP smart cards.
+
+Package: gpgsm
+Architecture: any
+Multi-Arch: foreign
+Depends:
+ gnupg-agent (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Recommends:
+ dirmngr (= ${binary:Version}),
+Breaks:
+ gnupg2 (<< 2.1.10-2),
+Replaces:
+ gnupg2 (<< 2.1.10-2),
+Description: GNU privacy guard - S/MIME version
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC4880.
+ .
+ This package contains the gpgsm program. gpgsm is a tool to provide
+ digital encryption and signing services on X.509 certificates and the
+ CMS protocol. gpgsm includes complete certificate management.
+
+Package: gnupg
+Architecture: any
+Multi-Arch: foreign
+Depends:
+ gnupg-agent (= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Recommends:
+ dirmngr (= ${binary:Version}),
+ gnupg-l10n (= ${source:Version}),
+ ${shlibs:Recommends},
+Suggests:
+ parcimonie,
+ xloadimage,
+Breaks:
+ debsig-verify (<< 0.15),
+ dirmngr (<< ${binary:Version}),
+ gnupg2 (<< 2.1.11-7+exp1),
+ libgnupg-interface-perl (<< 0.52-3),
+ libgnupg-perl (<= 0.19-1),
+ libmail-gnupg-perl (<= 0.22-1),
+ monkeysphere (<< 0.38~),
+ php-crypt-gpg (<= 1.4.1-1),
+ python-apt (<= 1.1.0~beta4),
+ python-gnupg (<< 0.3.8-3),
+ python3-apt (<= 1.1.0~beta4),
+Replaces:
+ gnupg2 (<< 2.1.11-7+exp1),
+Provides:
+ gpg,
+Description: GNU privacy guard - a free PGP replacement
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC4880.
+ .
+ This package contains /usr/bin/gpg and some helper utilities like
+ gpgconf and kbxutil.
+
+Package: gnupg2
+Architecture: all
+Section: oldlibs
+Priority: extra
+Multi-Arch: foreign
+Depends:
+ gnupg (>= ${source:Version}),
+ ${misc:Depends},
+Description: GNU privacy guard - a free PGP replacement (dummy transitional package)
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC4880.
+ .
+ This is a dummy transitional package that provides symlinks from gpg2
+ to gpg.
+
+Package: gpgv
+Architecture: any
+Priority: important
+Multi-Arch: foreign
+Depends:
+ ${misc:Depends},
+ ${shlibs:Depends},
+Breaks:
+ gnupg2 (<< 2.0.21-2),
+ gpgv2 (<< 2.1.11-7+exp1),
+ python-debian (<< 0.1.29),
+Replaces:
+ gnupg2 (<< 2.0.21-2),
+ gpgv2 (<< 2.1.11-7+exp1),
+Suggests:
+ gnupg,
+Description: GNU privacy guard - signature verification tool
+ GnuPG is GNU's tool for secure communication and data storage.
+ .
+ gpgv is actually a stripped-down version of gpg which is only able
+ to check signatures. It is somewhat smaller than the fully-blown gpg
+ and uses a different (and simpler) way to check that the public keys
+ used to make the signature are valid. There are no configuration
+ files and only a few options are implemented.
+
+Package: gpgv2
+Section: oldlibs
+Priority: extra
+Architecture: all
+Multi-Arch: foreign
+Depends:
+ gpgv (>= ${source:Version}),
+ ${misc:Depends},
+Description: GNU privacy guard - signature verification tool (dummy transitional package)
+ GnuPG is GNU's tool for secure communication and data storage.  gpgv
+ is a stripped-down version of gpg which is only able to check
+ signatures.
+ .
+ This is a dummy transitional package that provides symlinks from gpgv2
+ to gpgv.
+
+Package: dirmngr
+Architecture: any
+Depends:
+ adduser,
+ lsb-base (>= 3.2-13),
+ ${misc:Depends},
+ ${shlibs:Depends},
+Recommends:
+ gnupg (= ${binary:Version}),
+ ${shlibs:Recommends},
+Enhances:
+ gnupg,
+ gpgsm,
+ squid,
+Breaks:
+ gnupg2 (<< 2.1.10-2),
+Replaces:
+ gnupg2 (<< 2.1.10-2),
+Suggests:
+ dbus-user-session,
+ libpam-systemd,
+ pinentry-gnome3,
+ tor,
+Description: GNU privacy guard - network certificate management service
+ dirmngr is a server for managing and downloading OpenPGP and X.509
+ certificates, as well as updates and status signals related to those
+ certificates.  For OpenPGP, this means pulling from the public
+ HKP/HKPS keyservers, or from LDAP servers.  For X.509 this includes
+ Certificate Revocation Lists (CRLs) and Online Certificate Status
+ Protocol updates (OCSP).  It is capable of using tor for network
+ access.
+ .
+ dirmngr is used for network access by gpg, gpgsm, and dirmngr-client,
+ among other tools.
+
+Package: gpgv-udeb
+Package-Type: udeb
+Section: debian-installer
+Priority: extra
+Architecture: any
+Depends:
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: minimal signature verification tool
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC 4880.
+ .
+ This is GnuPG's signature verification tool, gpgv, packaged in minimal
+ form for use in debian-installer.
+
+Package: gpgv-static
+Priority: extra
+Architecture: any
+Depends:
+ ${misc:Depends},
+ ${shlibs:Depends},
+Recommends:
+ debian-archive-keyring,
+ debootstrap,
+Description: minimal signature verification tool (static build)
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC 4880.
+ .
+ This is GnuPG's signature verification tool, gpgv, built statically
+ so that it can be directly used on any platform that is running on
+ the Linux kernel.  Android and ChromeOS are two well known examples,
+ but there are many other platforms that this will work for, like
+ embedded Linux OSes.  This gpgv in combination with debootstrap and
+ the Debian archive keyring allows the secure creation of chroot
+ installs on these platforms by using the full Debian signature
+ verification that is present in all official Debian mirrors.
+
+Package: gpgv-win32
+Architecture: all
+Priority: extra
+Multi-Arch: foreign
+Depends:
+ ${misc:Depends},
+Suggests:
+ wine,
+Description: GNU privacy guard - signature verification tool (win32 build)
+ GnuPG is GNU's tool for secure communication and data storage.
+ .
+ gpgv is a stripped-down version of gnupg which is only able to check
+ signatures.  It is smaller than the full-blown gnupg and uses a
+ different (and simpler) way to check that the public keys used to
+ make the signature are trustworthy.
+ .
+ This is a win32 version of gpgv.  It's meant to be used by the win32-loader
+ component of Debian-Installer.
+
+Package: gnupg-l10n
+Architecture: all
+Priority: extra
+Multi-Arch: foreign
+Depends:
+ ${misc:Depends},
+Enhances:
+ gnupg,
+Breaks:
+ gnupg (<< 2.1.14-2~),
+ gnupg2 (<< 2.1.14-2~),
+Replaces:
+ gnupg (<< 2.1.14-2~),
+ gnupg2 (<< 2.1.14-2~),
+Description: GNU privacy guard - localization files
+ GnuPG is GNU's tool for secure communication and data storage.
+ It can be used to encrypt data and to create digital signatures.
+ It includes an advanced key management facility and is compliant
+ with the proposed OpenPGP Internet standard as described in RFC 4880.
+ .
+ This package contains the translation files for the use of GnuPG in
+ non-English locales.
diff --git a/copyright b/copyright
new file mode 100644 (file)
index 0000000..5676d81
--- /dev/null
+++ b/copyright
@@ -0,0 +1,233 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: GnuPG - The GNU Privacy Guard (modern version)
+Upstream-Contact: GnuPG development mailing list <gnupg-devel@gnupg.org>
+Source: https://gnupg.org/download/
+
+Files: *
+Copyright: 1992, 1995-2016, Free Software Foundation, Inc
+License: GPL-3+
+
+Files: agent/command.c
+ agent/command-ssh.c
+ agent/gpg-agent.c
+ common/homedir.c
+ common/sysutils.c
+ g10/mainproc.c
+Copyright: 1998-2007, 2009, 2012, Free Software Foundation, Inc
+  2013, Werner Koch
+License: GPL-3+
+
+Files: autogen.sh
+Copyright: 2003, g10 Code GmbH
+License: permissive
+
+Files: common/gc-opt-flags.h
+ common/i18n.h
+ tools/clean-sat.c
+ tools/no-libgcrypt.c
+Copyright: 1998-2001, 2003, 2004, 2006, 2007 Free Software Foundation, Inc
+License: permissive
+
+Files: common/localename.c
+Copyright: 1985, 1989-1993, 1995-2003, 2007, 2008 Free Software Foundation, Inc.
+License: LGPL-2.1+
+
+Files: dirmngr/dns.c
+ dirmngr/dns.h
+Copyright: 2008-2010, 2012-2016 William Ahern
+License: Expat
+
+Files: doc/yat2m.c
+ scd/app-geldkarte.c
+Copyright: 2004, 2005, g10 Code GmbH
+  2006, 2008, 2009, 2011, Free Software Foundation, Inc
+License: GPL-3+
+
+Files: scd/ccid-driver.h
+ scd/ccid-driver.c
+Copyright: 2003-2007, Free Software Foundation, Inc
+License: GPL-3+ or BSD-3-clause
+
+Files: tools/rfc822parse.c
+ tools/rfc822parse.h
+Copyright: 1999-2000, Werner Koch, Duesseldorf
+  2003-2004, g10 Code GmbH
+License: LGPL-3+
+
+Files: tools/sockprox.c
+Copyright: 2007, g10 Code GmbH
+License: GPL-3+
+
+Files: doc/OpenPGP
+Copyright: 1998-2013 Free Software Foundation, Inc.
+           1997, 1998, 2013 Werner Koch
+           1998 The Internet Society
+License: RFC-Reference
+
+Files: tests/gpgscm/*
+Copyright: 2000, Dimitrios Souflis
+           2016, Justus Winter, Werner Koch
+License: TinySCHEME
+
+License: TinySCHEME
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ .
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ .
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ Neither the name of Dimitrios Souflis nor the names of the
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+License: permissive
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+ .
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+License: RFC-Reference
+ doc/OpenPGP merely cites and references IETF Draft
+ draft-ietf-openpgp-formats-07.txt. This is believed to be fair use;
+ but if not, it's covered by the source document's license under
+ the 'comment on' clause. The license statement follows.
+ .
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph
+ are included on all such copies and derivative works.  However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+ .
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+
+License: GPL-3+
+ GnuPG is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ GnuPG is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the full text of the GNU General Public
+ License version 3 can be found in the file
+ `/usr/share/common-licenses/GPL-3'.
+
+License: LGPL-3+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 3 of
+ the License, or (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the full text of the GNU Lesser General Public
+ License version 3 can be found in the file
+ `/usr/share/common-licenses/LGPL-3'.
+
+License: LGPL-2.1+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the full text of the GNU Lesser General Public
+ License version 2.1 can be found in the file
+ `/usr/share/common-licenses/LGPL-2.1'.
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, and the entire permission notice in its entirety,
+    including the disclaimer of warranties.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote
+    products derived from this software without specific prior
+    written permission.
+ .
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+ .
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dirmngr.NEWS b/dirmngr.NEWS
new file mode 100644 (file)
index 0000000..b0c550f
--- /dev/null
@@ -0,0 +1,49 @@
+dirmngr (2.1.18-1) unstable; urgency=medium
+
+  If your machine is configured with system user session management,
+  dirmngr will be managed automatically by systemd's user sessions on
+  machines configured with use systemd.  Please consider installing the
+  packages that the dirmngr package Suggests:, and see
+  /usr/share/doc/dirmngr/README.Debian for more details.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 23 Jan 2017 22:50:34 -0500
+
+dirmngr (2.1.13-3) experimental; urgency=medium
+
+  gpg and most related processes will auto-launch dirmngr if needed.
+
+  Any user who wants to launch dirmngr manually should do so with:
+
+     gpgconf --launch dirmngr
+
+  and may want to terminate dirmngr when their session ends with:
+
+     gpgconf --kill dirmngr
+
+  Users on machines with systemd can ensure that dirmngr is always
+  running for their session (and that it gets terminated at logout)
+  with:
+
+     gpgconf --kill dirmngr
+     systemctl --user enable dirmngr
+     systemctl --user start dirmngr
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 28 Jun 2016 17:55:15 -0400
+
+dirmngr (2.1.0~beta895-1) experimental; urgency=medium
+
+  No more dirmngr system service!
+  ===============================
+  
+  As of the 2.1.0 beta series, dirmngr is a local daemon that works
+  closely with gnupg2.  It is launched on its own, per-user, and
+  listens on a standard socket (usually ~/.gnupg/S.dirmngr).  There is
+  no more system-wide dirmngr process.
+
+  If there is a special case where a dirmngr system process is
+  actually needed, please report a bug in dirmngr, and we can sort out
+  a way to set one up for that case so that everyone with dirmngr
+  installed doesn't need to have it running.
+  
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 07 Oct 2014 10:33:52 -0400
+
diff --git a/dirmngr.README.Debian b/dirmngr.README.Debian
new file mode 100644 (file)
index 0000000..099240a
--- /dev/null
@@ -0,0 +1,47 @@
+dirmngr system integration
+==========================
+
+Since 2.1.x, gpg and most related processes will auto-launch dirmngr
+if needed.  These auto-launched processes will inherit whatever
+environment they started from, and they will not terminate
+automatically.
+
+systemd
+=======
+
+Since 2.1.17, users on machines with systemd will have a dirmngr
+process launched automatically by systemd's user session, upon first
+access of the standard socket.  systemd will also cleanly tear this
+process down at session logout.
+
+Users who don't want systemd to manage their dirmngr in this way for
+all future sessions should do:
+
+    systemctl --user mask --now dirmngr.socket
+
+Doing this means that dirmngr will fall back to its manual mode of
+operation.  (This decision can be reversed by the user with "unmask"
+instead of "mask")
+
+See systemctl(1) for more details about managing the dirmngr.socket
+unit.
+
+Manual dirmngr startup and teardown
+===================================
+
+Any user who wants to launch dirmngr manually (e.g., to talk to it
+with a tool from outside the GnuPG suite) and is *not* using systemd
+should first ensure that it is launched with:
+
+   gpgconf --launch dirmngr
+
+If dirmngr is launched manually or automatically (but not supervised
+by systemd), you also probably want to ensure that it terminates when
+your session ends with:
+
+   gpgconf --kill dirmngr
+
+If you're not using systemd, you may wish to add this command to your
+session logout scripts.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>, Mon, 23 Jan 2017 22:49:45 -0500
diff --git a/dirmngr.docs b/dirmngr.docs
new file mode 100644 (file)
index 0000000..817be40
--- /dev/null
@@ -0,0 +1,4 @@
+AUTHORS
+NEWS
+THANKS
+TODO
diff --git a/dirmngr.install b/dirmngr.install
new file mode 100644 (file)
index 0000000..4bd9ed2
--- /dev/null
@@ -0,0 +1,6 @@
+debian/tmp/usr/bin/dirmngr
+debian/tmp/usr/bin/dirmngr-client
+debian/tmp/usr/lib/gnupg/dirmngr_ldap
+debian/tmp/usr/share/gnupg/sks-keyservers.netCA.pem
+doc/examples/systemd-user/dirmngr.service usr/lib/systemd/user
+doc/examples/systemd-user/dirmngr.socket usr/lib/systemd/user
diff --git a/dirmngr.links b/dirmngr.links
new file mode 100644 (file)
index 0000000..ca801e7
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/systemd/user/dirmngr.socket /usr/lib/systemd/user/sockets.target.wants/dirmngr.socket
diff --git a/dirmngr.maintscript b/dirmngr.maintscript
new file mode 100644 (file)
index 0000000..aa11aa5
--- /dev/null
@@ -0,0 +1,5 @@
+rm_conffile /etc/default/dirmngr
+rm_conffile /etc/dirmngr/dirmngr.conf
+rm_conffile /etc/dirmngr/ldapservers.conf
+rm_conffile /etc/init.d/dirmngr
+rm_conffile /etc/logrotate.d/dirmngr
diff --git a/dirmngr.manpages b/dirmngr.manpages
new file mode 100644 (file)
index 0000000..93702d9
--- /dev/null
@@ -0,0 +1,2 @@
+debian/tmp/usr/share/man/man1/dirmngr-client.1
+debian/tmp/usr/share/man/man8/dirmngr.8
diff --git a/gbp.conf b/gbp.conf
new file mode 100644 (file)
index 0000000..b6518b7
--- /dev/null
+++ b/gbp.conf
@@ -0,0 +1,37 @@
+[DEFAULT]
+pristine-tar = True
+upstream-vcs-tag = gnupg-%(version)s
+debian-branch = stretch
+
+[buildpackage]
+compression = bzip2
+
+[import-orig]
+filter = [
+ 'aclocal.m4',
+ 'build-aux/compile',
+ 'build-aux/config.rpath',
+ 'build-aux/depcomp',
+ 'build-aux/install-sh',
+ 'build-aux/missing',
+ 'build-aux/mkinstalldirs',
+ 'build-aux/texinfo.tex',
+ 'config.h.in',
+ 'configure',
+ 'doc/gnupg.info*',
+ 'INSTALL',
+ 'm4/intdiv0.m4',
+ 'm4/intl.m4',
+ 'm4/lock.m4',
+ 'm4/printf-posix.m4',
+ 'm4/size_max.m4',
+ 'm4/uintmax_t.m4',
+ 'm4/wint_t.m4',
+ '*/*/Makefile.in',
+ '*/Makefile.in',
+ 'Makefile.in',
+ 'po/*.gmo',
+ 'po/Makefile.in.in',
+ 'po/stamp-po',
+ ]
+filter-pristine-tar = False
diff --git a/gnupg-agent.NEWS b/gnupg-agent.NEWS
new file mode 100644 (file)
index 0000000..69b4e49
--- /dev/null
@@ -0,0 +1,19 @@
+gnupg-agent (2.1.18-1) unstable; urgency=medium
+
+  If your machine is configured with system user session management,
+  gpg-agent will be managed automatically by systemd's user sessions on
+  machines configured with use systemd.  Please consider installing the
+  packages that the gnupg-agent package Suggests:, and see
+  /usr/share/doc/gnupg-agent/README.Debian for more details.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Mon, 23 Jan 2017 22:54:48 -0500
+
+gnupg-agent (2.1.13-3) experimental; urgency=medium
+
+  gpg-agent is no longer auto-launched by
+  /etc/X11/Xsession.d/90gpg-agent.  Please read
+  /usr/share/doc/gnupg-agent/README.Debian for details about system
+  integration.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Tue, 28 Jun 2016 17:29:46 -0400
+
diff --git a/gnupg-agent.README.Debian b/gnupg-agent.README.Debian
new file mode 100644 (file)
index 0000000..f57d278
--- /dev/null
@@ -0,0 +1,82 @@
+gpg-agent system integration
+============================
+
+Since 2.1.x, gpg and most related processes will auto-launch gpg-agent
+if needed.  These auto-launched processes will inherit whatever
+environment they started from, and they will not terminate
+automatically.
+
+systemd
+=======
+
+Since 2.1.17, users on machines with systemd will have their gpg-agent
+process launched automatically by systemd's user session, upon first
+access of any of the expected gpg-agent sockets (including the ssh
+socket).  systemd will also cleanly tear this process down at session
+logout.
+
+If dbus-user-session and pinentry-gnome3 packages are installed, then
+all user interaction with this systemd-managed gpg-agent process
+(e.g. prompting for passwords or confirmations, etc) will take place
+over the d-bus session, for better integration with graphical
+environments like GNOME.
+
+Users who don't want systemd to manage their gpg-agent in this way for
+all future sessions should do:
+
+    systemctl --user mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
+
+Doing this means that gpg-agent will fall back to its manual mode of
+operation.  (This decision can be reversed by the user with "unmask"
+instead of "mask")
+
+See systemctl(1) for more details about managing the gpg-agent*.socket
+units.
+
+ssh-agent emulation
+===================
+
+gpg-agent offers an ssh-agent emulation which can be achieved by
+setting the environment variable SSH_AUTH_SOCK to:
+
+    /run/user/$(id -u)/gnupg/S.gpg-agent.ssh
+
+(replace $(id -u) with the user's numeric user ID, of course). 
+
+But ssh doesn't have a way to tell ssh-agent how to prompt the user
+when necessary; the systemd-managed gpg-agent process will only know
+how to prompt the user if you have dbus-user-session and
+pinentry-gnome3 installed.  This is the recommended configuration for
+gpg-agent's ssh-agent emulation on desktop machines running systemd,
+and doesn't need any additional configuration.
+
+However, if dbus-user-session and pinentry-gnome3 are not in use, by
+default the systemd-managed gpg-agent will not know how to get
+feedback from the user when a request is first received by ssh.  You
+can give it a hint for all future ssh connections by running:
+
+    gpg-connect-agent updatestartuptty /bye
+
+You may wish to do this in the login scripts for your user session if
+you run systemd without dbus-user-session and pinentry-gnome3, and you
+plan to use gpg-agent's ssh-agent emulation.
+
+Manual gpg-agent startup and teardown
+=====================================
+
+Any user who wants to launch gpg-agent manually (e.g., to talk to it
+with a tool from outside the GnuPG suite) and is *not* using systemd
+should first ensure that it is launched with:
+
+    gpgconf --launch gpg-agent
+
+If gpg-agent is launched manually or automatically (but not supervised
+by systemd), you probably want to ensure that it terminates when your
+session ends with:
+
+    gpgconf --kill gpg-agent
+
+If you're not using systemd, you may wish to add this to your session
+logout scripts.
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>, Mon, 23 Jan 2017 22:56:08 -0500
diff --git a/gnupg-agent.examples b/gnupg-agent.examples
new file mode 100644 (file)
index 0000000..34213be
--- /dev/null
@@ -0,0 +1,2 @@
+doc/examples/pwpattern.list
+doc/examples/trustlist.txt
diff --git a/gnupg-agent.install b/gnupg-agent.install
new file mode 100644 (file)
index 0000000..2a4dcbe
--- /dev/null
@@ -0,0 +1,12 @@
+debian/Xsession.d/90gpg-agent etc/X11/Xsession.d
+debian/systemd-user/gpg-agent-browser.socket usr/lib/systemd/user
+debian/tmp/usr/bin/gpg-agent
+debian/tmp/usr/bin/gpg-connect-agent
+debian/tmp/usr/bin/symcryptrun
+debian/tmp/usr/lib/gnupg/gpg-check-pattern
+debian/tmp/usr/lib/gnupg/gpg-preset-passphrase
+debian/tmp/usr/lib/gnupg/gpg-protect-tool
+doc/examples/systemd-user/gpg-agent-extra.socket usr/lib/systemd/user
+doc/examples/systemd-user/gpg-agent-ssh.socket usr/lib/systemd/user
+doc/examples/systemd-user/gpg-agent.service usr/lib/systemd/user
+doc/examples/systemd-user/gpg-agent.socket usr/lib/systemd/user
diff --git a/gnupg-agent.links b/gnupg-agent.links
new file mode 100644 (file)
index 0000000..90f6ce1
--- /dev/null
@@ -0,0 +1,6 @@
+usr/lib/gnupg/gpg-preset-passphrase usr/lib/gnupg2/gpg-preset-passphrase
+usr/lib/gnupg/gpg-protect-tool usr/lib/gnupg2/gpg-protect-tool
+usr/lib/systemd/user/gpg-agent-browser.socket usr/lib/systemd/user/sockets.target.wants/gpg-agent-browser.socket
+usr/lib/systemd/user/gpg-agent-extra.socket usr/lib/systemd/user/sockets.target.wants/gpg-agent-extra.socket
+usr/lib/systemd/user/gpg-agent-ssh.socket usr/lib/systemd/user/sockets.target.wants/gpg-agent-ssh.socket
+usr/lib/systemd/user/gpg-agent.socket usr/lib/systemd/user/sockets.target.wants/gpg-agent.socket
diff --git a/gnupg-agent.manpages b/gnupg-agent.manpages
new file mode 100644 (file)
index 0000000..4819831
--- /dev/null
@@ -0,0 +1,5 @@
+debian/gpg-check-pattern.1
+debian/tmp/usr/share/man/man1/gpg-agent.1
+debian/tmp/usr/share/man/man1/gpg-connect-agent.1
+debian/tmp/usr/share/man/man1/gpg-preset-passphrase.1
+debian/tmp/usr/share/man/man1/symcryptrun.1
diff --git a/gnupg-l10n.install b/gnupg-l10n.install
new file mode 100644 (file)
index 0000000..9aaad82
--- /dev/null
@@ -0,0 +1,2 @@
+debian/tmp/usr/share/gnupg/help.*.txt
+debian/tmp/usr/share/locale
diff --git a/gnupg.README.Debian b/gnupg.README.Debian
new file mode 100644 (file)
index 0000000..24944d3
--- /dev/null
@@ -0,0 +1,44 @@
+Using "Modern" GnuPG
+====================
+
+As of version 2.1.11-7+exp1, the gnupg package is provided by the "modern"
+version of GnuPG.
+
+This means:
+
+  * supporting daemons are auto-launched as needed
+
+  * all access to secret key material is handled by gpg-agent
+
+  * all smartcard access is handled by scdaemon
+
+  * all network access is handled by dirmngr
+
+  * PGPv3 keys are no longer supported
+
+  * secret keys are no longer stored in $GNUPGHOME/secring.gpg, but
+    instead in $GNUPGHOME/private-keys-v1.d/
+
+  * public keyrings are stored in keybox format (~/.gnupg/pubring.kbx) by
+    default for new users.  Upgrading users will continue to use
+    pubring.gpg until they decide to explicitly convert.
+
+Converting an existing installation
+-----------------------------------
+
+If you have an existing GnuPG homedir from "classic" GnuPG, secret
+keys should be migrated automatically upon the first run of the
+"modern" version.
+
+If you have any secret keys that are stored only in a smartcard, after
+your first use of "modern" gpg you should insert the card and run:
+
+   gpg --card-status
+
+ (see https://bugs.debian.org/795881)
+
+Public keys will not be automatically migrated from pubring.gpg to
+pubring.kbx, however.  If you want to migrate your public keyring, you
+can use a script like /usr/bin/migrate-pubring-from-classic-gpg
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>, Mon, 18 Apr 2016 19:08:36 -0400
diff --git a/gnupg.docs b/gnupg.docs
new file mode 100644 (file)
index 0000000..b182260
--- /dev/null
@@ -0,0 +1,9 @@
+NEWS
+README
+THANKS
+TODO
+doc/DETAILS
+doc/FAQ
+doc/HACKING
+doc/KEYSERVER
+doc/OpenPGP
diff --git a/gnupg.examples b/gnupg.examples
new file mode 100644 (file)
index 0000000..3e74b94
--- /dev/null
@@ -0,0 +1 @@
+doc/examples/gpgconf.conf
diff --git a/gnupg.info b/gnupg.info
new file mode 100644 (file)
index 0000000..e4baa0f
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/share/info/gnupg.info*
+doc/gnupg-card-architecture.png
+doc/gnupg-module-overview.png
diff --git a/gnupg.install b/gnupg.install
new file mode 100644 (file)
index 0000000..9208425
--- /dev/null
@@ -0,0 +1,12 @@
+build/tools/gpg-zip usr/bin
+build/tools/gpgsplit usr/bin
+debian/migrate-pubring-from-classic-gpg usr/bin
+debian/tmp/usr/bin/gpg
+debian/tmp/usr/bin/gpgconf
+debian/tmp/usr/bin/gpgparsemail
+debian/tmp/usr/bin/kbxutil
+debian/tmp/usr/bin/watchgnupg
+debian/tmp/usr/sbin/addgnupghome
+debian/tmp/usr/sbin/applygnupgdefaults
+debian/tmp/usr/share/gnupg/distsigkey.gpg
+tools/lspgpot usr/bin
diff --git a/gnupg.manpages b/gnupg.manpages
new file mode 100644 (file)
index 0000000..4fc76c3
--- /dev/null
@@ -0,0 +1,11 @@
+debian/gpg-zip.1
+debian/gpgsplit.1
+debian/kbxutil.1
+debian/lspgpot.1
+debian/migrate-pubring-from-classic-gpg.1
+debian/tmp/usr/share/man/man1/gpg.1
+debian/tmp/usr/share/man/man1/gpgconf.1
+debian/tmp/usr/share/man/man1/gpgparsemail.1
+debian/tmp/usr/share/man/man1/watchgnupg.1
+debian/tmp/usr/share/man/man8/addgnupghome.8
+debian/tmp/usr/share/man/man8/applygnupgdefaults.8
diff --git a/gnupg2.links b/gnupg2.links
new file mode 100644 (file)
index 0000000..96fde98
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin/gpg usr/bin/gpg2
+usr/share/man/man1/gpg.1.gz usr/share/man/man1/gpg2.1.gz
diff --git a/gpg-check-pattern.1 b/gpg-check-pattern.1
new file mode 100644 (file)
index 0000000..05dbc1e
--- /dev/null
@@ -0,0 +1,35 @@
+.TH GPG-CHECK-PATTERN "1" "March 2016" "gpg-check-pattern (GnuPG) 2.1.11" "User Commands"
+
+.SH NAME
+gpg-check-pattern \- Check a passphrase on stdin against the patternfile
+
+.SH SYNOPSIS
+.B gpg\-check\-pattern
+.RB [ options ]
+.I patternfile
+
+.SH DESCRIPTION
+.B gpg\-check\-pattern checks a passphrase given on stdin against a specified patternfile.
+
+.SH OPTIONS
+.TP
+.BR \-v ", " \-\-verbose
+Produce verbose output
+.TP
+.BR \-\-check
+run only a syntax check on the patternfile
+.TP
+.BR \-0 ",  " \-\-null
+input is expected to be null delimited
+.PP
+Please report bugs to <https://bugs.gnupg.org>.
+
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
+
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+This manpage was written by \fBDaniel Kahn Gillmor\fR for the Debian
+distribution (but may be used by others).
diff --git a/gpg-zip.1 b/gpg-zip.1
new file mode 100644 (file)
index 0000000..cba5db4
--- /dev/null
+++ b/gpg-zip.1
@@ -0,0 +1,102 @@
+.TH "GPG\-ZIP" 1 "November 2006"
+
+.SH NAME
+gpg\-zip \- encrypt or sign files into an archive
+
+.SH SYNOPSIS
+.B gpg\-zip
+.RB [ OPTIONS ]
+.IR filename1 " [" "filename2, ..." ]
+.IR directory1 " [" "directory2, ..." ]
+
+.SH DESCRIPTION
+This manual page documents briefly the 
+.B gpg\-zip
+command.
+.PP
+.B gpg\-zip
+encrypts or signs files into an archive. It is an gpg-ized tar using the
+same format as PGP's PGP Zip.
+
+.SH OPTIONS
+.TP
+.BR \-e ", " \-\-encrypt
+Encrypt data. This option may be combined with 
+.B \-\-symmetric
+(for output that may be decrypted via a secret key or a passphrase).
+.TP
+.BR \-d ", " \-\-decrypt
+Decrypt data.
+.TP
+.BR \-c ", " \-\-symmetric
+Encrypt with a symmetric cipher using a passphrase.  The default
+symmetric cipher used is CAST5, but may be chosen with the
+.B \-\-cipher\-algo
+option to
+.BR gpg (1).
+.TP
+.BR \-s ", " \-\-sign
+Make a signature. See
+.BR gpg (1).
+.TP
+.BR \-r ", " \-\-recipient " \fIUSER\fR"
+Encrypt for user id \fIUSER\fR. See
+.BR gpg (1).
+.TP
+.BR \-u ", " \-\-local\-user " \fIUSER\fR"
+Use \fIUSER\fR as the key to sign with. See
+.BR gpg (1).
+.TP
+.B \-\-list\-archive
+List the contents of the specified archive.
+.TP
+.BR \-o ", " \-\-output " " \fIFILE\fR"
+Write output to specified file
+.IR FILE .
+.TP
+.BI \-\-gpg " GPG"
+Use the specified command instead of
+.BR gpg .
+.TP
+.BI \-\-gpg\-args " ARGS"
+Pass the specified options to
+.BR gpg (1).
+.TP
+.BI \-\-tar " TAR"
+Use the specified command instead of
+.BR tar .
+.TP
+.BI \-\-tar\-args " ARGS"
+Pass the specified options to 
+.BR tar (1).
+.TP
+.BR \-h ", " \-\-help
+Output a short usage information.
+.TP
+.B \-\-version
+Output the program version.
+
+.SH DIAGNOSTICS
+The program returns \fB0\fR if everything was fine, \fB1\fR otherwise.
+
+.SH EXAMPLES
+Encrypt the contents of directory \fImydocs\fR for user Bob to file \fItest1\fR:
+.IP
+.B gpg\-zip \-\-encrypt \-\-output test1 \-\-gpg-args ""\-r Bob"" mydocs
+.PP
+List the contents of archive \fItest1\fR:
+.IP
+.B gpg\-zip \-\-list\-archive test1
+
+.SH SEE ALSO
+.BR gpg (1),
+.BR tar (1)
+
+.SH AUTHOR
+Copyright (C) 2005 Free Software Foundation, Inc. Please report bugs to
+<\&bug-gnupg@gnu.org\&>.
+
+This manpage was written by \fBColin Tuckley\fR <\&colin@tuckley.org\&>
+and \fBDaniel Leidert\fR <\&daniel.leidert@wgdd.de\&> for the Debian
+distribution (but may be used by others).
+
diff --git a/gpgsm.install b/gpgsm.install
new file mode 100644 (file)
index 0000000..8822607
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/bin/gpgsm
diff --git a/gpgsm.manpages b/gpgsm.manpages
new file mode 100644 (file)
index 0000000..ad6a686
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/share/man/man1/gpgsm.1
diff --git a/gpgsplit.1 b/gpgsplit.1
new file mode 100644 (file)
index 0000000..116ce89
--- /dev/null
@@ -0,0 +1,41 @@
+.TH "gpgsplit" 1 "December 2005" 
+
+.SH NAME
+gpgsplit \- Split an OpenPGP message into packets
+
+.SH SYNOPSIS
+.B gpgsplit 
+.RI [ OPTIONS ]
+.RI [ FILES ]
+
+.SH DESCRIPTION
+This manual page documents briefly the 
+.B gpgsplit
+command.
+.PP
+.B gpgsplit
+splits an OpenPGP message into packets.
+
+.SH OPTIONS
+.TP
+.BR \-v , \-\-verbose
+Verbose.
+.TP
+.BR \-p , "\-\-prefix " \fISTRING\fR
+Prepend filenames with \fISTRING\fR.
+.TP
+.B \-\-uncompress
+Uncompress a packet.
+.TP
+.B \-\-secret\-to\-public
+Convert secret keys to public keys.
+.TP
+.B \-\-no\-split
+Write to stdout and don't actually split.
+
+.SH AUTHOR
+Copyright (C) 2002 Free Software Foundation, Inc. Please report bugs to
+<bug-gnupg@gnu.org>.
+
+This manpage was written by Francois Wendling <frwendling@free.fr>.
+
diff --git a/gpgv-static.1 b/gpgv-static.1
new file mode 100644 (file)
index 0000000..c8dcc1a
--- /dev/null
@@ -0,0 +1,32 @@
+.TH GPGV-STATIC "1" "November 2016" "GnuPG" "Gnu Privacy Guard 2.1"
+
+.SH NAME
+gpgv-static - Verify OpenPGP signatures (static build)
+
+.SH SYNOPSIS
+.B gpgv-static [\fIoptions\fP] \fIsigned_files\fP
+
+.SH DESCRIPTION
+\fBgpgv\fR is an OpenPGP signature verification tool.
+
+\fBgpgv-static\fR is \fBgpgv\fR built statically so that it can be
+directly used on any platform that is running on the Linux kernel,
+such as Android, ChromeOS, or many embedded Linux systems.
+
+This version of \fBgpgv\fR in combination with \fBdebootstrap\fR and
+the Debian archive keyring allows the secure creation of chroot
+installs on these platforms by using the full Debian signature
+verification that is present in all official Debian mirrors.
+
+You may wish to re-name the binary to plain \fBgpgv\fR when
+transferring it into such a platform to create a chroot.
+
+Please read the documentation for \fBgpgv\fR for more details.
+
+.SH SEE ALSO
+\fBgpg\fR(1)
+
+.SH AUTHOR
+This manual page was written by Daniel Kahn Gillmor
+<dkg@fifthhorseman.net> for the Debian project, but may be used by
+others under the same license as GnuPG itself.
diff --git a/gpgv-static.install b/gpgv-static.install
new file mode 100644 (file)
index 0000000..adb6deb
--- /dev/null
@@ -0,0 +1 @@
+build-gpgv-static/g10/gpgv-static usr/bin/
diff --git a/gpgv-static.lintian-overrides b/gpgv-static.lintian-overrides
new file mode 100644 (file)
index 0000000..fa0b8df
--- /dev/null
@@ -0,0 +1,3 @@
+# gpgv-static is deliberately built statically.  We cannot avoid
+# embedding zlib.
+gpgv-static: embedded-library usr/bin/gpgv-static: zlib
diff --git a/gpgv-static.manpages b/gpgv-static.manpages
new file mode 100644 (file)
index 0000000..e3f73aa
--- /dev/null
@@ -0,0 +1 @@
+debian/gpgv-static.1
diff --git a/gpgv-udeb.install b/gpgv-udeb.install
new file mode 100644 (file)
index 0000000..fe27533
--- /dev/null
@@ -0,0 +1 @@
+build-gpgv-udeb/g10/gpgv usr/bin/
diff --git a/gpgv-win32.install b/gpgv-win32.install
new file mode 100644 (file)
index 0000000..cf3cd8c
--- /dev/null
@@ -0,0 +1 @@
+build-gpgv-win32/g10/gpgv.exe usr/share/win32
diff --git a/gpgv.install b/gpgv.install
new file mode 100644 (file)
index 0000000..0a9f9a2
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/bin/gpgv
diff --git a/gpgv.manpages b/gpgv.manpages
new file mode 100644 (file)
index 0000000..86a9e29
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/share/man/man1/gpgv.1
diff --git a/gpgv2.links b/gpgv2.links
new file mode 100644 (file)
index 0000000..5107429
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin/gpgv usr/bin/gpgv2
+usr/share/man/man1/gpgv.1.gz usr/share/man/man1/gpgv2.1.gz
diff --git a/kbxutil.1 b/kbxutil.1
new file mode 100644 (file)
index 0000000..52b338a
--- /dev/null
+++ b/kbxutil.1
@@ -0,0 +1,62 @@
+.TH KBXUTIL "1" "March 2016" "kbxutil (GnuPG) 2.1.11" "User Commands"
+
+.SH NAME
+kbxutil \- List, export, import Keybox data
+
+.SH SYNOPSIS
+.B kbxutil
+.RB [ OPTIONS ]
+.RB [ FILES ]
+
+.SH DESCRIPTION
+List, export, import Keybox data
+
+.SH COMMANDS
+.TP
+.B \-\-stats
+show key statistics
+.TP
+.B \-\-import\-openpgp
+import OpenPGP keyblocks
+.TP
+.B \-\-find\-dups
+find duplicates
+.TP
+.B \-\-cut
+export records
+
+.SH OPTIONS
+.TP
+.BI \-\-from " N"
+first record to export
+.TP
+.BI \-\-to " N"
+last record to export
+.TP
+.BR \-v ", " \-\-verbose
+verbose
+.TP
+.BR \-q ", " \-\-quiet
+be somewhat more quiet
+.TP
+.BR \-n ", " \-\-dry\-run
+do not make any changes
+.TP
+.B \-\-debug
+set debugging flags
+.TP
+.B \-\-debug\-all
+enable full debugging
+
+.SH BUGS
+Please report bugs to <https://bugs.gnupg.org>.
+
+.SH COPYRIGHT
+Copyright \(co 2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
+
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+This manpage was written by \fBDaniel Kahn Gillmor\fR for the Debian
+distribution (but may be used by others).
diff --git a/lspgpot.1 b/lspgpot.1
new file mode 100644 (file)
index 0000000..ba27eca
--- /dev/null
+++ b/lspgpot.1
@@ -0,0 +1,22 @@
+.TH "lspgpot" 1 "December 2005" 
+
+.SH NAME
+lspgpot - extracts the ownertrust values from PGP keyrings and list them in
+GnuPG ownertrust format.
+
+
+.SH SYNOPSIS
+.B lspgpot
+
+
+.SH DESCRIPTION
+.B lspgpot
+extracts the ownertrust values from PGP keyrings and list them in
+GnuPG ownertrust format.
+
+.SH AUTHOR
+Copyright (C) 2002 Free Software Foundation, Inc. Please report bugs to
+<bug-gnupg@gnu.org>.
+
+This manpage was written by Francois Wendling <frwendling@free.fr>.
+
diff --git a/migrate-pubring-from-classic-gpg b/migrate-pubring-from-classic-gpg
new file mode 100755 (executable)
index 0000000..13ee1f8
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+# script to migrate fully from pubring.gpg to pubring.kbx
+
+# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+# Date: 2016-04-01
+# License: GPLv3+
+
+# This was written for the Debian project
+
+set -e
+
+GPG="${GPG:-gpg}"
+
+# select the default GnuPG home directory to work from:
+GHD=${GNUPGHOME:-${HOME:-$(getent passwd "$(id -u)" | cut -f6 -d:)}/.gnupg}
+
+# Check that this is gnupg 2.1 or 2.2:
+VERSION=$("$GPG" --version | head -n1 | cut -f3 -d\  | cut -f1,2 -d.)
+if [ "$VERSION" != 2.1 ] && [ "$VERSION" != 2.2 ] ; then
+    printf '%s is version %s not version 2.1 or 2.2, this script might be wrong\n' "$GPG" "$VERSION" >&2
+    exit 1
+fi    
+
+usage() {
+    printf 'Usage: %s [GPGHOMEDIR|--default]
+\tMigrate public keyring in GPGHOMEDIR from "classic" to "modern" GnuPG
+\tusing %s version %s.
+
+\t--default migrates the GnuPG home directory at "%s"
+' "$0" "$GPG" "$VERSION" "$GHD"
+}
+
+if [ -z "$1" ]; then
+    usage >&2
+    exit 1
+else
+    case "$1" in
+        --help|--usage|-h)
+            usage
+            exit
+            ;;
+        --default)
+            ;;
+        *)
+            GHD="$1"
+            ;;
+    esac
+fi
+
+# ensure that there is a pubring.gpg to migrate:
+if ! [ -f "$GHD/pubring.gpg" ]; then
+    printf 'There is no %s/pubring.gpg, no need to migrate\n' "$GHD" >&2
+    exit
+fi
+if ! [ -s "$GHD/pubring.gpg" ]; then
+    mv -- "$GHD/pubring.gpg" "$GHD/pubring.gpg.empty"
+    printf '%s/pubring.gpg was empty (and has been moved out of the way), no need to migrate\n' "$GHD" >&2
+    exit
+fi
+
+BACKUP="$(mktemp -d "$GHD/migrate-from-classic-backup.$(date +%F).XXXXXX")"
+printf 'Migrating from:\n%s\n[Backing up to %s]\n' "$(ls -l "$GHD/pubring.gpg")" "$BACKUP" >&2
+
+"$GPG" --export-ownertrust > "$BACKUP/ownertrust.txt"
+mv "$GHD/pubring.gpg" "$BACKUP/"
+"$GPG" --import-options import-local-sigs,keep-ownertrust,repair-pks-subkey-bug --import < "$BACKUP/pubring.gpg"
+"$GPG" --import-ownertrust < "$BACKUP/ownertrust.txt"
+"$GPG" --check-trustdb
+
+if ! [ -f "$GHD/pubring.kbx" ]; then
+    printf 'No keybox was created at %s/pubring.kbx.  Something went wrong!\n' "$GHD" >&2
+    exit 1
+fi
+
+printf 'Migration completed successfully:\n%s\n' "$(ls -l "$GHD/pubring.kbx")" >&2 
diff --git a/migrate-pubring-from-classic-gpg.1 b/migrate-pubring-from-classic-gpg.1
new file mode 100644 (file)
index 0000000..4d26b89
--- /dev/null
@@ -0,0 +1,50 @@
+.TH "MIGRATE-PUBRING-FROM-CLASSIC-GPG" 1 "April 2016"
+
+.SH NAME
+migrate\-pubring\-from\-classic\-gpg \- Migrate a public keyring from "classic" to "modern" GnuPG
+
+.SH SYNOPSIS
+.B migrate\-pubring\-from\-classic\-gpg
+.RB "[ " GPGHOMEDIR " | "
+.IR \-\-default " ]"
+
+.SH DESCRIPTION
+
+.B migrate\-pubring\-from\-classic\-gpg
+migrates the public keyring in GnuPG home directory GPGHOMEDIR from
+the "classic" keyring format to the "modern" keybox format using GnuPG
+versions 2.1 or 2.2.
+
+Specifying
+.B \-\-default
+selects the standard GnuPG home directory (looking at $GNUPGHOME
+first, and falling back to ~/.gnupg if unset.
+
+.SH OPTIONS
+.BR \-h ", " \-\-help ", " \-\-usage
+Output a short usage information.
+
+.SH DIAGNOSTICS
+The program sends quite a bit of text (perhaps too much) to stderr.
+
+During a migration, the tool backs up several pieces of data in a
+timestamped subdirectory of the GPGHOMEDIR.
+
+.SH ENVIRONMENT VARIABLES
+
+.B GNUPGHOME
+Selects the GnuPG home directory when set and --default is given.
+
+.B GPG
+The name of the
+.B gpg
+executable (defaults to
+.B gpg
+).
+
+.SH SEE ALSO
+.BR gpg (1)
+
+.SH AUTHOR
+Copyright (C) 2016 Daniel Kahn Gillmor for the Debian project. Please
+report bugs via the Debian BTS.
diff --git a/patches/0012-tools-Fix-memory-leak.patch b/patches/0012-tools-Fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..4d47557
--- /dev/null
@@ -0,0 +1,28 @@
+From: Justus Winter <justus@g10code.com>
+Date: Mon, 23 Jan 2017 11:52:30 +0100
+Subject: tools: Fix memory leak.
+
+* tools/gpgconf-comp.c (change_options_file): Fix leak.
+--
+Previously, 'src_filename' and 'orig_filename' leaked if creating the
+backup file failed.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 5b28f025085b386e0ec49535d4cd3f875a414eb0)
+---
+ tools/gpgconf-comp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index a25b5136e..85eb80ab5 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -2641,6 +2641,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
+   if (res < 0 && errno != ENOENT)
+     {
+       xfree (dest_filename);
++      xfree (src_filename);
++      xfree (orig_filename);
+       return -1;
+     }
+   if (res < 0)
diff --git a/patches/0013-tools-Improve-error-handling.patch b/patches/0013-tools-Improve-error-handling.patch
new file mode 100644 (file)
index 0000000..b0034da
--- /dev/null
@@ -0,0 +1,29 @@
+From: Justus Winter <justus@g10code.com>
+Date: Mon, 23 Jan 2017 14:24:22 +0100
+Subject: tools: Improve error handling.
+
+* tools/gpgconf-comp.c (gp_component_change_options): Improve error
+handling when reading from stdin.
+--
+Previously, errors encountered while reading the configuration changes
+were ignored.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit b0348fdb26637b0bcbd68a96c1746a1613b309af)
+---
+ tools/gpgconf-comp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 85eb80ab5..180fd65c2 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -3328,6 +3328,8 @@ gc_component_change_options (int component, estream_t in, estream_t out,
+           change_one_value (option, runtime, flags, new_value, 0);
+         }
++      if (length < 0 || gpgrt_ferror (in))
++      gc_error (1, errno, "error reading stream 'in'");
+     }
+   /* Now that we have collected and locally verified the changes,
diff --git a/patches/0014-dirmngr-New-option-disable-ipv4.patch b/patches/0014-dirmngr-New-option-disable-ipv4.patch
new file mode 100644 (file)
index 0000000..0aa0549
--- /dev/null
@@ -0,0 +1,245 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 24 Jan 2017 16:36:28 +0100
+Subject: dirmngr: New option --disable-ipv4.
+
+* dirmngr/dirmngr.c (oDisableIPv4): New const.
+(opts): New option --disable-ipv4.
+(parse_rereadable_options): Set that option.
+* dirmngr/dirmngr.h (opt): New field 'disable_ipv4'.
+* dirmngr/dns-stuff.c (opt_disable_ipv4): bew var.
+(set_dns_disable_ipv4): New.
+(resolve_name_standard): Skip v4 addresses when OPT_DISABLE_IPV4 is
+set.
+* dirmngr/ks-engine-hkp.c (map_host): Ditto.
+(send_request): Pass HTTP_FLAG_IGNORE_IPv4 if opt.disable_v4 is set.
+* dirmngr/crlfetch.c (crl_fetch): Ditto.
+* dirmngr/ks-engine-finger.c (ks_finger_fetch): Ditto.
+* dirmngr/ks-engine-http.c (ks_http_fetch): Ditto.
+* dirmngr/ocsp.c (do_ocsp_request): Ditto.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 72736af86a501592d974d46ff754a63959e183bd)
+---
+ dirmngr/crlfetch.c         |  4 +++-
+ dirmngr/dirmngr.c          |  5 +++++
+ dirmngr/dirmngr.h          |  1 +
+ dirmngr/dns-stuff.c        | 15 +++++++++++++++
+ dirmngr/dns-stuff.h        |  4 ++++
+ dirmngr/ks-engine-finger.c |  4 +++-
+ dirmngr/ks-engine-hkp.c    |  8 ++++++--
+ dirmngr/ks-engine-http.c   |  3 ++-
+ dirmngr/ocsp.c             |  3 ++-
+ doc/dirmngr.texi           |  5 +++++
+ 10 files changed, 46 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
+index 8fe6e0b1b..aa82137f7 100644
+--- a/dirmngr/crlfetch.c
++++ b/dirmngr/crlfetch.c
+@@ -198,7 +198,9 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+         err = http_open_document (&hd, url, NULL,
+                                   ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                                    |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0)
+-                                   |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++                                   |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                                   |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0)
++                                   ),
+                                   ctrl->http_proxy, NULL, NULL, NULL);
+       switch ( err? 99999 : http_get_status_code (hd) )
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 8d9de9e5a..83356c94c 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -111,6 +111,7 @@ enum cmd_and_opt_values {
+   oBatch,
+   oDisableHTTP,
+   oDisableLDAP,
++  oDisableIPv4,
+   oIgnoreLDAPDP,
+   oIgnoreHTTPDP,
+   oIgnoreOCSPSvcUrl,
+@@ -224,6 +225,8 @@ static ARGPARSE_OPTS opts[] = {
+   ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
++  ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
++
+   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
+   ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
+@@ -586,6 +589,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+     case oDisableHTTP: opt.disable_http = 1; break;
+     case oDisableLDAP: opt.disable_ldap = 1; break;
++    case oDisableIPv4: opt.disable_ipv4 = 1; break;
+     case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
+     case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
+     case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
+@@ -645,6 +649,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+   set_dns_verbose (opt.verbose, !!DBG_DNS);
+   http_set_verbose (opt.verbose, !!DBG_NETWORK);
++  set_dns_disable_ipv4 (opt.disable_ipv4);
+   return 1; /* Handled. */
+ }
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index acd4c636d..fd80d7237 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -98,6 +98,7 @@ struct
+   int disable_http;       /* Do not use HTTP at all.  */
+   int disable_ldap;       /* Do not use LDAP at all.  */
++  int disable_ipv4;       /* Do not use leagacy IP addresses.  */
+   int honor_http_proxy;   /* Honor the http_proxy env variable. */
+   const char *http_proxy; /* The default HTTP proxy.  */
+   const char *ldap_proxy; /* Use given LDAP proxy.  */
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 9347196b3..ad19fc2ce 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -119,6 +119,10 @@ static int opt_debug;
+ /* The timeout in seconds for libdns requests.  */
+ static int opt_timeout;
++/* The flag to disable IPv4 access - right now this only skips
++ * returned A records.  */
++static int opt_disable_ipv4;
++
+ /* If set force the use of the standard resolver.  */
+ static int standard_resolver;
+@@ -227,6 +231,15 @@ set_dns_verbose (int verbose, int debug)
+ }
++/* Set the Disable-IPv4 flag so that the name resolver does not return
++ * A addresses.  */
++void
++set_dns_disable_ipv4 (int yes)
++{
++  opt_disable_ipv4 = !!yes;
++}
++
++
+ /* Set the timeout for libdns requests to SECONDS.  A value of 0 sets
+  * the default timeout and values are capped at 10 minutes.  */
+ void
+@@ -873,6 +886,8 @@ resolve_name_standard (const char *name, unsigned short port,
+     {
+       if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
+         continue;
++      if (opt_disable_ipv4 && ai->ai_family == AF_INET)
++        continue;
+       dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
+       dai->family = ai->ai_family;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index d68dd1728..9eb97fd6a 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -95,6 +95,10 @@ struct srventry
+ /* Set verbosity and debug mode for this module. */
+ void set_dns_verbose (int verbose, int debug);
++/* Set the Disable-IPv4 flag so that the name resolver does not return
++ * A addresses.  */
++void set_dns_disable_ipv4 (int yes);
++
+ /* Set the timeout for libdns requests to SECONDS.  */
+ void set_dns_timeout (int seconds);
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index b1f02ad7d..114f2e9ac 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -83,7 +83,9 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+   *server++ = 0;
+   err = http_raw_connect (&http, server, 79,
+-                          (opt.use_tor? HTTP_FLAG_FORCE_TOR : 0), NULL);
++                          ((opt.use_tor? HTTP_FLAG_FORCE_TOR : 0)
++                           | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++                          NULL);
+   if (err)
+     {
+       xfree (name);
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 2b90441e2..dad83efcd 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -526,6 +526,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+             {
+               if (ai->family != AF_INET && ai->family != AF_INET6)
+                 continue;
++              if (opt.disable_ipv4 && ai->family == AF_INET)
++                continue;
+               dirmngr_tick (ctrl);
+               add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
+@@ -607,7 +609,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+         {
+           for (ai = aibuf; ai; ai = ai->next)
+             {
+-              if (ai->family == AF_INET6 || ai->family == AF_INET)
++              if (ai->family == AF_INET6
++                  || (!opt.disable_ipv4 && ai->family == AF_INET))
+                 {
+                   err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+                   if (!err)
+@@ -1058,7 +1061,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+                    /* fixme: AUTH */ NULL,
+                    (httpflags
+                     |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++                    |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy,
+                    session,
+                    NULL,
+diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
+index 858c943ea..dbbf4bb79 100644
+--- a/dirmngr/ks-engine-http.c
++++ b/dirmngr/ks-engine-http.c
+@@ -88,7 +88,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+                    /* httphost */ NULL,
+                    /* fixme: AUTH */ NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy,
+                    session,
+                    NULL,
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index 9127cf754..b46c78567 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -174,7 +174,8 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+  once_more:
+   err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy, NULL, NULL, NULL);
+   if (err)
+     {
+diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
+index dd104273d..b00c2d377 100644
+--- a/doc/dirmngr.texi
++++ b/doc/dirmngr.texi
+@@ -312,6 +312,11 @@ not be used a different one can be given using this option.  Note that
+ a numerical IP address must be given (IPv6 or IPv4) and that no error
+ checking is done for @var{ipaddr}.
++@item --disable-ipv4
++@opindex disable-ipv4
++Disable the use of all IPv4 addresses.  This option is mainly useful
++for debugging.
++
+ @item --disable-ldap
+ @opindex disable-ldap
+ Entirely disables the use of LDAP.
diff --git a/patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch b/patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch
new file mode 100644 (file)
index 0000000..bcf4ee6
--- /dev/null
@@ -0,0 +1,255 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 24 Jan 2017 18:41:43 +0100
+Subject: dirmngr: Simplify error returning inside http.c.
+
+* dirmngr/http.c (connect_server): Change to return an gpg_error_t
+and to store socket at the passed address.
+(http_raw_connect, send_request): Adjust accordingly.
+--
+
+This change removes cruft from the code and allows to return the error
+code from the name lookup.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 51e5a5e5a46279809848b4ab4419f35045336010)
+---
+ dirmngr/http.c | 101 ++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 50 insertions(+), 51 deletions(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index 35877d241..fe9c3c734 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -155,9 +155,9 @@ static gpg_error_t send_request (http_t hd, const char *httphost,
+ static char *build_rel_path (parsed_uri_t uri);
+ static gpg_error_t parse_response (http_t hd);
+-static assuan_fd_t connect_server (const char *server, unsigned short port,
++static gpg_error_t connect_server (const char *server, unsigned short port,
+                                    unsigned int flags, const char *srvtag,
+-                                   int *r_host_not_found);
++                                   assuan_fd_t *r_sock);
+ static gpg_error_t write_server (int sock, const char *data, size_t length);
+ static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
+@@ -924,7 +924,6 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+   gpg_error_t err = 0;
+   http_t hd;
+   cookie_t cookie;
+-  int hnf;
+   *r_hd = NULL;
+@@ -950,12 +949,9 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+   {
+     assuan_fd_t sock;
+-    sock = connect_server (server, port, hd->flags, srvtag, &hnf);
+-    if (sock == ASSUAN_INVALID_FD)
++    err = connect_server (server, port, hd->flags, srvtag, &sock);
++    if (err)
+       {
+-        err = gpg_err_make (default_errsource,
+-                            (hnf? GPG_ERR_UNKNOWN_HOST
+-                             : gpg_err_code_from_syserror ()));
+         xfree (hd);
+         return err;
+       }
+@@ -1643,7 +1639,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+   char *proxy_authstr = NULL;
+   char *authstr = NULL;
+   int sock;
+-  int hnf;
+   if (hd->uri->use_tls && !hd->session)
+     {
+@@ -1713,7 +1708,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+             && *http_proxy ))
+     {
+       parsed_uri_t uri;
+-      int save_errno;
+       if (proxy)
+       http_proxy = proxy;
+@@ -1760,25 +1754,20 @@ send_request (http_t hd, const char *httphost, const char *auth,
+             }
+         }
+-      sock = connect_server (*uri->host ? uri->host : "localhost",
+-                             uri->port ? uri->port : 80,
+-                             hd->flags, srvtag, &hnf);
+-      save_errno = errno;
++      err = connect_server (*uri->host ? uri->host : "localhost",
++                            uri->port ? uri->port : 80,
++                            hd->flags, srvtag, &sock);
+       http_release_parsed_uri (uri);
+-      if (sock == ASSUAN_INVALID_FD)
+-        gpg_err_set_errno (save_errno);
+     }
+   else
+     {
+-      sock = connect_server (server, port, hd->flags, srvtag, &hnf);
++      err = connect_server (server, port, hd->flags, srvtag, &sock);
+     }
+-  if (sock == ASSUAN_INVALID_FD)
++  if (err)
+     {
+       xfree (proxy_authstr);
+-      return gpg_err_make (default_errsource,
+-                           (hnf? GPG_ERR_UNKNOWN_HOST
+-                               : gpg_err_code_from_syserror ()));
++      return err;
+     }
+   hd->sock = my_socket_new (sock);
+   if (!hd->sock)
+@@ -1788,7 +1777,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+     }
+-
+ #if HTTP_USE_NTBTLS
+   if (hd->uri->use_tls)
+     {
+@@ -2476,11 +2464,13 @@ my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
+ }
+-/* Actually connect to a server.  Returns the file descriptor or -1 on
+-   error.  ERRNO is set on error. */
+-static assuan_fd_t
++/* Actually connect to a server.  On success 0 is returned and the
++ * file descriptor for the socket is stored at R_SOCK; on error an
++ * error code is returned and ASSUAN_INVALID_FD is stored at
++ * R_SOCK.  */
++static gpg_error_t
+ connect_server (const char *server, unsigned short port,
+-                unsigned int flags, const char *srvtag, int *r_host_not_found)
++                unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
+ {
+   gpg_error_t err;
+   assuan_fd_t sock = ASSUAN_INVALID_FD;
+@@ -2488,11 +2478,11 @@ connect_server (const char *server, unsigned short port,
+   int hostfound = 0;
+   int anyhostaddr = 0;
+   int srv, connected;
+-  int last_errno = 0;
++  gpg_error_t last_err = 0;
+   struct srventry *serverlist = NULL;
+-  int ret;
+-  *r_host_not_found = 0;
++  *r_sock = ASSUAN_INVALID_FD;
++
+ #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
+   init_sockets ();
+ #endif /*Windows*/
+@@ -2509,18 +2499,21 @@ connect_server (const char *server, unsigned short port,
+                                          ASSUAN_SOCK_TOR);
+       if (sock == ASSUAN_INVALID_FD)
+         {
+-          if (errno == EHOSTUNREACH)
+-            *r_host_not_found = 1;
+-          log_error ("can't connect to '%s': %s\n", server, strerror (errno));
++          err = gpg_err_make (default_errsource,
++                              (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
++                              : gpg_err_code_from_syserror ());
++          log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
++          return err;
+         }
+-      else
+-        notify_netactivity ();
+-      return sock;
++
++      notify_netactivity ();
++      *r_sock = sock;
++      return 0;
+ #else /*!ASSUAN_SOCK_TOR*/
+-      gpg_err_set_errno (ENETUNREACH);
+-      return -1; /* Out of core.  */
++      err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
++      return ASSUAN_INVALID_FD;
+ #endif /*!HASSUAN_SOCK_TOR*/
+     }
+@@ -2533,6 +2526,7 @@ connect_server (const char *server, unsigned short port,
+         log_info ("getting '%s' SRV for '%s' failed: %s\n",
+                   srvtag, server, gpg_strerror (err));
+       /* Note that on error SRVCOUNT is zero.  */
++      err = 0;
+     }
+   if (!serverlist)
+@@ -2541,7 +2535,8 @@ connect_server (const char *server, unsigned short port,
+        up a fake SRV record. */
+       serverlist = xtrycalloc (1, sizeof *serverlist);
+       if (!serverlist)
+-        return -1; /* Out of core.  */
++        return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++
+       serverlist->port = port;
+       strncpy (serverlist->target, server, DIMof (struct srventry, target));
+       serverlist->target[DIMof (struct srventry, target)-1] = '\0';
+@@ -2562,6 +2557,7 @@ connect_server (const char *server, unsigned short port,
+         {
+           log_info ("resolving '%s' failed: %s\n",
+                     serverlist[srv].target, gpg_strerror (err));
++          last_err = err;
+           continue; /* Not found - try next one. */
+         }
+       hostfound = 1;
+@@ -2578,18 +2574,20 @@ connect_server (const char *server, unsigned short port,
+           sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
+           if (sock == ASSUAN_INVALID_FD)
+             {
+-              int save_errno = errno;
+-              log_error ("error creating socket: %s\n", strerror (errno));
++              err = gpg_err_make (default_errsource,
++                                  gpg_err_code_from_syserror ());
++              log_error ("error creating socket: %s\n", gpg_strerror (err));
+               free_dns_addrinfo (aibuf);
+               xfree (serverlist);
+-              errno = save_errno;
+-              return ASSUAN_INVALID_FD;
++              return err;
+             }
+           anyhostaddr = 1;
+-          ret = assuan_sock_connect (sock, ai->addr, ai->addrlen);
+-          if (ret)
+-            last_errno = errno;
++          if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
++            {
++              last_err = gpg_err_make (default_errsource,
++                                       gpg_err_code_from_syserror ());
++            }
+           else
+             {
+               connected = 1;
+@@ -2616,17 +2614,18 @@ connect_server (const char *server, unsigned short port,
+                    server, (int)WSAGetLastError());
+ #else
+         log_error ("can't connect to '%s': %s\n",
+-                   server, strerror (last_errno));
++                   server, gpg_strerror (last_err));
+ #endif
+         }
+-      if (!hostfound || (hostfound && !anyhostaddr))
+-        *r_host_not_found = 1;
++      err = last_err? last_err : gpg_err_make (default_errsource,
++                                               GPG_ERR_UNKNOWN_HOST);
+       if (sock != ASSUAN_INVALID_FD)
+       assuan_sock_close (sock);
+-      gpg_err_set_errno (last_errno);
+-      return ASSUAN_INVALID_FD;
++      return err;
+     }
+-  return sock;
++
++  *r_sock = sock;
++  return 0;
+ }
diff --git a/patches/0016-gpg-Print-a-warning-on-Tor-problems.patch b/patches/0016-gpg-Print-a-warning-on-Tor-problems.patch
new file mode 100644 (file)
index 0000000..1979069
--- /dev/null
@@ -0,0 +1,188 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 24 Jan 2017 20:45:31 +0100
+Subject: gpg: Print a warning on Tor problems.
+
+* dirmngr/ks-engine-hkp.c (tor_not_running_p): New.
+(map_host): Call that to print a warning.
+(handle_send_request_error): Ditto and avoid marking the host dead.
+Also print a tor_config_problem warning.  Add arg CTRL; adjust callers
+to pass that new arg.
+* g10/call-dirmngr.c (ks_status_cb): Detect and print the new
+warnings.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 770b75a746836773909af25ccb9b480e61cea677)
+---
+ dirmngr/ks-engine-hkp.c | 60 ++++++++++++++++++++++++++++++++++++-------------
+ g10/call-dirmngr.c      | 26 ++++++++++++++++++++-
+ 2 files changed, 70 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index dad83efcd..858cd2f26 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -278,6 +278,31 @@ arecords_is_pool (dns_addrinfo_t aibuf)
+ }
++/* Print a warninng iff Tor is not running but Tor has been requested.
++ * Also return true if it is not running.  */
++static int
++tor_not_running_p (ctrl_t ctrl)
++{
++  assuan_fd_t sock;
++
++  if (!opt.use_tor)
++    return 0;
++
++  sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
++  if (sock != ASSUAN_INVALID_FD)
++    {
++      assuan_sock_close (sock);
++      return 0;
++    }
++
++  log_info ("(it seems Tor is not running)\n");
++  dirmngr_status (ctrl, "WARNING", "tor_not_running 0",
++                  "Tor is enabled but the local Tor daemon"
++                  " seems to be down", NULL);
++  return 1;
++}
++
++
+ /* Add the host AI under the NAME into the HOSTTABLE.  If PORT is not
+    zero, it specifies which port to use to talk to the host.  If NAME
+    specifies a pool (as indicated by IS_POOL), update the given
+@@ -475,6 +500,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+           if (err)
+             {
+               xfree (reftbl);
++              if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
++                tor_not_running_p (ctrl);
+               return err;
+             }
+@@ -1180,13 +1207,13 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+ }
+-/* Helper to evaluate the error code ERR form a send_request() call
++/* Helper to evaluate the error code ERR from a send_request() call
+    with REQUEST.  The function returns true if the caller shall try
+    again.  TRIES_LEFT points to a variable to track the number of
+    retries; this function decrements it and won't return true if it is
+    down to zero. */
+ static int
+-handle_send_request_error (gpg_error_t err, const char *request,
++handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
+                            unsigned int *tries_left)
+ {
+   int retry = 0;
+@@ -1197,16 +1224,9 @@ handle_send_request_error (gpg_error_t err, const char *request,
+   switch (gpg_err_code (err))
+     {
+     case GPG_ERR_ECONNREFUSED:
+-      if (opt.use_tor)
+-        {
+-          assuan_fd_t sock;
+-
+-          sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
+-          if (sock == ASSUAN_INVALID_FD)
+-            log_info ("(it seems Tor is not running)\n");
+-          else
+-            assuan_sock_close (sock);
+-        }
++      if (tor_not_running_p (ctrl))
++        break; /* A retry does not make sense.  */
++      /* Okay: Tor is up or --use-tor is not used.  */
+       /*FALLTHRU*/
+     case GPG_ERR_ENETUNREACH:
+     case GPG_ERR_ENETDOWN:
+@@ -1224,6 +1244,16 @@ handle_send_request_error (gpg_error_t err, const char *request,
+         }
+       break;
++    case GPG_ERR_EACCES:
++      if (opt.use_tor)
++        {
++          log_info ("(Tor configuration problem)\n");
++          dirmngr_status (ctrl, "WARNING", "tor_config_problem 0",
++                          "Please check that the \"SocksPort\" flag "
++                          "\"IPv6Traffic\" is set in torrc", NULL);
++        }
++      break;
++
+     default:
+       break;
+     }
+@@ -1334,7 +1364,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
+   /* Send the request.  */
+   err = send_request (ctrl, request, hostport, httphost, httpflags,
+                       NULL, NULL, &fp, r_http_status);
+-  if (handle_send_request_error (err, request, &tries))
++  if (handle_send_request_error (ctrl, err, request, &tries))
+     {
+       reselect = 1;
+       goto again;
+@@ -1468,7 +1498,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
+   /* Send the request.  */
+   err = send_request (ctrl, request, hostport, httphost, httpflags,
+                       NULL, NULL, &fp, NULL);
+-  if (handle_send_request_error (err, request, &tries))
++  if (handle_send_request_error (ctrl, err, request, &tries))
+     {
+       reselect = 1;
+       goto again;
+@@ -1577,7 +1607,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
+   /* Send the request.  */
+   err = send_request (ctrl, request, hostport, httphost, 0,
+                       put_post_cb, &parm, &fp, NULL);
+-  if (handle_send_request_error (err, request, &tries))
++  if (handle_send_request_error (ctrl, err, request, &tries))
+     {
+       reselect = 1;
+       goto again;
+diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
+index 4be9da117..2f2ba982e 100644
+--- a/g10/call-dirmngr.c
++++ b/g10/call-dirmngr.c
+@@ -374,7 +374,8 @@ ks_status_cb (void *opaque, const char *line)
+ {
+   struct ks_status_parm_s *parm = opaque;
+   gpg_error_t err = 0;
+-  const char *s;
++  const char *s, *s2;
++  const char *warn;
+   if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE")))
+     {
+@@ -385,6 +386,29 @@ ks_status_cb (void *opaque, const char *line)
+             err = gpg_error_from_syserror ();
+         }
+     }
++  else if ((s = has_leading_keyword (line, "WARNING")))
++    {
++      if ((s2 = has_leading_keyword (s, "tor_not_running")))
++        warn = _("Tor is not running");
++      else if ((s2 = has_leading_keyword (s, "tor_config_problem")))
++        warn = _("Tor is not properly configured");
++      else
++        warn = NULL;
++
++      if (warn)
++        {
++          log_info (_("WARNING: %s\n"), warn);
++          if (s2)
++            {
++              while (*s2 && !spacep (s2))
++                s2++;
++              while (*s2 && spacep (s2))
++                s2++;
++              if (*s2)
++                print_further_info ("%s", s2);
++            }
++        }
++    }
+   return err;
+ }
diff --git a/patches/0017-agent-Fix-double-free.patch b/patches/0017-agent-Fix-double-free.patch
new file mode 100644 (file)
index 0000000..b3d96ed
--- /dev/null
@@ -0,0 +1,49 @@
+From: Justus Winter <justus@g10code.com>
+Date: Wed, 25 Jan 2017 13:51:57 +0100
+Subject: agent: Fix double free.
+
+* agent/cache.c (agent_store_cache_hit): Make sure the update is
+atomic.
+--
+Previously, the function freed the last key, and duplicated the new
+key after doing that.  There is a chance, however, that calling the
+allocator surrenders control to a different thread, causing a double
+free if a different thread also calls this function.
+
+To make sure the update is atomic under the non-preemptive thread
+model, we must make sure not to surrender control to a different
+thread.  Therefore, we avoid calling the allocator during the
+update.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit e175152ef7515921635bf1e00383e812668d13fc)
+---
+ agent/cache.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/agent/cache.c b/agent/cache.c
+index f58eaeaaa..248368277 100644
+--- a/agent/cache.c
++++ b/agent/cache.c
+@@ -475,6 +475,19 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+ void
+ agent_store_cache_hit (const char *key)
+ {
+-  xfree (last_stored_cache_key);
+-  last_stored_cache_key = key? xtrystrdup (key) : NULL;
++  char *new;
++  char *old;
++
++  /* To make sure the update is atomic under the non-preemptive thread
++   * model, we must make sure not to surrender control to a different
++   * thread.  Therefore, we avoid calling the allocator during the
++   * update.  */
++  new = key ? xtrystrdup (key) : NULL;
++
++  /* Atomic update.  */
++  old = last_stored_cache_key;
++  last_stored_cache_key = new;
++  /* Done.  */
++
++  xfree (old);
+ }
diff --git a/patches/0018-gpg-Fix-searching-for-mail-addresses-in-keyrings.patch b/patches/0018-gpg-Fix-searching-for-mail-addresses-in-keyrings.patch
new file mode 100644 (file)
index 0000000..6365109
--- /dev/null
@@ -0,0 +1,54 @@
+From: Justus Winter <justus@g10code.com>
+Date: Wed, 25 Jan 2017 16:33:20 +0100
+Subject: gpg: Fix searching for mail addresses in keyrings.
+
+* g10/keyring.c (compare_name): Fix KEYDB_SEARCH_MODE_MAIL* searches
+in keyrings when the UID is a plain addr-spec.
+--
+Previously, 'gpg --list-key "<foo@example.org>"' failed if 1/ the
+keyring format is used and 2/ the key's UID is a plain addr-spec
+(cf. RFC2822 section 4.3), e.g. 'foo@example.org'.
+
+GnuPG-bug-id: 2930
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 3f4f20ee6eff052c88647b820d9ecfdbd8df0f40)
+---
+ g10/keyring.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/g10/keyring.c b/g10/keyring.c
+index f1281e98e..328290ed8 100644
+--- a/g10/keyring.c
++++ b/g10/keyring.c
+@@ -928,13 +928,27 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen)
+     else if (   mode == KEYDB_SEARCH_MODE_MAIL
+              || mode == KEYDB_SEARCH_MODE_MAILSUB
+              || mode == KEYDB_SEARCH_MODE_MAILEND) {
++        int have_angles = 1;
+       for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++)
+           ;
++      if (i == uidlen)
++        {
++          /* The UID is a plain addr-spec (cf. RFC2822 section 4.3).  */
++          have_angles = 0;
++          s = uid;
++          i = 0;
++        }
+       if (i < uidlen)  {
+-          /* skip opening delim and one char and look for the closing one*/
+-          s++; i++;
+-          for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++)
+-              ;
++          if (have_angles)
++            {
++              /* skip opening delim and one char and look for the closing one*/
++              s++; i++;
++              for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++)
++                ;
++            }
++          else
++            se = s + uidlen;
++
+           if (i < uidlen) {
+               i = se - s;
+               if (mode == KEYDB_SEARCH_MODE_MAIL) {
diff --git a/patches/0019-dirmngr-New-option-no-use-tor-and-internal-changes.patch b/patches/0019-dirmngr-New-option-no-use-tor-and-internal-changes.patch
new file mode 100644 (file)
index 0000000..f936685
--- /dev/null
@@ -0,0 +1,382 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Wed, 1 Feb 2017 17:54:14 +0100
+Subject: dirmngr: New option --no-use-tor and internal changes.
+
+* dirmngr/dns-stuff.c (disable_dns_tormode): New.
+* dirmngr/dirmngr.c (oNoUseTor): New const.
+(opts): New option --no-use-tor.
+(tor_mode): New var.
+(parse_rereadable_options): Change to use TOR_MODE.
+(dirmngr_use_tor): New.
+(set_tor_mode): Call disable_dns_tormode.  Implement oNoUseTor.
+* dirmngr/dirmngr.h (opt): Remove field 'use_tor'.  Replace all
+references by a call to dirmngr_use_tor().
+* dirmngr/server.c (cmd_getinfo): Distinguish between default and
+enforced TOR_MODE.
+--
+
+This patch replaces the global variable opt.use_tar by a function
+testing a file local mode flag.  This patch prepares for a
+use-tor-if-available mode.
+
+GnuPG-bug-id: 2935
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 7440119e729d3fdedda8a9b44b70f8959beea8d7)
+---
+ dirmngr/crlfetch.c         | 10 +++++-----
+ dirmngr/dirmngr.c          | 46 +++++++++++++++++++++++++++++++++++++++++++---
+ dirmngr/dirmngr.h          |  3 +--
+ dirmngr/dns-stuff.c        |  8 ++++++++
+ dirmngr/dns-stuff.h        |  1 +
+ dirmngr/ks-engine-finger.c |  2 +-
+ dirmngr/ks-engine-hkp.c    |  6 +++---
+ dirmngr/ks-engine-http.c   |  2 +-
+ dirmngr/ks-engine-ldap.c   |  6 +++---
+ dirmngr/ocsp.c             |  4 ++--
+ dirmngr/server.c           | 10 +++++++---
+ 11 files changed, 75 insertions(+), 23 deletions(-)
+
+diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
+index aa82137f7..337fe6e4d 100644
+--- a/dirmngr/crlfetch.c
++++ b/dirmngr/crlfetch.c
+@@ -198,7 +198,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+         err = http_open_document (&hd, url, NULL,
+                                   ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                                    |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0)
+-                                   |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                                   |(dirmngr_use_tor()? HTTP_FLAG_FORCE_TOR:0)
+                                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0)
+                                    ),
+                                   ctrl->http_proxy, NULL, NULL, NULL);
+@@ -292,7 +292,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+                      "LDAP");
+           err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+         }
+-      else if (opt.use_tor)
++      else if (dirmngr_use_tor ())
+         {
+           /* For now we do not support LDAP over Tor.  */
+           log_error (_("CRL access not possible due to Tor mode\n"));
+@@ -318,7 +318,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+ gpg_error_t
+ crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader)
+ {
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("CRL access not possible due to Tor mode\n"));
+@@ -350,7 +350,7 @@ crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader)
+ gpg_error_t
+ ca_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn)
+ {
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("CRL access not possible due to Tor mode\n"));
+@@ -377,7 +377,7 @@ gpg_error_t
+ start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context,
+                   strlist_t patterns, const ldap_server_t server)
+ {
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("CRL access not possible due to Tor mode\n"));
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 83356c94c..43e9cbd07 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -138,6 +138,7 @@ enum cmd_and_opt_values {
+   oHTTPWrapperProgram,
+   oIgnoreCertExtension,
+   oUseTor,
++  oNoUseTor,
+   oKeyServer,
+   oNameServer,
+   oDisableCheckOwnSocket,
+@@ -224,6 +225,7 @@ static ARGPARSE_OPTS opts[] = {
+                 N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
+   ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
++  ARGPARSE_s_n (oNoUseTor, "no-use-tor", "@"),
+   ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
+@@ -300,6 +302,16 @@ static volatile int shutdown_pending;
+ /* Flags to indicate that we shall not watch our own socket. */
+ static int disable_check_own_socket;
++/* Flag to control the Tor mode.  */
++static enum
++  { TOR_MODE_AUTO = 0,  /* Switch to NO or YES         */
++    TOR_MODE_NEVER,     /* Never use Tor.              */
++    TOR_MODE_NO,        /* Do not use Tor              */
++    TOR_MODE_YES,       /* Use Tor                     */
++    TOR_MODE_FORCE      /* Force using Tor             */
++  } tor_mode;
++
++
+ /* Counter for the active connections.  */
+ static int active_connections;
+@@ -475,7 +487,7 @@ set_debug (void)
+ static void
+ set_tor_mode (void)
+ {
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* Enable Tor mode and when called again force a new curcuit
+        * (e.g. on SIGHUP).  */
+@@ -486,6 +498,26 @@ set_tor_mode (void)
+           log_info ("(is your Libassuan recent enough?)\n");
+         }
+     }
++  else
++    disable_dns_tormode ();
++}
++
++
++/* Return true if Tor shall be used.  */
++int
++dirmngr_use_tor (void)
++{
++  if (tor_mode == TOR_MODE_AUTO)
++    {
++      /* FIXME: Figure out whether Tor is running.  */
++    }
++
++  if (tor_mode == TOR_MODE_FORCE)
++    return 2; /* Use Tor (using 2 to indicate force mode) */
++  else if (tor_mode == TOR_MODE_YES)
++    return 1; /* Use Tor */
++  else
++    return 0; /* Do not use Tor.  */
+ }
+@@ -548,7 +580,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+       FREE_STRLIST (opt.ignored_cert_extensions);
+       http_register_tls_ca (NULL);
+       FREE_STRLIST (opt.keyserver);
+-      /* Note: We do not allow resetting of opt.use_tor at runtime.  */
++      /* Note: We do not allow resetting of TOR_MODE_FORCE at runtime.  */
++      if (tor_mode != TOR_MODE_FORCE)
++        tor_mode = TOR_MODE_AUTO;
+       disable_check_own_socket = 0;
+       enable_standard_resolver (0);
+       set_dns_timeout (0);
+@@ -625,7 +659,13 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+       add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
+       break;
+-    case oUseTor: opt.use_tor = 1; break;
++    case oUseTor:
++      tor_mode = TOR_MODE_FORCE;
++      break;
++    case oNoUseTor:
++      if (tor_mode != TOR_MODE_FORCE)
++        tor_mode = TOR_MODE_NEVER;
++      break;
+     case oStandardResolver: enable_standard_resolver (1); break;
+     case oRecursiveResolver: enable_recursive_resolver (1); break;
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index fd80d7237..6a4fd003f 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -91,7 +91,6 @@ struct
+                                  program.  */
+   int running_detached; /* We are running in detached mode.  */
+-  int use_tor;          /* Tor mode has been enabled.  */
+   int allow_version_check; /* --allow-version-check is active.  */
+   int force;          /* Force loading outdated CRLs. */
+@@ -191,7 +190,7 @@ void dirmngr_init_default_ctrl (ctrl_t ctrl);
+ void dirmngr_deinit_default_ctrl (ctrl_t ctrl);
+ void dirmngr_sighup_action (void);
+ const char* dirmngr_get_current_socket_name (void);
+-
++int dirmngr_use_tor (void);
+ /*-- Various housekeeping functions.  --*/
+ void ks_hkp_reload (void);
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index ad19fc2ce..52f011a00 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -222,6 +222,14 @@ enable_dns_tormode (int new_circuit)
+ }
++/* Disable tor mode.  */
++void
++disable_dns_tormode (void)
++{
++  tor_mode = 0;
++}
++
++
+ /* Set verbosity and debug mode for this module. */
+ void
+ set_dns_verbose (int verbose, int debug)
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index 9eb97fd6a..9b8303c3b 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -120,6 +120,7 @@ int recursive_resolver_p (void);
+ /* Put this module eternally into Tor mode.  When called agained with
+  * NEW_CIRCUIT request a new TOR circuit for the next DNS query.  */
+ void enable_dns_tormode (int new_circuit);
++void disable_dns_tormode (void);
+ /* Change the default IP address of the nameserver to IPADDR.  The
+    address needs to be a numerical IP address and will be used for the
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index 114f2e9ac..811b72de4 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -83,7 +83,7 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+   *server++ = 0;
+   err = http_raw_connect (&http, server, 79,
+-                          ((opt.use_tor? HTTP_FLAG_FORCE_TOR : 0)
++                          ((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0)
+                            | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                           NULL);
+   if (err)
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 858cd2f26..be8b08333 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -285,7 +285,7 @@ tor_not_running_p (ctrl_t ctrl)
+ {
+   assuan_fd_t sock;
+-  if (!opt.use_tor)
++  if (!dirmngr_use_tor ())
+     return 0;
+   sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
+@@ -1088,7 +1088,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+                    /* fixme: AUTH */ NULL,
+                    (httpflags
+                     |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    |(dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+                     |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy,
+                    session,
+@@ -1245,7 +1245,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
+       break;
+     case GPG_ERR_EACCES:
+-      if (opt.use_tor)
++      if (dirmngr_use_tor ())
+         {
+           log_info ("(Tor configuration problem)\n");
+           dirmngr_status (ctrl, "WARNING", "tor_config_problem 0",
+diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
+index dbbf4bb79..69642ff98 100644
+--- a/dirmngr/ks-engine-http.c
++++ b/dirmngr/ks-engine-http.c
+@@ -88,7 +88,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+                    /* httphost */ NULL,
+                    /* fixme: AUTH */ NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+                     | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy,
+                    session,
+diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c
+index 6d520e98e..b7aa7cc65 100644
+--- a/dirmngr/ks-engine-ldap.c
++++ b/dirmngr/ks-engine-ldap.c
+@@ -850,7 +850,7 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
+   (void) ctrl;
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("LDAP access not possible due to Tor mode\n"));
+@@ -1033,7 +1033,7 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
+   (void) ctrl;
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("LDAP access not possible due to Tor mode\n"));
+@@ -1909,7 +1909,7 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri,
+   /* Elide a warning.  */
+   (void) ctrl;
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not support LDAP over Tor.  */
+       log_error (_("LDAP access not possible due to Tor mode\n"));
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index b46c78567..aff8e3288 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -132,7 +132,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+   (void)ctrl;
+-  if (opt.use_tor)
++  if (dirmngr_use_tor ())
+     {
+       /* For now we do not allow OCSP via Tor due to possible privacy
+          concerns.  Needs further research.  */
+@@ -174,7 +174,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+  once_more:
+   err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+-                    | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++                    | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+                     | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+                    ctrl->http_proxy, NULL, NULL, NULL);
+   if (err)
+diff --git a/dirmngr/server.c b/dirmngr/server.c
+index c9c4ad437..bca3a61e4 100644
+--- a/dirmngr/server.c
++++ b/dirmngr/server.c
+@@ -625,7 +625,7 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
+   else if (!strcmp (key, "honor-keyserver-url-used"))
+     {
+       /* Return an error if we are running in Tor mode.  */
+-      if (opt.use_tor)
++      if (dirmngr_use_tor ())
+         err = gpg_error (GPG_ERR_FORBIDDEN);
+     }
+   else
+@@ -2338,14 +2338,18 @@ cmd_getinfo (assuan_context_t ctx, char *line)
+     }
+   else if (!strcmp (line, "tor"))
+     {
+-      if (opt.use_tor)
++      int use_tor;
++
++      use_tor = dirmngr_use_tor ();
++      if (use_tor)
+         {
+           if (!is_tor_running (ctrl))
+             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
+           else
+             err = 0;
+           if (!err)
+-            assuan_set_okay_line (ctx, "- Tor mode is enabled");
++            assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
++                                  /**/              : "- Tor mode is enforced");
+         }
+       else
+         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
diff --git a/patches/0020-gpg-Remove-period-at-end-of-warning.patch b/patches/0020-gpg-Remove-period-at-end-of-warning.patch
new file mode 100644 (file)
index 0000000..247ff44
--- /dev/null
@@ -0,0 +1,26 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Fri, 6 Jan 2017 11:51:08 +0100
+Subject: gpg: Remove period at end of warning.
+
+* g10/tofu.c (tofu_register_encryption): Remove period at end of
+warning.
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+(cherry picked from commit 6f9d8a956b2ca0f5a0eb7acc656fc17af2f2de47)
+---
+ g10/tofu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 8d535fa6c..149a18545 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -3480,7 +3480,7 @@ tofu_register_encryption (ctrl_t ctrl,
+       if (! user_id_list)
+         log_info (_("WARNING: Encrypting to %s, which has no "
+-                    "non-revoked user ids.\n"),
++                    "non-revoked user ids\n"),
+                   keystr (pk->keyid));
+     }
diff --git a/patches/0021-gpg-Add-newline-to-output.patch b/patches/0021-gpg-Add-newline-to-output.patch
new file mode 100644 (file)
index 0000000..b79c546
--- /dev/null
@@ -0,0 +1,25 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Thu, 2 Feb 2017 11:00:51 +0100
+Subject: gpg: Add newline to output.
+
+* g10/tofu.c (ask_about_binding): Add newline to output.
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+(cherry picked from commit 74268180e5a3acc827f3a369f1fe5971f3bbe285)
+---
+ g10/tofu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 149a18545..9f5f40694 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -1969,7 +1969,7 @@ ask_about_binding (ctrl_t ctrl,
+       else if (!response[0])
+         /* Default to unknown.  Don't save it.  */
+         {
+-          tty_printf (_("Defaulting to unknown."));
++          tty_printf (_("Defaulting to unknown.\n"));
+           *policy = TOFU_POLICY_UNKNOWN;
+           break;
+         }
diff --git a/patches/0022-gpg-Only-print-out-TOFU-statistics-for-conflicts-in-.patch b/patches/0022-gpg-Only-print-out-TOFU-statistics-for-conflicts-in-.patch
new file mode 100644 (file)
index 0000000..d8b5d79
--- /dev/null
@@ -0,0 +1,187 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Thu, 2 Feb 2017 13:24:57 +0100
+Subject: gpg: Only print out TOFU statistics for conflicts in interactive mode
+
+* g10/tofu.c (get_trust): Add arguments POLICYP and CONFLICT_SETP.  If
+they are not NULL, return the policy and conflict set (if there is
+one), respectively.  Update callers.  If MAY_ASK is FALSE, don't print
+out the statistics.
+(tofu_register_encryption): If there is a conflict and we haven't yet
+printed the statistics about the conflicting bindings, do so now.
+(tofu_get_validity): Likewise.
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+GnuPG-bug-id: 2914
+(cherry picked from commit 027b81b35fe36692005b8dba22d9eb2db05e8c80)
+---
+ g10/tofu.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 69 insertions(+), 14 deletions(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 9f5f40694..fc03c5a7d 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2644,7 +2644,9 @@ get_policy (tofu_dbs_t dbs, PKT_public_key *pk,
+ static enum tofu_policy
+ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+            const char *fingerprint, const char *email,
+-         const char *user_id, int may_ask, time_t now)
++           const char *user_id, int may_ask,
++           enum tofu_policy *policyp, strlist_t *conflict_setp,
++           time_t now)
+ {
+   tofu_dbs_t dbs = ctrl->tofu.dbs;
+   int in_transaction = 0;
+@@ -2683,6 +2685,7 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+     if (tdb_keyid_is_utk (kid))
+       {
+         trust_level = TRUST_ULTIMATE;
++        policy = TOFU_POLICY_GOOD;
+         goto out;
+       }
+   }
+@@ -2690,7 +2693,8 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+   begin_transaction (ctrl, 0);
+   in_transaction = 1;
+-  policy = get_policy (dbs, pk, fingerprint, user_id, email, &conflict_set, now);
++  policy = get_policy (dbs, pk, fingerprint, user_id, email,
++                       &conflict_set, now);
+   if (policy == TOFU_POLICY_AUTO)
+     {
+       policy = opt.tofu_default_policy;
+@@ -2758,10 +2762,6 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+     }
+   else
+     {
+-      for (iter = conflict_set; iter; iter = iter->next)
+-        show_statistics (dbs, iter->d, email,
+-                         TOFU_POLICY_ASK, NULL, 1, now);
+-
+       trust_level = TRUST_UNDEFINED;
+     }
+@@ -2807,7 +2807,13 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+   if (in_transaction)
+     end_transaction (ctrl, 0);
+-  free_strlist (conflict_set);
++  if (policyp)
++    *policyp = policy;
++
++  if (conflict_setp)
++    *conflict_setp = conflict_set;
++  else
++    free_strlist (conflict_set);
+   return trust_level;
+ }
+@@ -3326,7 +3332,8 @@ tofu_register_signature (ctrl_t ctrl,
+       /* Make sure the binding exists and record any TOFU
+          conflicts.  */
+-      if (get_trust (ctrl, pk, fingerprint, email, user_id->d, 0, now)
++      if (get_trust (ctrl, pk, fingerprint, email, user_id->d,
++                     0, NULL, NULL, now)
+           == _tofu_GET_TRUST_ERROR)
+         {
+           rc = gpg_error (GPG_ERR_GENERAL);
+@@ -3492,11 +3499,13 @@ tofu_register_encryption (ctrl_t ctrl,
+   for (user_id = user_id_list; user_id; user_id = user_id->next)
+     {
+       char *email = email_from_user_id (user_id->d);
++      strlist_t conflict_set = NULL;
++      enum tofu_policy policy;
+       /* Make sure the binding exists and that we recognize any
+          conflicts.  */
+       int tl = get_trust (ctrl, pk, fingerprint, email, user_id->d,
+-                          may_ask, now);
++                          may_ask, &policy, &conflict_set, now);
+       if (tl == _tofu_GET_TRUST_ERROR)
+         {
+           /* An error.  */
+@@ -3505,6 +3514,28 @@ tofu_register_encryption (ctrl_t ctrl,
+           goto die;
+         }
++
++      /* If there is a conflict and MAY_ASK is true, we need to show
++       * the TOFU statistics for the current binding and the
++       * conflicting bindings.  But, if we are not in batch mode, then
++       * they have already been printed (this is required to make sure
++       * the information is available to the caller before cpr_get is
++       * called).  */
++      if (policy == TOFU_POLICY_ASK && may_ask && opt.batch)
++        {
++          strlist_t iter;
++
++          /* The conflict set should contain at least the current
++           * key.  */
++          log_assert (conflict_set);
++
++          for (iter = conflict_set; iter; iter = iter->next)
++            show_statistics (dbs, iter->d, email,
++                             TOFU_POLICY_ASK, NULL, 1, now);
++        }
++
++      free_strlist (conflict_set);
++
+       rc = gpgsql_stepx
+         (dbs->db, &dbs->s.register_encryption, NULL, NULL, &err,
+          "insert into encryptions\n"
+@@ -3681,11 +3712,13 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+   for (user_id = user_id_list; user_id; user_id = user_id->next, bindings ++)
+     {
+       char *email = email_from_user_id (user_id->d);
++      strlist_t conflict_set = NULL;
++      enum tofu_policy policy;
+       /* Always call get_trust to make sure the binding is
+          registered.  */
+       int tl = get_trust (ctrl, pk, fingerprint, email, user_id->d,
+-                          may_ask, now);
++                          may_ask, &policy, &conflict_set, now);
+       if (tl == _tofu_GET_TRUST_ERROR)
+         {
+           /* An error.  */
+@@ -3708,13 +3741,35 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+       if (may_ask && tl != TRUST_ULTIMATE && tl != TRUST_EXPIRED)
+         {
+-          enum tofu_policy policy =
+-            get_policy (dbs, pk, fingerprint, user_id->d, email, NULL, now);
++          /* If policy is ask, then we already printed out the
++           * conflict information in ask_about_binding or will do so
++           * in a moment.  */
++          if (policy != TOFU_POLICY_ASK)
++            need_warning |=
++              show_statistics (dbs, fingerprint, email, policy, NULL, 0, now);
++
++          /* If there is a conflict and MAY_ASK is true, we need to
++           * show the TOFU statistics for the current binding and the
++           * conflicting bindings.  But, if we are not in batch mode,
++           * then they have already been printed (this is required to
++           * make sure the information is available to the caller
++           * before cpr_get is called).  */
++          if (policy == TOFU_POLICY_ASK && opt.batch)
++            {
++              strlist_t iter;
+-          need_warning |=
+-            show_statistics (dbs, fingerprint, email, policy, NULL, 0, now);
++              /* The conflict set should contain at least the current
++               * key.  */
++              log_assert (conflict_set);
++
++              for (iter = conflict_set; iter; iter = iter->next)
++                show_statistics (dbs, iter->d, email,
++                                 TOFU_POLICY_ASK, NULL, 1, now);
++            }
+         }
++      free_strlist (conflict_set);
++
+       if (tl == TRUST_NEVER)
+         trust_level = TRUST_NEVER;
+       else if (tl == TRUST_EXPIRED)
diff --git a/patches/0023-gpg-If-there-is-a-TOFU-conflict-elide-the-too-few-me.patch b/patches/0023-gpg-If-there-is-a-TOFU-conflict-elide-the-too-few-me.patch
new file mode 100644 (file)
index 0000000..2ae2abe
--- /dev/null
@@ -0,0 +1,42 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Thu, 2 Feb 2017 13:26:17 +0100
+Subject: gpg: If there is a TOFU conflict, elide the too few message warning.
+
+* g10/tofu.c (tofu_get_validity): If there was a conflict, don't also
+print out a warning about too few messages.
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+(cherry picked from commit a08c781739e7561093f32b732c4991f2bd817ec2)
+---
+ g10/tofu.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index fc03c5a7d..41bdd5f30 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -3694,6 +3694,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+   int bindings = 0;
+   int bindings_valid = 0;
+   int need_warning = 0;
++  int had_conflict = 0;
+   dbs = opendbs (ctrl);
+   if (! dbs)
+@@ -3762,6 +3763,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+                * key.  */
+               log_assert (conflict_set);
++              had_conflict = 1;
+               for (iter = conflict_set; iter; iter = iter->next)
+                 show_statistics (dbs, iter->d, email,
+                                  TOFU_POLICY_ASK, NULL, 1, now);
+@@ -3794,7 +3796,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+       xfree (email);
+     }
+-  if (need_warning)
++  if (need_warning && ! had_conflict)
+     show_warning (fingerprint, user_id_list);
+  die:
diff --git a/patches/0024-gpg-Ensure-TOFU-bindings-associated-with-UTKs-are-re.patch b/patches/0024-gpg-Ensure-TOFU-bindings-associated-with-UTKs-are-re.patch
new file mode 100644 (file)
index 0000000..42d257e
--- /dev/null
@@ -0,0 +1,60 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Thu, 2 Feb 2017 14:24:38 +0100
+Subject: gpg: Ensure TOFU bindings associated with UTKs are registered as
+ usual
+
+* g10/tofu.c (get_trust): Call get_policy before short-circuiting the
+policy lookup for ultimately trusted keys to make sure the binding is
+added to the bindings table, if necessary.
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+GnuPG-bug-id: 2929
+(cherry picked from commit 769272ba87f282a69e8d5f9bb27c86e6bec4496b)
+---
+ g10/tofu.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 41bdd5f30..85347bb74 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2306,7 +2306,11 @@ build_conflict_set (tofu_dbs_t dbs,
+ /* Return the effective policy for the binding <FINGERPRINT, EMAIL>
+  * (email has already been normalized) and any conflict information in
+  * *CONFLICT_SETP, if CONFLICT_SETP is not NULL.  Returns
+- * _tofu_GET_POLICY_ERROR if an error occurs.  */
++ * _tofu_GET_POLICY_ERROR if an error occurs.
++ *
++ * This function registers the binding in the bindings table if it has
++ * not yet been registered.
++ */
+ static enum tofu_policy
+ get_policy (tofu_dbs_t dbs, PKT_public_key *pk,
+             const char *fingerprint, const char *user_id, const char *email,
+@@ -2677,6 +2681,14 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+               && _tofu_GET_TRUST_ERROR != TRUST_FULLY
+               && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE);
++  begin_transaction (ctrl, 0);
++  in_transaction = 1;
++
++  /* We need to call get_policy even if the key is ultimately trusted
++   * to make sure the binding has been registered.  */
++  policy = get_policy (dbs, pk, fingerprint, user_id, email,
++                       &conflict_set, now);
++
+   /* If the key is ultimately trusted, there is nothing to do.  */
+   {
+     u32 kid[2];
+@@ -2690,11 +2702,6 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+       }
+   }
+-  begin_transaction (ctrl, 0);
+-  in_transaction = 1;
+-
+-  policy = get_policy (dbs, pk, fingerprint, user_id, email,
+-                       &conflict_set, now);
+   if (policy == TOFU_POLICY_AUTO)
+     {
+       policy = opt.tofu_default_policy;
diff --git a/patches/0025-gpg-Don-t-assume-that-strtoul-interprets-as-0.patch b/patches/0025-gpg-Don-t-assume-that-strtoul-interprets-as-0.patch
new file mode 100644 (file)
index 0000000..b92a49f
--- /dev/null
@@ -0,0 +1,53 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Thu, 2 Feb 2017 15:48:45 +0100
+Subject: gpg: Don't assume that strtoul interprets "" as 0.
+
+* g10/tofu.c (show_statistics): If there are not records, return 0
+instead of NULL.
+
+--
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+GnuPG-bug-id: 2853
+
+According to SUSv3:
+
+  If the subject sequence is empty or does not have the expected form,
+  no conversion is performed
+  ...
+  If no conversion could be performed, 0 is returned and errno may be
+  set to [EINVAL].
+
+  http://pubs.opengroup.org/onlinepubs/007908799/xsh/strtol.html
+
+It appears that MacOS X sets errno to EINVAL, but glibc doesn't.
+Hence, we map NULL to 0 explicitly.
+
+(cherry picked from commit 407f5f9baea5591f148974240a87dfb43e5efef3)
+---
+ g10/tofu.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 85347bb74..449e921b6 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2983,7 +2983,8 @@ show_statistics (tofu_dbs_t dbs,
+   /* Get the signature stats.  */
+   rc = gpgsql_exec_printf
+     (dbs->db, strings_collect_cb, &strlist, &err,
+-     "select count (*), min (signatures.time), max (signatures.time)\n"
++     "select count (*), coalesce (min (signatures.time), 0),\n"
++     "  coalesce (max (signatures.time), 0)\n"
+      " from signatures\n"
+      " left join bindings on signatures.binding = bindings.oid\n"
+      " where fingerprint = %Q and email = %Q;",
+@@ -3036,7 +3037,8 @@ show_statistics (tofu_dbs_t dbs,
+   /* Get the encryption stats.  */
+   rc = gpgsql_exec_printf
+     (dbs->db, strings_collect_cb, &strlist, &err,
+-     "select count (*), min (encryptions.time), max (encryptions.time)\n"
++     "select count (*), coalesce (min (encryptions.time), 0),\n"
++     "  coalesce (max (encryptions.time), 0)\n"
+      " from encryptions\n"
+      " left join bindings on encryptions.binding = bindings.oid\n"
+      " where fingerprint = %Q and email = %Q;",
diff --git a/patches/0026-gpg-More-diagnostics-for-a-launched-pinentry.patch b/patches/0026-gpg-More-diagnostics-for-a-launched-pinentry.patch
new file mode 100644 (file)
index 0000000..7fe05e5
--- /dev/null
@@ -0,0 +1,81 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 3 Feb 2017 12:04:52 +0100
+Subject: gpg: More diagnostics for a launched pinentry.
+
+* agent/call-pinentry.c (start_pinentry): Call getinfo/ttyinfo.
+* g10/server.c (gpg_proxy_pinentry_notify): Simplify the output so
+that we do not change the code when adding new fields to
+PINENTRY_LAUNCHED.
+--
+
+This patch changes the --verbose output of gpg to show
+for example
+
+  gpg: pinentry launched (5228 gtk2 1.0.1-beta10 \
+  /dev/pts/4 xterm localhost:10.0)
+
+the used tty, its type, and the value of DISPLAY in addiion to the
+pid, flavor, and version.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 7052a0d77cf8f3a445b252a809d29be445788625)
+---
+ agent/call-pinentry.c |  6 +++++-
+ g10/server.c          | 19 ++++++++-----------
+ 2 files changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
+index fa00bf921..2bebee205 100644
+--- a/agent/call-pinentry.c
++++ b/agent/call-pinentry.c
+@@ -541,7 +541,7 @@ start_pinentry (ctrl_t ctrl)
+     }
+-  /* Ask the pinentry for its version and flavor and streo that as a
++  /* Ask the pinentry for its version and flavor and store that as a
+    * string in MB.  This information is useful for helping users to
+    * figure out Pinentry problems.  */
+   {
+@@ -555,6 +555,10 @@ start_pinentry (ctrl_t ctrl)
+     if (assuan_transact (entry_ctx, "GETINFO version",
+                          put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
+       put_membuf_str (&mb, "unknown");
++    put_membuf_str (&mb, " ");
++    if (assuan_transact (entry_ctx, "GETINFO ttyinfo",
++                         put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
++      put_membuf_str (&mb, "? ? ?");
+     put_membuf (&mb, "", 1);
+     flavor_version = get_membuf (&mb, NULL);
+   }
+diff --git a/g10/server.c b/g10/server.c
+index b89f0be69..e3a3bad22 100644
+--- a/g10/server.c
++++ b/g10/server.c
+@@ -770,18 +770,15 @@ gpg_server (ctrl_t ctrl)
+ gpg_error_t
+ gpg_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+ {
+-  if (opt.verbose)
+-    {
+-      char *linecopy = xtrystrdup (line);
+-      char *fields[4];
+-
+-      if (linecopy
+-          && split_fields (linecopy, fields, DIM (fields)) >= 4
+-          && !strcmp (fields[0], "PINENTRY_LAUNCHED"))
+-        log_info (_("pinentry launched (pid %s, flavor %s, version %s)\n"),
+-                  fields[1], fields[2], fields[3]);
++  const char *s;
+-      xfree (linecopy);
++  if (opt.verbose
++      && !strncmp (line, "PINENTRY_LAUNCHED", 17)
++      && (line[17]==' '||!line[17]))
++    {
++      for (s = line + 17; *s && spacep (s); s++)
++        ;
++      log_info (_("pinentry launched (%s)\n"), s);
+     }
+   if (!ctrl || !ctrl->server_local
diff --git a/patches/0027-doc-Clarify-abbreviation-of-help.patch b/patches/0027-doc-Clarify-abbreviation-of-help.patch
new file mode 100644 (file)
index 0000000..6d08d4b
--- /dev/null
@@ -0,0 +1,27 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sat, 4 Feb 2017 01:28:08 -0500
+Subject: doc: Clarify abbreviation of --help.
+
+* doc/gpg.texi: clarify abbreviation of --help.
+
+Debian-bug-id: 852979
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+(cherry picked from commit f2b276dffbe2435b17abf2b3c51684d3636f3f11)
+---
+ doc/gpg.texi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index 8e1a5e6fc..b79b78334 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -141,7 +141,8 @@ cannot abbreviate this command.
+ @itemx -h
+ @opindex help
+ Print a usage message summarizing the most useful command-line options.
+-Note that you cannot abbreviate this command.
++Note that you cannot arbitrarily abbreviate this command
++(though you can use its short form @option{-h}).
+ @item --warranty
+ @opindex warranty
diff --git a/patches/0028-scd-Backport-two-fixes-from-master.patch b/patches/0028-scd-Backport-two-fixes-from-master.patch
new file mode 100644 (file)
index 0000000..2193f94
--- /dev/null
@@ -0,0 +1,55 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Sun, 5 Feb 2017 08:34:08 +0900
+Subject: scd: Backport two fixes from master.
+
+* scd/app.c (app_new_register): Initialize by -1, so that it can detect
+an error correctly when card reader can't power-on the card initially.
+* scd/command.c (open_card_with_request): Release APP before the scan.
+
+--
+The first one-liner patch handles an erroneous card.
+
+The second patch handles the case when we repeatedly do
+signing/decrypting by a single session of scdaemon.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+---
+ scd/app.c     | 1 +
+ scd/command.c | 5 +++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/scd/app.c b/scd/app.c
+index b10a452d6..989e0c060 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -192,6 +192,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name)
+     }
+   app->slot = slot;
++  app->card_status = (unsigned int)-1;
+   if (npth_mutex_init (&app->lock, NULL))
+     {
+diff --git a/scd/command.c b/scd/command.c
+index 8c7ca20a6..0ae6d29aa 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -217,6 +217,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
+   gpg_error_t err;
+   unsigned char *serialno_bin = NULL;
+   size_t serialno_bin_len = 0;
++  app_t app = ctrl->app_ctx;
+   /* If we are already initialized for one specific application we
+      need to check that the client didn't requested a specific
+@@ -224,6 +225,10 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
+   if (apptype && ctrl->app_ctx)
+     return check_application_conflict (apptype, ctrl->app_ctx);
++  /* Re-scan USB devices.  Release APP, before the scan.  */
++  ctrl->app_ctx = NULL;
++  release_application (app);
++
+   if (serialno)
+     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
diff --git a/patches/0029-scd-Fix-use-case-of-PC-SC.patch b/patches/0029-scd-Fix-use-case-of-PC-SC.patch
new file mode 100644 (file)
index 0000000..a26360d
--- /dev/null
@@ -0,0 +1,93 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Mon, 13 Feb 2017 11:09:13 +0900
+Subject: scd: Fix use case of PC/SC.
+
+* scd/apdu.c (apdu_open_reader): Add an argument APP_EMPTY.
+When CCID driver fails to open, try PC/SC if APP is nothing.
+* scd/app.c (select_application): Supply arg if APP is nothing.
+
+--
+
+After scanning available card readers by CCID driver, scdaemon should
+try PC/SC service if no APP is registered yet.  Also, when the slot
+is allocated for PC/SC (ccid.handle==NULL), it should not call
+ccid_compare_BAI, otherwise scdaemon crashes.
+
+Debian-bug-id: 852702, 854005, 854595, 854616
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+---
+ scd/apdu.c | 14 +++++++++++---
+ scd/apdu.h |  2 +-
+ scd/app.c  |  2 +-
+ 3 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/scd/apdu.c b/scd/apdu.c
+index 38ebd2be5..149154cf3 100644
+--- a/scd/apdu.c
++++ b/scd/apdu.c
+@@ -3117,7 +3117,7 @@ apdu_open_one_reader (const char *portstr)
+ }
+ int
+-apdu_open_reader (struct dev_list *dl)
++apdu_open_reader (struct dev_list *dl, int app_empty)
+ {
+   int slot;
+@@ -3167,6 +3167,7 @@ apdu_open_reader (struct dev_list *dl)
+           /* Check identity by BAI against already opened HANDLEs.  */
+           for (slot = 0; slot < MAX_READER; slot++)
+             if (reader_table[slot].used
++                && reader_table[slot].ccid.handle
+                 && ccid_compare_BAI (reader_table[slot].ccid.handle, bai))
+               break;
+@@ -3191,12 +3192,19 @@ apdu_open_reader (struct dev_list *dl)
+             dl->idx++;
+         }
+-      slot = -1;
++      /* Not found.  Try one for PC/SC, only when it's the initial scan.  */
++      if (app_empty && dl->idx == dl->idx_max)
++        {
++          dl->idx++;
++          slot = apdu_open_one_reader (dl->portstr);
++        }
++      else
++        slot = -1;
+     }
+   else
+ #endif
+     { /* PC/SC readers.  */
+-      if (dl->idx == 0)
++      if (app_empty && dl->idx == 0)
+         {
+           dl->idx++;
+           slot = apdu_open_one_reader (dl->portstr);
+diff --git a/scd/apdu.h b/scd/apdu.h
+index 473def518..6751e8c9b 100644
+--- a/scd/apdu.h
++++ b/scd/apdu.h
+@@ -91,7 +91,7 @@ gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p);
+ void apdu_dev_list_finish (struct dev_list *l);
+ /* Note, that apdu_open_reader returns no status word but -1 on error. */
+-int apdu_open_reader (struct dev_list *l);
++int apdu_open_reader (struct dev_list *l, int app_empty);
+ int apdu_open_remote_reader (const char *portstr,
+                              const unsigned char *cookie, size_t length,
+                              int (*readfnc) (void *opaque,
+diff --git a/scd/app.c b/scd/app.c
+index 989e0c060..8fb0d4553 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -340,7 +340,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
+           int slot;
+           int sw;
+-          slot = apdu_open_reader (l);
++          slot = apdu_open_reader (l, !app_top);
+           if (slot < 0)
+             break;
diff --git a/patches/0030-scd-Fix-factory-reset.patch b/patches/0030-scd-Fix-factory-reset.patch
new file mode 100644 (file)
index 0000000..6a8822e
--- /dev/null
@@ -0,0 +1,367 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 17 Feb 2017 03:30:05 -0500
+Subject: scd: Fix factory-reset.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+
+Backport from master branch:
+
+    99d4dfe83
+    e2792813a
+    031e3fa7b
+
+Additionally, fix another bug when tested with 2.1.18-7 with PC/SC.
+---
+ scd/app-common.h |  3 +-
+ scd/app.c        | 86 ++++++++++++++++++++++++++++++++------------------------
+ scd/command.c    |  6 ++--
+ scd/scdaemon.c   | 51 ++++++++++++++++++++++++++++++---
+ scd/scdaemon.h   |  1 +
+ 5 files changed, 102 insertions(+), 45 deletions(-)
+
+diff --git a/scd/app-common.h b/scd/app-common.h
+index b979f54..c7a0575 100644
+--- a/scd/app-common.h
++++ b/scd/app-common.h
+@@ -54,6 +54,7 @@ struct app_ctx_s {
+   const char *apptype;
+   unsigned int card_version;
+   unsigned int card_status;
++  unsigned int reset_requested:1;
+   unsigned int require_get_status:1;
+   unsigned int did_chv1:1;
+   unsigned int force_chv1:1;   /* True if the card does not cache CHV1. */
+@@ -134,7 +135,7 @@ gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
+                                 int scan, const unsigned char *serialno_bin,
+                                 size_t serialno_bin_len);
+ char *get_supported_applications (void);
+-void release_application (app_t app);
++void release_application (app_t app, int locked_already);
+ gpg_error_t app_munge_serialno (app_t app);
+ gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
+                                     unsigned int flags);
+diff --git a/scd/app.c b/scd/app.c
+index 8fb0d45..3f3f3ef 100644
+--- a/scd/app.c
++++ b/scd/app.c
+@@ -136,40 +136,32 @@ check_application_conflict (const char *name, app_t app)
+ }
+-static void
+-release_application_internal (app_t app)
+-{
+-  if (!app->ref_count)
+-    log_bug ("trying to release an already released context\n");
+-
+-  --app->ref_count;
+-}
+-
+ gpg_error_t
+ app_reset (app_t app, ctrl_t ctrl, int send_reset)
+ {
+-  gpg_error_t err;
+-
+-  err = lock_app (app, ctrl);
+-  if (err)
+-    return err;
++  gpg_error_t err = 0;
+   if (send_reset)
+     {
+-      int sw = apdu_reset (app->slot);
++      int sw;
++
++      lock_app (app, ctrl);
++      sw = apdu_reset (app->slot);
+       if (sw)
+         err = gpg_error (GPG_ERR_CARD_RESET);
+-      /* Release the same application which is used by other sessions.  */
+-      send_client_notifications (app, 1);
++      app->reset_requested = 1;
++      unlock_app (app);
++
++      scd_kick_the_loop ();
++      gnupg_sleep (1);
+     }
+   else
+     {
+       ctrl->app_ctx = NULL;
+-      release_application_internal (app);
++      release_application (app, 0);
+     }
+-  unlock_app (app);
+   return err;
+ }
+@@ -370,6 +362,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
+         }
+       apdu_dev_list_finish (l);
++      scd_kick_the_loop ();
+     }
+   npth_mutex_lock (&app_list_lock);
+@@ -465,6 +458,8 @@ deallocate_app (app_t app)
+     }
+   xfree (app->serialno);
++
++  unlock_app (app);
+   xfree (app);
+ }
+@@ -474,7 +469,7 @@ deallocate_app (app_t app)
+    actually deferring the deallocation to allow for a later reuse by
+    a new connection. */
+ void
+-release_application (app_t app)
++release_application (app_t app, int locked_already)
+ {
+   if (!app)
+     return;
+@@ -484,9 +479,15 @@ release_application (app_t app)
+      is using the card - this way the PIN cache and other cached data
+      are preserved.  */
+-  lock_app (app, NULL);
+-  release_application_internal (app);
+-  unlock_app (app);
++  if (!locked_already)
++    lock_app (app, NULL);
++
++  if (!app->ref_count)
++    log_bug ("trying to release an already released context\n");
++
++  --app->ref_count;
++  if (!locked_already)
++    unlock_app (app);
+ }
+@@ -1023,11 +1024,16 @@ scd_update_reader_status_file (void)
+   npth_mutex_lock (&app_list_lock);
+   for (a = app_top; a; a = app_next)
+     {
++      unsigned int status;
++
++      lock_app (a, NULL);
+       app_next = a->next;
+-      if (a->require_get_status)
++
++      if (a->reset_requested)
++        status = 0;
++      else
+         {
+           int sw;
+-          unsigned int status;
+           sw = apdu_get_status (a->slot, 0, &status);
+           if (sw == SW_HOST_NO_READER)
+@@ -1038,24 +1044,30 @@ scd_update_reader_status_file (void)
+           else if (sw)
+             {
+               /* Get status failed.  Ignore that.  */
++              unlock_app (a);
+               continue;
+             }
++        }
++
++      if (a->card_status != status)
++        {
++          report_change (a->slot, a->card_status, status);
++          send_client_notifications (a, status == 0);
+-          if (a->card_status != status)
++          if (status == 0)
+             {
+-              report_change (a->slot, a->card_status, status);
+-              send_client_notifications (a, status == 0);
+-
+-              if (status == 0)
+-                {
+-                  log_debug ("Removal of a card: %d\n", a->slot);
+-                  apdu_close_reader (a->slot);
+-                  deallocate_app (a);
+-                }
+-              else
+-                a->card_status = status;
++              log_debug ("Removal of a card: %d\n", a->slot);
++              apdu_close_reader (a->slot);
++              deallocate_app (a);
++            }
++          else
++            {
++              a->card_status = status;
++              unlock_app (a);
+             }
+         }
++      else
++        unlock_app (a);
+     }
+   npth_mutex_unlock (&app_list_lock);
+ }
+diff --git a/scd/command.c b/scd/command.c
+index 0ae6d29..b17c4a1 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -227,7 +227,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
+   /* Re-scan USB devices.  Release APP, before the scan.  */
+   ctrl->app_ctx = NULL;
+-  release_application (app);
++  release_application (app, 0);
+   if (serialno)
+     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
+@@ -1492,7 +1492,7 @@ cmd_restart (assuan_context_t ctx, char *line)
+   if (app)
+     {
+       ctrl->app_ctx = NULL;
+-      release_application (app);
++      release_application (app, 0);
+     }
+   if (locked_session && ctrl->server_local == locked_session)
+     {
+@@ -1919,7 +1919,7 @@ send_client_notifications (app_t app, int removal)
+           {
+             sl->ctrl_backlink->app_ctx = NULL;
+             sl->card_removed = 1;
+-            release_application (app);
++            release_application (app, 1);
+           }
+         if (!sl->event_signal || !sl->assuan_ctx)
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index 74fed44..02f0e72 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -52,6 +52,7 @@
+ #include "ccid-driver.h"
+ #include "gc-opt-flags.h"
+ #include "asshelp.h"
++#include "exechelp.h"
+ #include "../common/init.h"
+ #ifndef ENAMETOOLONG
+@@ -224,7 +225,8 @@ static assuan_sock_nonce_t socket_nonce;
+    disabled but it won't perform any ticker specific actions. */
+ static int ticker_disabled;
+-
++/* FD to notify update of usb devices.  */
++static int notify_fd;
\f
+ static char *create_socket_name (char *standard_name);
+ static gnupg_fd_t create_server_socket (const char *name,
+@@ -1181,6 +1183,16 @@ start_connection_thread (void *arg)
+ }
++void
++scd_kick_the_loop (void)
++{
++  int ret;
++
++  /* Kick the select loop.  */
++  ret = write (notify_fd, "", 1);
++  (void)ret;
++}
++
+ /* Connection handler loop.  Wait for connection requests and spawn a
+    thread after accepting a connection.  LISTEN_FD is allowed to be -1
+    in which case this code will only do regular timeouts and handle
+@@ -1202,9 +1214,23 @@ handle_connections (int listen_fd)
+ #ifndef HAVE_W32_SYSTEM
+   int signo;
+ #endif
++  int pipe_fd[2];
++
++  ret = gnupg_create_pipe (pipe_fd);
++  if (ret)
++    {
++      log_error ("pipe creation failed: %s\n", gpg_strerror (ret));
++      return;
++    }
++  notify_fd = pipe_fd[1];
+   ret = npth_attr_init(&tattr);
+-  /* FIXME: Check error.  */
++  if (ret)
++    {
++      log_error ("npth_attr_init failed: %s\n", strerror (ret));
++      return;
++    }
++
+   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+ #ifndef HAVE_W32_SYSTEM
+@@ -1233,6 +1259,8 @@ handle_connections (int listen_fd)
+   for (;;)
+     {
++      int max_fd;
++
+       if (shutdown_pending)
+         {
+           if (active_connections == 0)
+@@ -1261,14 +1289,20 @@ handle_connections (int listen_fd)
+          thus a simple assignment is fine to copy the entire set.  */
+       read_fdset = fdset;
++      FD_SET (pipe_fd[0], &read_fdset);
++      if (nfd < pipe_fd[0])
++        max_fd = pipe_fd[0];
++      else
++        max_fd = nfd;
++
+ #ifndef HAVE_W32_SYSTEM
+-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
++      ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+       saved_errno = errno;
+       while (npth_sigev_get_pending(&signo))
+       handle_signal (signo);
+ #else
+-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
++      ret = npth_eselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+       saved_errno = errno;
+ #endif
+@@ -1284,6 +1318,13 @@ handle_connections (int listen_fd)
+       /* Timeout.  Will be handled when calculating the next timeout.  */
+       continue;
++      if (FD_ISSET (pipe_fd[0], &read_fdset))
++        {
++          char buf[256];
++
++          ret = read (pipe_fd[0], buf, sizeof buf);
++        }
++
+       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
+       {
+           ctrl_t ctrl;
+@@ -1322,6 +1363,8 @@ handle_connections (int listen_fd)
+       }
+     }
++  close (pipe_fd[0]);
++  close (pipe_fd[1]);
+   cleanup ();
+   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
+   npth_attr_destroy (&tattr);
+diff --git a/scd/scdaemon.h b/scd/scdaemon.h
+index d0bc98e..fcab648 100644
+--- a/scd/scdaemon.h
++++ b/scd/scdaemon.h
+@@ -125,6 +125,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
+ void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
+ void scd_update_reader_status_file (void);
+ void send_client_notifications (app_t app, int removal);
++void scd_kick_the_loop (void);
+ #endif /*SCDAEMON_H*/
diff --git a/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch b/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch
new file mode 100644 (file)
index 0000000..e22f218
--- /dev/null
@@ -0,0 +1,66 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sat, 4 Feb 2017 01:23:32 -0500
+Subject: gpg: Fix aliases --list-key, --list-sig, and --check-sig.
+
+* g10/gpg.c (opts): Define commands with ARGPARSE_c
+instead of ARGPARSE_s_n.
+
+--
+
+These three entries are commands, but they're being treated as a
+string-based option for some reason.  However, if you try to use them
+concurrently with another command like --clearsign, you'll get "gpg:
+conflicting commands".
+
+Furthermore, because they're marked as options, their flags differ
+from the commands that they alias, they cause ambiguity in
+abbreviation (e.g. try "gpg --list-ke") which should have been fixed
+by 7249ab0f95d1f6cb8ee61eefedc79801bb56398f.
+
+Marking them explicitly as commands for argparse should be more
+accurate and should resolve the abbreviation ambiguity issue.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+gpg: fix aliases --list-key, --list-sig, and --check-sig.
+
+* g10/gpg.c: ARGPARSE_OPTS opts[]: define commands with ARGPARSE_c
+instead of ARGPARSE_s_n.
+
+--
+
+These three entries are commands, but they're being treated as a
+string-based option for some reason.  However, if you try to use them
+concurrently with another command like --clearsign, you'll get "gpg:
+conflicting commands".
+
+Furthermore, because they're marked as options, their flags differ
+from the commands that they alias, they cause ambiguity in
+abbreviation (e.g. try "gpg --list-ke") which should have been fixed
+by 7249ab0f95d1f6cb8ee61eefedc79801bb56398f.
+
+Marking them explicitly as commands for argparse should be more
+accurate and should resolve the abbreviation ambiguity issue.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+(cherry picked from commit f31120a5aa40b6e4e89d41d1d5d34e0f7da173b4)
+---
+ g10/gpg.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index f9039ae..e280c22 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -728,9 +728,9 @@ static ARGPARSE_OPTS opts[] = {
+   ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
+   ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
+   ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
+-  ARGPARSE_s_n (aListKeys, "list-key", "@"),   /* alias */
+-  ARGPARSE_s_n (aListSigs, "list-sig", "@"),   /* alias */
+-  ARGPARSE_s_n (aCheckKeys, "check-sig", "@"), /* alias */
++  ARGPARSE_c (aListKeys, "list-key", "@"),   /* alias */
++  ARGPARSE_c (aListSigs, "list-sig", "@"),   /* alias */
++  ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */
+   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
+   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
+   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
diff --git a/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch b/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
new file mode 100644 (file)
index 0000000..bf9691b
--- /dev/null
@@ -0,0 +1,228 @@
+From: Justus Winter <justus@g10code.com>
+Date: Wed, 8 Feb 2017 13:49:41 +0100
+Subject: gpg,common: Make sure that all fd given are valid.
+
+* common/sysutils.c (gnupg_fd_valid): New function.
+* common/sysutils.h (gnupg_fd_valid): New declaration.
+* common/logging.c (log_set_file): Use the new function.
+* g10/cpr.c (set_status_fd): Likewise.
+* g10/gpg.c (main): Likewise.
+* g10/keylist.c (read_sessionkey_from_fd): Likewise.
+* g10/passphrase.c (set_attrib_fd): Likewise.
+* tests/openpgp/Makefile.am (XTESTS): Add the new test.
+* tests/openpgp/issue2941.scm: New file.
+--
+
+Consider a situation where the user passes "--status-fd 3" but file
+descriptor 3 is not open.
+
+During the course of executing the rest of the commands, it's possible
+that gpg itself will open some files, and file descriptor 3 will get
+allocated.
+
+In this situation, the status information will be appended directly to
+whatever file happens to have landed on fd 3 (the trustdb? the
+keyring?).
+
+This is a potential data destruction issue for all writable file
+descriptor options:
+
+   --status-fd
+   --attribute-fd
+   --logger-fd
+
+It's also a potential issue for readable file descriptor options, but
+the risk is merely weird behavior, and not data corruption:
+
+   --override-session-key-fd
+   --passphrase-fd
+   --command-fd
+
+Fixes this by checking whether the fd is valid early on before using
+it.
+
+GnuPG-bug-id: 2941
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 6823ed46584e753de3aba48a00ab738ab009a860)
+---
+ common/logging.c            |  3 +++
+ common/sysutils.c           | 11 +++++++++++
+ common/sysutils.h           |  1 +
+ g10/cpr.c                   |  3 +++
+ g10/gpg.c                   |  5 +++++
+ g10/keylist.c               |  3 +++
+ g10/passphrase.c            |  3 +++
+ tests/openpgp/Makefile.am   |  4 ++--
+ tests/openpgp/issue2941.scm | 34 ++++++++++++++++++++++++++++++++++
+ 9 files changed, 65 insertions(+), 2 deletions(-)
+ create mode 100755 tests/openpgp/issue2941.scm
+
+diff --git a/common/logging.c b/common/logging.c
+index 8c70742..ac13053 100644
+--- a/common/logging.c
++++ b/common/logging.c
+@@ -570,6 +570,9 @@ log_set_file (const char *name)
+ void
+ log_set_fd (int fd)
+ {
++  if (! gnupg_fd_valid (fd))
++    log_fatal ("logger-fd is invalid: %s\n", strerror (errno));
++
+   set_file_fd (NULL, fd);
+ }
+diff --git a/common/sysutils.c b/common/sysutils.c
+index e67420f..a796677 100644
+--- a/common/sysutils.c
++++ b/common/sysutils.c
+@@ -1281,3 +1281,14 @@ gnupg_get_socket_name (int fd)
+   return name;
+ }
+ #endif /*!HAVE_W32_SYSTEM*/
++
++/* Check whether FD is valid.  */
++int
++gnupg_fd_valid (int fd)
++{
++  int d = dup (fd);
++  if (d < 0)
++    return 0;
++  close (d);
++  return 1;
++}
+diff --git a/common/sysutils.h b/common/sysutils.h
+index a9316d7..ecd9f84 100644
+--- a/common/sysutils.h
++++ b/common/sysutils.h
+@@ -72,6 +72,7 @@ int  gnupg_setenv (const char *name, const char *value, int overwrite);
+ int  gnupg_unsetenv (const char *name);
+ char *gnupg_getcwd (void);
+ char *gnupg_get_socket_name (int fd);
++int gnupg_fd_valid (int fd);
+ gpg_error_t gnupg_inotify_watch_socket (int *r_fd, const char *socket_name);
+ int gnupg_inotify_has_name (int fd, const char *name);
+diff --git a/g10/cpr.c b/g10/cpr.c
+index 0133cad..4984e89 100644
+--- a/g10/cpr.c
++++ b/g10/cpr.c
+@@ -107,6 +107,9 @@ set_status_fd (int fd)
+   if (fd == -1)
+     return;
++  if (! gnupg_fd_valid (fd))
++    log_fatal ("status-fd is invalid: %s\n", strerror (errno));
++
+   if (fd == 1)
+     statusfp = es_stdout;
+   else if (fd == 2)
+diff --git a/g10/gpg.c b/g10/gpg.c
+index e280c22..66a2055 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -3079,6 +3079,8 @@ main (int argc, char **argv)
+         case oCommandFD:
+             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
++          if (! gnupg_fd_valid (opt.command_fd))
++            log_fatal ("command-fd is invalid: %s\n", strerror (errno));
+             break;
+         case oCommandFile:
+             opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
+@@ -5293,6 +5295,9 @@ read_sessionkey_from_fd (int fd)
+   int i, len;
+   char *line;
++  if (! gnupg_fd_valid (fd))
++    log_fatal ("override-session-key-fd is invalid: %s\n", strerror (errno));
++
+   for (line = NULL, i = len = 100; ; i++ )
+     {
+       if (i >= len-1 )
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 4fe1e40..abdcb9f 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -1900,6 +1900,9 @@ set_attrib_fd (int fd)
+   if (fd == -1)
+     return;
++  if (! gnupg_fd_valid (fd))
++    log_fatal ("attribute-fd is invalid: %s\n", strerror (errno));
++
+ #ifdef HAVE_DOSISH_SYSTEM
+   setmode (fd, O_BINARY);
+ #endif
+diff --git a/g10/passphrase.c b/g10/passphrase.c
+index fb4ec4c..37abc0f 100644
+--- a/g10/passphrase.c
++++ b/g10/passphrase.c
+@@ -166,6 +166,9 @@ read_passphrase_from_fd( int fd )
+   int i, len;
+   char *pw;
++  if (! gnupg_fd_valid (fd))
++    log_fatal ("passphrase-fd is invalid: %s\n", strerror (errno));
++
+   if ( !opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
+     { /* Not used but we have to do a dummy read, so that it won't end
+          up at the begin of the message if the quite usual trick to
+diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
+index 05341fb..377a2ed 100644
+--- a/tests/openpgp/Makefile.am
++++ b/tests/openpgp/Makefile.am
+@@ -95,12 +95,12 @@ XTESTS = \
+       issue2015.scm \
+       issue2346.scm \
+       issue2417.scm \
+-      issue2419.scm
++      issue2419.scm \
++      issue2941.scm
+ # Fixme: gpgconf.scm does not yet work with make distcheck.
+ #     gpgconf.scm
+-
+ # XXX: Currently, one cannot override automake's 'check' target.  As a
+ # workaround, we avoid defining 'TESTS', thus automake will not emit
+ # the 'check' target.  For extra robustness, we merely define a
+diff --git a/tests/openpgp/issue2941.scm b/tests/openpgp/issue2941.scm
+new file mode 100755
+index 0000000..d7220e0
+--- /dev/null
++++ b/tests/openpgp/issue2941.scm
+@@ -0,0 +1,34 @@
++#!/usr/bin/env gpgscm
++
++;; Copyright (C) 2017 g10 Code GmbH
++;;
++;; This file is part of GnuPG.
++;;
++;; GnuPG is free software; you can redistribute it and/or modify
++;; it under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 3 of the License, or
++;; (at your option) any later version.
++;;
++;; GnuPG is distributed in the hope that it will be useful,
++;; but WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++;; GNU General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with this program; if not, see <http://www.gnu.org/licenses/>.
++
++(load (with-path "defs.scm"))
++(setup-legacy-environment)
++
++(define (check-failure options)
++  (let ((command `(,@gpg ,@options)))
++    (catch '()
++         (call-check command)
++         (error "Expected an error, but got none when executing" command))))
++
++(for-each-p
++ "Checking invocation with invalid file descriptors (issue2941)."
++ (lambda (option)
++   (check-failure `(,(string-append "--" option "=23") --sign gpg.conf)))
++ '("status-fd" "attribute-fd" "logger-fd"
++   "override-session-key-fd" "passphrase-fd" "command-fd"))
diff --git a/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch b/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch
new file mode 100644 (file)
index 0000000..52f4d36
--- /dev/null
@@ -0,0 +1,36 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Wed, 8 Feb 2017 12:05:08 -0500
+Subject: common: Avoid warning about implicit declaration of gnupg_fd_valid.
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+* common/logging.c: Add #include "sysutils.h".
+
+--
+
+Without this, we see:
+
+logging.c:573:9: warning: implicit declaration of function \
+  â€˜gnupg_fd_valid’ [-Wimplicit-function-declaration]
+   if (! gnupg_fd_valid (fd))
+         ^~~~~~~~~~~~~~
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+(cherry picked from commit 8810314e377a9cb6612150a57cf99260ed0bb9f6)
+---
+ common/logging.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/common/logging.c b/common/logging.c
+index ac13053..670affb 100644
+--- a/common/logging.c
++++ b/common/logging.c
+@@ -61,6 +61,7 @@
+ #include "i18n.h"
+ #include "common-defs.h"
+ #include "logging.h"
++#include "sysutils.h"
+ #ifdef HAVE_W32_SYSTEM
+ # define S_IRGRP S_IRUSR
diff --git a/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch b/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch
new file mode 100644 (file)
index 0000000..3665e3b
--- /dev/null
@@ -0,0 +1,51 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 10 Feb 2017 17:16:07 +0100
+Subject: gpg: Fix memory leak in the error case of signature creation.
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+* g10/sign.c (write_signature_packets): Free SIG.  Also replace
+xcalloc by xtrycalloc.
+--
+
+If do_sign fails SIG was not released.  Note that in the good case SIG
+is transferred to PKT and freed by free_packet.
+
+Reported-by: Stephan Müller
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 5996c7bf99f3a681393fd9589276399ebc956cff)
+---
+ g10/sign.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/g10/sign.c b/g10/sign.c
+index acc894c..ff099b3 100644
+--- a/g10/sign.c
++++ b/g10/sign.c
+@@ -686,7 +686,10 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
+       pk = sk_rover->pk;
+       /* Build the signature packet.  */
+-      sig = xmalloc_clear (sizeof *sig);
++      sig = xtrycalloc (1, sizeof *sig);
++      if (!sig)
++        return gpg_error_from_syserror ();
++
+       if (duration || opt.sig_policy_url
+           || opt.sig_notations || opt.sig_keyserver_url)
+         sig->version = 4;
+@@ -731,8 +734,12 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
+             print_status_sig_created (pk, sig, status_letter);
+           free_packet (&pkt);
+           if (rc)
+-            log_error ("build signature packet failed: %s\n", gpg_strerror (rc));
++            log_error ("build signature packet failed: %s\n",
++                       gpg_strerror (rc));
+       }
++      else
++        xfree (sig);
++
+       if (rc)
+         return rc;
+     }
diff --git a/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch b/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch
new file mode 100644 (file)
index 0000000..6172346
--- /dev/null
@@ -0,0 +1,32 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 13 Feb 2017 13:09:51 +0100
+Subject: gpg: Print a warning if no command has been given.
+
+* g10/gpg.c (main): Print in the default case.
+--
+
+GnuPG-bug-id: 2943
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 810adfd47801fc01e45fb71af9f05c91f7890cdb)
+---
+ g10/gpg.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 66a2055..0c5a167 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -4894,8 +4894,12 @@ main (int argc, char **argv)
+ #endif /*USE_TOFU*/
+       break;
+-      case aListPackets:
+       default:
++        if (!opt.quiet)
++          log_info (_("WARNING: no command supplied."
++                      "  Trying to guess what you mean ...\n"));
++        /*FALLTHU*/
++      case aListPackets:
+       if( argc > 1 )
+           wrong_args("[filename]");
+       /* Issue some output for the unix newbie */
diff --git a/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch b/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch
new file mode 100644 (file)
index 0000000..fa39a09
--- /dev/null
@@ -0,0 +1,40 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 13 Feb 2017 19:38:53 +0100
+Subject: gpgconf: No ENOENT warning with --change-options et al.
+
+* tools/gpgconf-comp.c (retrieve_options_from_program): Check ERRNO
+before printing a warning.
+--
+
+It is common that a conf files does not exist - thus we should not
+print a warning.
+
+GnuPG-bug-id: 2944
+
+BTW: The error messages in gpgconf should be reworked to match those
+of the other components.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 30dac0486b6357e84fbe79c612eea940b654e4d1)
+---
+ tools/gpgconf-comp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 180fd65..a0d9659 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -2163,8 +2163,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
+   config = es_fopen (config_filename, "r");
+   if (!config)
+-    gc_error (0, errno, "warning: can not open config file %s",
+-            config_filename);
++    {
++      if (errno != ENOENT)
++        gc_error (0, errno, "warning: can not open config file %s",
++                  config_filename);
++    }
+   else
+     {
+       while ((length = es_read_line (config, &line, &line_len, NULL)) > 0)
diff --git a/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch b/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch
new file mode 100644 (file)
index 0000000..b91abd7
--- /dev/null
@@ -0,0 +1,60 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 13 Feb 2017 20:09:26 +0100
+Subject: dirmngr: Do a DNS lookup even if it is missing from nsswitch.conf.
+
+* dirmngr/dns-stuff.c (libdns_init): Do not print error message for a
+missing nsswitch.conf.  Make sure that tehre is a DNS entry.
+--
+
+GnuPG-bug-id: 2948
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit dee026d761ae3d7594c3dbc5b3fa842df53cc189)
+---
+ dirmngr/dns-stuff.c | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 52f011a..bc2e071 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -498,12 +498,10 @@ libdns_init (void)
+         (dns_nssconf_loadpath (ld.resolv_conf, fname));
+       if (err)
+         {
+-          log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err));
+-          /* not fatal, nsswitch.conf is not used on all systems; assume
+-           * classic behavior instead.  Our dns library states "bf" which tries
+-           * DNS then Files, which is not classic; FreeBSD
+-           * /usr/src/lib/libc/net/gethostnamadr.c defines default_src[] which
+-           * is Files then DNS, which is. */
++          /* This is not a fatal error: nsswitch.conf is not used on
++           * all systems; assume classic behavior instead.  */
++          if (gpg_err_code (err) != GPG_ERR_ENOENT)
++            log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err));
+           if (opt_debug)
+             log_debug ("dns: fallback resolution order, files then DNS\n");
+           ld.resolv_conf->lookup[0] = 'f';
+@@ -511,6 +509,23 @@ libdns_init (void)
+           ld.resolv_conf->lookup[2] = '\0';
+           err = GPG_ERR_NO_ERROR;
+         }
++      else if (!strchr (ld.resolv_conf->lookup, 'b'))
++        {
++          /* No DNS resulution type found in the list.  This might be
++           * due to systemd based systems which allow for custom
++           * keywords which are not known to us and thus we do not
++           * know whether DNS is wanted or not.  Becuase DNS is
++           * important for our infrastructure, we forcefully append
++           * DNS to the end of the list.  */
++          if (strlen (ld.resolv_conf->lookup)+2 < sizeof ld.resolv_conf->lookup)
++            {
++              if (opt_debug)
++                log_debug ("dns: appending DNS to resolution order\n");
++              strcat (ld.resolv_conf->lookup, "b");
++            }
++          else
++            log_error ("failed to append DNS to resolution order\n");
++        }
+ #endif /* Unix */
+     }
diff --git a/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch b/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch
new file mode 100644 (file)
index 0000000..9ba738b
--- /dev/null
@@ -0,0 +1,162 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 14 Feb 2017 10:55:13 +0100
+Subject: gpg: Make --export-ssh-key work for the primary key.
+
+* g10/export.c (export_ssh_key): Also check the primary key.
+--
+
+If no suitable subkey was found for export, we now check whether the
+primary key is suitable for export and export this one.  Without this
+change it was only possible to export the primary key by using the '!'
+suffix in the key specification.
+
+Also added a sample key for testing this.
+
+GnuPG-bug-id: 2957
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit b456e5be91dc064fc9509ea86edab113721ed299)
+---
+ g10/export.c                                       | 42 ++++++++++++++++++++++
+ tests/openpgp/samplekeys/README                    |  2 ++
+ .../samplekeys/rsa-primary-auth-only.pub.asc       | 23 ++++++++++++
+ .../samplekeys/rsa-primary-auth-only.sec.asc       | 38 ++++++++++++++++++++
+ 4 files changed, 105 insertions(+)
+ create mode 100644 tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc
+ create mode 100644 tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc
+
+diff --git a/g10/export.c b/g10/export.c
+index f354ca0..8668126 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -2208,6 +2208,48 @@ export_ssh_key (ctrl_t ctrl, const char *userid)
+               latest_key = node;
+             }
+         }
++
++      /* If no subkey was suitable check the primary key.  */
++      if (!latest_key
++          && (node = keyblock) && node->pkt->pkttype == PKT_PUBLIC_KEY)
++        {
++          pk = node->pkt->pkt.public_key;
++          if (DBG_LOOKUP)
++            log_debug ("\tchecking primary key %08lX\n",
++                       (ulong) keyid_from_pk (pk, NULL));
++          if (!(pk->pubkey_usage & PUBKEY_USAGE_AUTH))
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key not usable for authentication\n");
++            }
++          else if (!pk->flags.valid)
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key not valid\n");
++            }
++          else if (pk->flags.revoked)
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key has been revoked\n");
++            }
++          else if (pk->has_expired)
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key has expired\n");
++            }
++          else if (pk->timestamp > curtime && !opt.ignore_valid_from)
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key not yet valid\n");
++            }
++          else
++            {
++              if (DBG_LOOKUP)
++                log_debug ("\tprimary key is fine\n");
++              latest_date = pk->timestamp;
++              latest_key = node;
++            }
++        }
+     }
+   if (!latest_key)
+diff --git a/tests/openpgp/samplekeys/README b/tests/openpgp/samplekeys/README
+index 29524d5..6f2399f 100644
+--- a/tests/openpgp/samplekeys/README
++++ b/tests/openpgp/samplekeys/README
+@@ -17,3 +17,5 @@ E657FB607BB4F21C90BB6651BC067AF28BC90111.asc Key with subkeys (no protection)
+ rsa-rsa-sample-1.asc   RSA+RSA sample key (no passphrase)
+ ed25519-cv25519-sample-1.asc  Ed25519+CV25519 sample key (no passphrase)
+ silent-running.asc     Collection of sample secret keys (no passphrases)
++rsa-primary-auth-only.pub.asc  rsa2408 primary only, usage: cert,auth
++rsa-primary-auth-only.sec.asc  Ditto but the secret keyblock.
+diff --git a/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc b/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc
+new file mode 100644
+index 0000000..f34999e
+--- /dev/null
++++ b/tests/openpgp/samplekeys/rsa-primary-auth-only.pub.asc
+@@ -0,0 +1,23 @@
++pub   rsa2048 2017-02-14 [CA]
++      F74B4029E6906D12EBDA8EE3BD7744900FDABC8D
++      Keygrip = AB1BB1843677AF7CC4D6C14444320C3FF4147E98
++uid           [ unknown] ssh://host.example.net
++
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++
++mQENBFiizWgBCACi28riS0AaC7UvXaZfoafEvcXq/MAq6akiowPf3eY4zz5DkBPf
++Ep3kGuDMAFqULvchIt9vpg719Zar/Xldi+UG+/KsDz+TT5k+nP6CwvBHbAXXtISv
++S51TKKnTFpvjcgJc1BMFN0pGf7JnZx1QfRfsZO2BvS4qVzYCWbSS9hlpMq4aIgOc
++ERBMsZYMPnI4ijbXysksecDC91kbJH0q5j8aGir5sDyrDwfVLp0SUAubRFU5gXuZ
++SEv9QmeV7XoXKXzk9KEYy7GUgoAJzabvbF0rVXqd3DE8KFkwK7rKBe8sGC04DWlK
++j/sHJcAfMSqCi/SZyYpO+FSfnB+uJ1BNc05hABEBAAG0FnNzaDovL2hvc3QuZXhh
++bXBsZS5uZXSJAU4EEwEIADgWIQT3S0Ap5pBtEuvajuO9d0SQD9q8jQUCWKLNaAIb
++IQULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRC9d0SQD9q8jZBrB/41MJWUeclV
++tM60+ydPNgUJwyRXpKdLIm/AtM1zOijlFkwsaMmzbFSFJJX98HGASHdU5OpL2Lv3
++1NNDNMbUuFumApVrLzJUBugFRb+8/uY7H3Z0/YKQ9g9OC3z7+uqFFv/+/wA+VdYX
++Zy6uim8E4OlJ41S68fQcMiTxbLTCDkvBbpf505t6JhNqF6JB+SBFQJXvRqjoydXf
++dyoiDz9N1V0ERzmGEiPewvHg2zWcVia07NGhxN3slQ3klOfYJQ8Ye72feNq1zKCy
++AyU3X8fL10XKWooCAU+t4hR5hXYxYTSZse5q0FHZ38Lt9c3ApMSZ2+ueeOtGbsH9
++kV8icGkI6KXp
++=zMXp
++-----END PGP PUBLIC KEY BLOCK-----
+diff --git a/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc b/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc
+new file mode 100644
+index 0000000..9d72421
+--- /dev/null
++++ b/tests/openpgp/samplekeys/rsa-primary-auth-only.sec.asc
+@@ -0,0 +1,38 @@
++sec   rsa2048 2017-02-14 [CA]
++      F74B4029E6906D12EBDA8EE3BD7744900FDABC8D
++      Keygrip = AB1BB1843677AF7CC4D6C14444320C3FF4147E98
++uid           [ unknown] ssh://host.example.net
++
++Passprase: none
++
++-----BEGIN PGP PRIVATE KEY BLOCK-----
++
++lQOYBFiizWgBCACi28riS0AaC7UvXaZfoafEvcXq/MAq6akiowPf3eY4zz5DkBPf
++Ep3kGuDMAFqULvchIt9vpg719Zar/Xldi+UG+/KsDz+TT5k+nP6CwvBHbAXXtISv
++S51TKKnTFpvjcgJc1BMFN0pGf7JnZx1QfRfsZO2BvS4qVzYCWbSS9hlpMq4aIgOc
++ERBMsZYMPnI4ijbXysksecDC91kbJH0q5j8aGir5sDyrDwfVLp0SUAubRFU5gXuZ
++SEv9QmeV7XoXKXzk9KEYy7GUgoAJzabvbF0rVXqd3DE8KFkwK7rKBe8sGC04DWlK
++j/sHJcAfMSqCi/SZyYpO+FSfnB+uJ1BNc05hABEBAAEAB/wN0yan4HIdQ+fU5i2c
++v0uknI9+i9zW8mWUi84Puks0K15CZ1VTLHC8JQ6hgq4twhw3HeS7GkJO3X2K4BuQ
++tggdIv94slqtQKaQ9XbNgYraz/AMXZtIiNy0FdGaGmM6rY+ccwxM9w1BFXn+48v4
++lzCUCq/2wX53wwDSC5dpRPw8km6+uksFh3dfY8kgfpjU/lUCCwQiooYrQhut1EGB
++lDLRHp2ntC1xsnowtdPzluIHFetFSnmn2ehGqXqXtXLAMF0HOirViO5dUVMuj2Pe
++ra3IYVYANYK/7FEsRXHxU6aB/BSnubb5EiqB1Oi1JNyMrvYZnRsoRUaMjVgjA4ne
++RwD5BADBZN2USYGgciDVh7kvTbrtS1igPhoe3xUUQsM0hVIEwBzG4A4pWXznIQyW
++BziVTnRNp953EbHJIYdn7vmJzdiRKI+hOvrF8dfvVsq+fp4pWxrc+zrC6qptpo6H
++IhkHWUpyfIPuTI8d+glIUIuDshwKau0UZ8VDTOYuRYEZX9PrAwQA15RdS3geA1cf
++UK/ZaKs5VnohcLtEE/z3BlvlQaEdHxSQJSLYC4By7zKVOFZlZkHk36IPikwYNTgc
++P57aLe7rwNZqPhADue1ZN6Ypetvrek55lAYL9XoPJ/mWaYz6oDWWW8vHYqEPk8OL
++N8/8a6DhK0iydXi9/ztHQllbOt0EUcsEAJBjX84FgIi3VRotRSEDN/tIhekNo8p6
++Pl8YF4V8A1hCVBEKRIcsPVx603DFiGFRcQQcBbblqVG4fpOYYgiBtEgJksRiMg/o
++kmVkl8BPrIhBGe2ez7byhhFvJDAoOWCdH0MWGaPGUoCGTDvd046GE8B3UWN9TSmo
++qAqfrUG0hQVQLEa0FnNzaDovL2hvc3QuZXhhbXBsZS5uZXSJAU4EEwEIADgWIQT3
++S0Ap5pBtEuvajuO9d0SQD9q8jQUCWKLNaAIbIQULCQgHAgYVCAkKCwIEFgIDAQIe
++AQIXgAAKCRC9d0SQD9q8jZBrB/41MJWUeclVtM60+ydPNgUJwyRXpKdLIm/AtM1z
++OijlFkwsaMmzbFSFJJX98HGASHdU5OpL2Lv31NNDNMbUuFumApVrLzJUBugFRb+8
++/uY7H3Z0/YKQ9g9OC3z7+uqFFv/+/wA+VdYXZy6uim8E4OlJ41S68fQcMiTxbLTC
++DkvBbpf505t6JhNqF6JB+SBFQJXvRqjoydXfdyoiDz9N1V0ERzmGEiPewvHg2zWc
++Via07NGhxN3slQ3klOfYJQ8Ye72feNq1zKCyAyU3X8fL10XKWooCAU+t4hR5hXYx
++YTSZse5q0FHZ38Lt9c3ApMSZ2+ueeOtGbsH9kV8icGkI6KXp
++=3QG9
++-----END PGP PRIVATE KEY BLOCK-----
diff --git a/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch b/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch
new file mode 100644 (file)
index 0000000..f1e9791
--- /dev/null
@@ -0,0 +1,71 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Wed, 15 Feb 2017 17:03:57 +0100
+Subject: dirmngr: Avoid PTR lookup for hosts in a pool
+
+* dirmngr/ks-engine-hkp.c (add_host): Don't to a PTR lookup for hosts
+in a pool.
+--
+
+GnuPG-bug-id: 2928
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit da2ba20868093e3054d18adc2b1bc56cb23e4ba7)
+---
+ dirmngr/ks-engine-hkp.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index be8b083..32db4bc 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -320,10 +320,17 @@ add_host (const char *name, int is_pool,
+   idx = find_hostinfo (name);
+-  if (!is_pool && !is_ip_address (name))
++  if (is_pool)
+     {
+-      /* This is a hostname but not a pool.  Use the name
+-         as given without going through resolve_dns_addr.  */
++      /* For a pool immediately convert the address to a string.  */
++      tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
++                                 (DNS_NUMERICHOST | DNS_WITHBRACKET), &tmphost);
++      is_numeric = 1;
++    }
++  else if (!is_ip_address (name))
++    {
++      /* This is a hostname.  Use the name as given without going
++       * through resolve_dns_addr.  */
+       tmphost = xtrystrdup (name);
+       if (!tmphost)
+         tmperr = gpg_error_from_syserror ();
+@@ -332,6 +339,10 @@ add_host (const char *name, int is_pool,
+     }
+   else
+     {
++      /* Do a PTR lookup on AI.  If a name was not found the function
++       * returns the numeric address (with brackets) and we set a flag
++       * so that we know that the conversion to a numerical string has
++       * already be done.  */
+       tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
+                                  DNS_WITHBRACKET, &tmphost);
+       if (tmphost && is_ip_address (tmphost))
+@@ -364,8 +375,7 @@ add_host (const char *name, int is_pool,
+       if (tmpidx == -1)
+         {
+-          log_error ("map_host for '%s' problem: %s - '%s'"
+-                     " [ignored]\n",
++          log_error ("map_host for '%s' problem: %s - '%s' [ignored]\n",
+                      name, strerror (errno), tmphost);
+         }
+       else  /* Set or update the entry. */
+@@ -375,6 +385,9 @@ add_host (const char *name, int is_pool,
+           if (port)
+             hosttable[tmpidx]->port = port;
++          /* If TMPHOST is not yet a numerical value do this now.
++           * Note: This is a simple string operations and not a PTR
++           * lookup (due to DNS_NUMERICHOST).  */
+           if (!is_numeric)
+             {
+               xfree (tmphost);
diff --git a/patches/0040-gpgv-w32-Fix-status-fd.patch b/patches/0040-gpgv-w32-Fix-status-fd.patch
new file mode 100644 (file)
index 0000000..555af36
--- /dev/null
@@ -0,0 +1,27 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 28 Feb 2017 09:35:41 +0100
+Subject: gpgv,w32: Fix --status-fd.
+
+* g10/gpgv.c (main): Use translate_sys2libc_fd_int for --status-fd.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 8a67dc4c4324b617b5a3fea51c59c674488544d6)
+---
+ g10/gpgv.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/g10/gpgv.c b/g10/gpgv.c
+index bd16b39..ca8fca4 100644
+--- a/g10/gpgv.c
++++ b/g10/gpgv.c
+@@ -194,7 +194,9 @@ main( int argc, char **argv )
+           break;
+         case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
+         case oOutput: opt.outfile = pargs.r.ret_str; break;
+-        case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
++        case oStatusFD:
++          set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
++          break;
+         case oLoggerFD:
+           log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
+           break;
diff --git a/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch b/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
new file mode 100644 (file)
index 0000000..ae0cff9
--- /dev/null
@@ -0,0 +1,42 @@
+From: Justus Winter <justus@g10code.com>
+Date: Tue, 28 Feb 2017 13:15:42 +0100
+Subject: gpg,tools: Make trust-model configurable via gpgconf.
+
+* g10/gpg.c (gpgconf_list): Add 'trust-model'.
+* tools/gpgconf-comp.c (gc_options_gpg): Likewise.
+
+GnuPG-bug-id: 2381
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit ebeccd73eb85f9027f0985d77dfe901266c6ddef)
+---
+ g10/gpg.c            | 1 +
+ tools/gpgconf-comp.c | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 0c5a167..09bdf66 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -1845,6 +1845,7 @@ gpgconf_list (const char *configfile)
+   es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+   es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+   es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
++  es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE);
+   /* The next one is an info only item and should match the macros at
+      the top of keygen.c  */
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index a0d9659..cdd2586 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -716,6 +716,10 @@ static gc_option_t gc_options_gpg[] =
+      (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
+      NULL, NULL,
+      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
++   { "trust-model",
++     GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
++     NULL, NULL,
++     GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+    { "Debug",
diff --git a/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch b/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
new file mode 100644 (file)
index 0000000..60d29b7
--- /dev/null
@@ -0,0 +1,40 @@
+From: Justus Winter <justus@g10code.com>
+Date: Tue, 28 Feb 2017 14:59:11 +0100
+Subject: gpg,tools: Make auto-key-retrieve configurable via gpgconf.
+
+* g10/gpg.c (gpgconf_list): Add 'auto-key-retrieve'.
+* tools/gpgconf-comp.c (gc_options_gpg): Likewise.
+
+GnuPG-bug-id: 2381
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit d379a0174cca595204b32da9a66c513a1304e6d0)
+---
+ g10/gpg.c            | 1 +
+ tools/gpgconf-comp.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 09bdf66..2a4a0ad 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -1840,6 +1840,7 @@ gpgconf_list (const char *configfile)
+   es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+   es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE);
+   es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
++  es_printf ("auto-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
+   es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+   es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+   es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index cdd2586..530c128 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -747,6 +747,8 @@ static gc_option_t gc_options_gpg[] =
+    { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
+      "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
+      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
++   { "auto-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
++     NULL, NULL, GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
+    GC_OPTION_NULL
diff --git a/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch b/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
new file mode 100644 (file)
index 0000000..9d6fe6e
--- /dev/null
@@ -0,0 +1,204 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Wed, 1 Mar 2017 13:36:01 +0100
+Subject: gpg: Allow creating keys using an existing ECC key.
+
+* common/sexputil.c (get_pk_algo_from_canon_sexp): Remove arg R_ALGO.
+Change to return the algo id.  Reimplement using get_pk_algo_from_key.
+* g10/keygen.c (check_keygrip): Adjust for change.
+* sm/certreqgen-ui.c (check_keygrip): Ditto.
+--
+
+GnuPG-bug-id: 2976
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 2bbdeb8ee87a6c7ec211be16391a11b7c6030bed)
+---
+ common/sexputil.c  | 65 +++++++++++++++---------------------------------------
+ common/util.h      |  6 ++---
+ g10/keygen.c       | 22 +++---------------
+ sm/certreqgen-ui.c | 24 +++++++++-----------
+ 4 files changed, 34 insertions(+), 83 deletions(-)
+
+diff --git a/common/sexputil.c b/common/sexputil.c
+index 0c5c730..a8dc1a5 100644
+--- a/common/sexputil.c
++++ b/common/sexputil.c
+@@ -512,53 +512,6 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
+ }
+-/* Return the algo of a public RSA expressed as an canonical encoded
+-   S-expression.  The return value is a statically allocated
+-   string.  On error that string is set to NULL. */
+-gpg_error_t
+-get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
+-                             const char **r_algo)
+-{
+-  gpg_error_t err;
+-  const unsigned char *buf, *tok;
+-  size_t buflen, toklen;
+-  int depth;
+-
+-  *r_algo = NULL;
+-
+-  buf = keydata;
+-  buflen = keydatalen;
+-  depth = 0;
+-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+-    return err;
+-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+-    return err;
+-  if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
+-    return gpg_error (GPG_ERR_BAD_PUBKEY);
+-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+-    return err;
+-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+-    return err;
+-  if (!tok)
+-    return gpg_error (GPG_ERR_BAD_PUBKEY);
+-
+-  if (toklen == 3 && !memcmp ("rsa", tok, toklen))
+-    *r_algo = "rsa";
+-  else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
+-    *r_algo = "dsa";
+-  else if (toklen == 3 && !memcmp ("elg", tok, toklen))
+-    *r_algo = "elg";
+-  else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
+-    *r_algo = "ecdsa";
+-  else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
+-    *r_algo = "eddsa";
+-  else
+-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
+-
+-  return 0;
+-}
+-
+-
+ /* Return the algo of a public KEY of SEXP. */
+ int
+ get_pk_algo_from_key (gcry_sexp_t key)
+@@ -606,3 +559,21 @@ get_pk_algo_from_key (gcry_sexp_t key)
+   return algo;
+ }
++
++
++/* This is a variant of get_pk_algo_from_key but takes an canonical
++ * encoded S-expression as input.  Returns a GCRYPT public key
++ * identiier or 0 on error.  */
++int
++get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen)
++{
++  gcry_sexp_t sexp;
++  int algo;
++
++  if (gcry_sexp_sscan (&sexp, NULL, keydata, keydatalen))
++    return 0;
++
++  algo = get_pk_algo_from_key (sexp);
++  gcry_sexp_release (sexp);
++  return algo;
++}
+diff --git a/common/util.h b/common/util.h
+index f7a53e1..b6d7156 100644
+--- a/common/util.h
++++ b/common/util.h
+@@ -195,10 +195,10 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
+                                         size_t *r_nlen,
+                                         unsigned char const **r_e,
+                                         size_t *r_elen);
+-gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
+-                                         size_t keydatalen,
+-                                         const char **r_algo);
++
+ int get_pk_algo_from_key (gcry_sexp_t key);
++int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
++                                 size_t keydatalen);
+ /*-- convert.c --*/
+ int hex2bin (const char *string, void *buffer, size_t length);
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 98ef29e..0180581 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -1838,7 +1838,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+   gpg_error_t err;
+   unsigned char *public;
+   size_t publiclen;
+-  const char *algostr;
++  int algo;
+   if (hexgrip[0] == '&')
+     hexgrip++;
+@@ -1848,26 +1848,10 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+     return 0;
+   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
+-  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
++  algo = get_pk_algo_from_canon_sexp (public, publiclen);
+   xfree (public);
+-  /* FIXME: Mapping of ECC algorithms is probably not correct. */
+-  if (!algostr)
+-    return 0;
+-  else if (!strcmp (algostr, "rsa"))
+-    return PUBKEY_ALGO_RSA;
+-  else if (!strcmp (algostr, "dsa"))
+-    return PUBKEY_ALGO_DSA;
+-  else if (!strcmp (algostr, "elg"))
+-    return PUBKEY_ALGO_ELGAMAL_E;
+-  else if (!strcmp (algostr, "ecc"))
+-    return PUBKEY_ALGO_ECDH;
+-  else if (!strcmp (algostr, "ecdsa"))
+-    return PUBKEY_ALGO_ECDSA;
+-  else if (!strcmp (algostr, "eddsa"))
+-    return PUBKEY_ALGO_EDDSA;
+-  else
+-    return 0;
++  return map_pk_gcry_to_openpgp (algo);
+ }
+diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c
+index ece8668..b50d338 100644
+--- a/sm/certreqgen-ui.c
++++ b/sm/certreqgen-ui.c
+@@ -95,7 +95,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+   gpg_error_t err;
+   ksba_sexp_t public;
+   size_t publiclen;
+-  const char *algostr;
++  int algo;
+   if (hexgrip[0] == '&')
+     hexgrip++;
+@@ -105,21 +105,17 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+     return NULL;
+   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
+-  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
++  algo = get_pk_algo_from_canon_sexp (public, publiclen);
+   xfree (public);
+-  if (!algostr)
+-    return NULL;
+-  else if (!strcmp (algostr, "rsa"))
+-    return "RSA";
+-  else if (!strcmp (algostr, "dsa"))
+-    return "DSA";
+-  else if (!strcmp (algostr, "elg"))
+-    return "ELG";
+-  else if (!strcmp (algostr, "ecdsa"))
+-    return "ECDSA";
+-  else
+-    return NULL;
++  switch (algo)
++    {
++    case GCRY_PK_RSA:   return "RSA";
++    case GCRY_PK_DSA:   return "DSA";
++    case GCRY_PK_ELG:   return "ELG";
++    case GCRY_PK_EDDSA: return "ECDSA";
++    default: return NULL;
++    }
+ }
diff --git a/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch b/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch
new file mode 100644 (file)
index 0000000..7dc7666
--- /dev/null
@@ -0,0 +1,156 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Wed, 1 Mar 2017 14:41:47 +0100
+Subject: gpg: Make --export-options work with --export-secret-keys.
+
+* g10/export.c (export_seckeys): Add arg OPTIONS and pass it to
+do_export.
+(export_secsubkeys): Ditto.
+* g10/gpg.c (main): Pass opt.export_options to export_seckeys and
+export_secsubkeys
+--
+
+Back in the old days we did not used the export options for secret
+keys export because of a lot of duplicated code and that the old
+secring.gpg was anyway smaller that the pubring.gpg.  With 2.1 it was
+pretty easy to enable it.
+
+Reported-by: Peter Lebbing
+GnuPG-bug-id: 2973
+(cherry picked from commit 891ab23411b7f20ef37d8bde81d9857b083235df)
+---
+ doc/gpg.texi |  7 ++++---
+ g10/export.c | 31 ++++++++++++++++---------------
+ g10/gpg.c    |  4 ++--
+ g10/main.h   |  6 ++++--
+ 4 files changed, 26 insertions(+), 22 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index b79b783..3b82b44 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -1824,7 +1824,8 @@ are available for all keyserver types, some common options are:
+   used with HKP keyservers.
+   @item auto-key-retrieve
+-  This is the same as the option @option{auto-key-retrieve}.
++  This is an obsolete alias for the option @option{auto-key-retrieve}.
++  Please do not use it; it will be removed in future versions..
+   @item honor-keyserver-url
+   When using @option{--refresh-keys}, if the key in question has a preferred
+@@ -2371,8 +2372,8 @@ The available properties are:
+ @item --export-options @code{parameters}
+ @opindex export-options
+ This is a space or comma delimited string that gives options for
+-exporting keys. Options can be prepended with a `no-' to give the
+-opposite meaning. The options are:
++exporting keys.  Options can be prepended with a `no-' to give the
++opposite meaning.  The options are:
+ @table @asis
+diff --git a/g10/export.c b/g10/export.c
+index 8668126..207f994 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -247,16 +247,17 @@ export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
+ /*
+  * Export secret keys (to stdout or to --output FILE).
+  *
+- * Depending on opt.armor the output is armored.  If USERS is NULL,
+- * all secret keys will be exported.  STATS is either an export stats
+- * object for update or NULL.
++ * Depending on opt.armor the output is armored.  OPTIONS are defined
++ * in main.h.  If USERS is NULL, all secret keys will be exported.
++ * STATS is either an export stats object for update or NULL.
+  *
+  * This function is the core of "gpg --export-secret-keys".
+  */
+ int
+-export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
++export_seckeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++                export_stats_t stats)
+ {
+-  return do_export (ctrl, users, 1, 0, stats);
++  return do_export (ctrl, users, 1, options, stats);
+ }
+@@ -264,16 +265,18 @@ export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
+  * Export secret sub keys (to stdout or to --output FILE).
+  *
+  * This is the same as export_seckeys but replaces the primary key by
+- * a stub key.  Depending on opt.armor the output is armored.  If
+- * USERS is NULL, all secret subkeys will be exported.  STATS is
+- * either an export stats object for update or NULL.
++ * a stub key.  Depending on opt.armor the output is armored.  OPTIONS
++ * are defined in main.h.  If USERS is NULL, all secret subkeys will
++ * be exported.  STATS is either an export stats object for update or
++ * NULL.
+  *
+  * This function is the core of "gpg --export-secret-subkeys".
+  */
+ int
+-export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
++export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++                   export_stats_t stats)
+ {
+-  return do_export (ctrl, users, 2, 0, stats);
++  return do_export (ctrl, users, 2, options, stats);
+ }
+@@ -1969,11 +1972,9 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
+         }
+       /* Always do the cleaning on the public key part if requested.
+-         Note that we don't yet set this option if we are exporting
+-         secret keys.  Note that both export-clean and export-minimal
+-         only apply to UID sigs (0x10, 0x11, 0x12, and 0x13).  A
+-         designated revocation is never stripped, even with
+-         export-minimal set.  */
++       * Note that both export-clean and export-minimal only apply to
++       * UID sigs (0x10, 0x11, 0x12, and 0x13).  A designated
++       * revocation is never stripped, even with export-minimal set.  */
+       if ((options & EXPORT_CLEAN))
+         clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 2a4a0ad..5a880fd 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -4546,7 +4546,7 @@ main (int argc, char **argv)
+           add_to_strlist2( &sl, *argv, utf8_strings );
+         {
+           export_stats_t stats = export_new_stats ();
+-          export_seckeys (ctrl, sl, stats);
++          export_seckeys (ctrl, sl, opt.export_options, stats);
+           export_print_stats (stats);
+           export_release_stats (stats);
+         }
+@@ -4559,7 +4559,7 @@ main (int argc, char **argv)
+           add_to_strlist2( &sl, *argv, utf8_strings );
+         {
+           export_stats_t stats = export_new_stats ();
+-          export_secsubkeys (ctrl, sl, stats);
++          export_secsubkeys (ctrl, sl, opt.export_options, stats);
+           export_print_stats (stats);
+           export_release_stats (stats);
+         }
+diff --git a/g10/main.h b/g10/main.h
+index 5ed501b..6837e98 100644
+--- a/g10/main.h
++++ b/g10/main.h
+@@ -397,8 +397,10 @@ gpg_error_t parse_and_set_export_filter (const char *string);
+ int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
+                     export_stats_t stats);
+-int export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
+-int export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
++int export_seckeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++                    export_stats_t stats);
++int export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++                       export_stats_t stats);
+ gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec,
+                                   unsigned int options,
diff --git a/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch b/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch
new file mode 100644 (file)
index 0000000..8b3e32b
--- /dev/null
@@ -0,0 +1,63 @@
+From: Justus Winter <justus@g10code.com>
+Date: Wed, 1 Mar 2017 17:47:47 +0100
+Subject: common,tools: Always escape newlines when escaping data.
+
+* common/stringhelp.c (do_percent_escape): Always escape newlines.
+* tools/gpgconf-comp.c (gc_percent_escape): Likewise.
+--
+Newlines always pose a problem for a line-based communication format.
+
+GnuPG-bug-id: 2387
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit e064c75b08a523f738108428fe0c417a46e66238)
+---
+ common/stringhelp.c  | 10 +++++++++-
+ tools/gpgconf-comp.c |  7 +++++++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/common/stringhelp.c b/common/stringhelp.c
+index dea2212..0abfa3d 100644
+--- a/common/stringhelp.c
++++ b/common/stringhelp.c
+@@ -1052,7 +1052,8 @@ do_percent_escape (const char *str, const char *extra, int die)
+     return NULL;
+   for (i=j=0; str[i]; i++)
+-    if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
++    if (str[i] == ':' || str[i] == '%' || str[i] == '\n'
++        || (extra && strchr (extra, str[i])))
+       j++;
+   if (die)
+     ptr = xmalloc (i + 2 * j + 1);
+@@ -1077,6 +1078,13 @@ do_percent_escape (const char *str, const char *extra, int die)
+         ptr[i++] = '2';
+         ptr[i++] = '5';
+       }
++      else if (*str == '\n')
++      {
++        /* The newline is problematic in a line-based format.  */
++        ptr[i++] = '%';
++        ptr[i++] = '0';
++        ptr[i++] = 'a';
++      }
+       else if (extra && strchr (extra, *str))
+         {
+         ptr[i++] = '%';
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 530c128..9358e2e 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -1490,6 +1490,13 @@ gc_percent_escape (const char *src)
+         *(dst++) = '2';
+         *(dst++) = 'c';
+       }
++      else if (*src == '\n')
++      {
++        /* The newline is problematic in a line-based format.  */
++        *(dst++) = '%';
++        *(dst++) = '0';
++        *(dst++) = 'a';
++      }
+       else
+       *(dst++) = *(src);
+       src++;
diff --git a/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch b/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
new file mode 100644 (file)
index 0000000..14480bf
--- /dev/null
@@ -0,0 +1,53 @@
+From: Justus Winter <justus@g10code.com>
+Date: Thu, 2 Mar 2017 11:39:00 +0100
+Subject: g10: Signal an error when trying to revoke non-existant UID.
+
+* g10/keyedit.c (keyedit_quick_revuid): Signal an error when trying to
+revoke non-existant UID.
+* tests/openpgp/quick-key-manipulation.scm: Test that.
+
+GnuPG-bug-id: 2962
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 62d21a4ab4029b32ea129f1cf3a0e1f22e2fb7b0)
+---
+ g10/keyedit.c                            | 2 ++
+ tests/openpgp/quick-key-manipulation.scm | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 1456d28..a477e92 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -3053,6 +3053,8 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+         }
+     }
++  log_error (_("User ID revocation failed: %s\n"), gpg_strerror (GPG_ERR_NOT_FOUND));
++
+  leave:
+   release_kbnode (keyblock);
+   keydb_release (kdbhd);
+diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm
+index d43f7b5..ae1d0b9 100755
+--- a/tests/openpgp/quick-key-manipulation.scm
++++ b/tests/openpgp/quick-key-manipulation.scm
+@@ -36,6 +36,7 @@
+ (define alpha "Alpha <alpha@invalid.example.net>")
+ (define bravo "Bravo <bravo@invalid.example.net>")
++(define charlie "Charlie <charlie@invalid.example.net>")
+ (define (key-data key)
+   (filter (lambda (x) (or (string=? (car x) "pub")
+@@ -78,6 +79,11 @@
+ (info "Checking that we can revoke a user ID...")
+ (call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,alpha))
++(info "Checking that we get an error revoking a non-existant user ID.")
++(catch '()
++       (call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,charlie))
++       (error "Expected an error, but get none."))
++
+ (assert (= 1 (count-uids-of-secret-key bravo)))
+ (info "Checking that we can change the expiration time.")
diff --git a/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch b/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
new file mode 100644 (file)
index 0000000..3b232db
--- /dev/null
@@ -0,0 +1,58 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 3 Mar 2017 09:50:40 +0100
+Subject: gpg: Fix possible segv when attribute packets are filtered.
+
+* g10/import.c (impex_filter_getval): Handle PKT_ATTRIBUTE the same as
+PKT_USER_ID
+(apply_drop_sig_filter): Ditto.
+--
+
+The old code was plainly wrong in that it considered PKT_ATTRIBUTE to
+use a PKT_signature object.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 5f6f3f5cae8a95ed469129f9677782c17951dab3)
+---
+ g10/import.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index b6c04dc..4e6f692 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1173,7 +1173,8 @@ impex_filter_getval (void *cookie, const char *propname)
+   static char numbuf[20];
+   const char *result;
+-  if (node->pkt->pkttype == PKT_USER_ID)
++  if (node->pkt->pkttype == PKT_USER_ID
++      || node->pkt->pkttype == PKT_ATTRIBUTE)
+     {
+       if (!strcmp (propname, "uid"))
+         result = node->pkt->pkt.user_id->name;
+@@ -1191,8 +1192,7 @@ impex_filter_getval (void *cookie, const char *propname)
+       else
+         result = NULL;
+     }
+-  else if (node->pkt->pkttype == PKT_SIGNATURE
+-           || node->pkt->pkttype == PKT_ATTRIBUTE)
++  else if (node->pkt->pkttype == PKT_SIGNATURE)
+     {
+       PKT_signature *sig = node->pkt->pkt.signature;
+@@ -1313,12 +1313,12 @@ apply_drop_sig_filter (kbnode_t keyblock, recsel_expr_t selector)
+       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+           || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+         break; /* ready.  */
+-      if (node->pkt->pkttype == PKT_USER_ID)
++      if (node->pkt->pkttype == PKT_USER_ID
++          || node->pkt->pkttype == PKT_ATTRIBUTE)
+         active = 1;
+       if (!active)
+         continue;
+-      if (node->pkt->pkttype != PKT_SIGNATURE
+-          && node->pkt->pkttype != PKT_ATTRIBUTE)
++      if (node->pkt->pkttype != PKT_SIGNATURE)
+         continue;
+       sig = node->pkt->pkt.signature;
diff --git a/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch b/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
new file mode 100644 (file)
index 0000000..9de4ed1
--- /dev/null
@@ -0,0 +1,59 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Sun, 5 Mar 2017 23:24:15 +0100
+Subject: gpg: Fix attempt to double free an UID structure.
+
+* g10/getkey.c (get_best_pubkey_byname): Set released .UID to NULL.
+--
+
+Phil Pennock reported an assertion failure when doing
+
+  % gpg --auto-key-locate dane --locate-keys someone
+  gpg: Ohhhh jeeee: Assertion "uid->ref > 0" in \
+         free_user_id failed (free-packet.c:310)
+
+on his keyring.  This patch is not tested but a good guess.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 4a130bbc2c2f4be6e8c6357512a943f435ade28f)
+---
+ g10/getkey.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/g10/getkey.c b/g10/getkey.c
+index e39de28..21dcf08 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -1592,8 +1592,10 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+   if (is_valid_mailbox (name) && ctx)
+     {
+       /* Rank results and return only the most relevant key.  */
+-      struct pubkey_cmp_cookie best = { 0 }, new;
+-      KBNODE new_keyblock;
++      struct pubkey_cmp_cookie best = { 0 };
++      struct pubkey_cmp_cookie new;
++      kbnode_t new_keyblock;
++
+       while (getkey_next (ctx, &new.key, &new_keyblock) == 0)
+         {
+           int diff = pubkey_cmp (ctrl, name, &best, &new, new_keyblock);
+@@ -1610,17 +1612,20 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+               /* Old key is better.  */
+               release_public_key_parts (&new.key);
+               free_user_id (new.uid);
++              new.uid = NULL;
+             }
+           else
+             {
+               /* A tie.  Keep the old key.  */
+               release_public_key_parts (&new.key);
+               free_user_id (new.uid);
++              new.uid = NULL;
+             }
+         }
+       getkey_end (ctx);
+       ctx = NULL;
+       free_user_id (best.uid);
++      best.uid = NULL;
+       if (best.valid)
+         {
diff --git a/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch b/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch
new file mode 100644 (file)
index 0000000..de1f75d
--- /dev/null
@@ -0,0 +1,75 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Wed, 8 Mar 2017 10:46:09 +0100
+Subject: doc: Add a note to the trust model direct.
+
+* doc/gpg.texi (GPG Configuration Options): Add note.  Chnage Index
+from trust-mode:foo to trust-model:foo.
+
+(cherry picked from commit f0257b4a86b73f5b956028e68590b6d2a23ea4da)
+---
+ doc/gpg.texi | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index 3b82b44..d658737 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -1600,17 +1600,17 @@ Set what trust model GnuPG should follow. The models are:
+ @table @asis
+   @item pgp
+-  @opindex trust-mode:pgp
++  @opindex trust-model:pgp
+   This is the Web of Trust combined with trust signatures as used in PGP
+   5.x and later. This is the default trust model when creating a new
+   trust database.
+   @item classic
+-  @opindex trust-mode:classic
++  @opindex trust-model:classic
+   This is the standard Web of Trust as introduced by PGP 2.
+   @item tofu
+-  @opindex trust-mode:tofu
++  @opindex trust-model:tofu
+   @anchor{trust-model-tofu}
+   TOFU stands for Trust On First Use.  In this trust model, the first
+   time a key is seen, it is memorized.  If later another key is seen
+@@ -1656,7 +1656,7 @@ Set what trust model GnuPG should follow. The models are:
+   @code{undefined} trust level is returned.
+   @item tofu+pgp
+-  @opindex trust-mode:tofu+pgp
++  @opindex trust-model:tofu+pgp
+   This trust model combines TOFU with the Web of Trust.  This is done
+   by computing the trust level for each model and then taking the
+   maximum trust level where the trust levels are ordered as follows:
+@@ -1669,12 +1669,16 @@ Set what trust model GnuPG should follow. The models are:
+   which some security-conscious users don't like.
+   @item direct
+-  @opindex trust-mode:direct
++  @opindex trust-model:direct
+   Key validity is set directly by the user and not calculated via the
+-  Web of Trust.
++  Web of Trust.  This model is soley based on the key and does
++  not distinguish user IDs.  Note that when changing to another trust
++  model the trust values assigned to a key are transformed into
++  ownertrust values, which also indicate how you trust the owner of
++  the key to sign other keys.
+   @item always
+-  @opindex trust-mode:always
++  @opindex trust-model:always
+   Skip key validation and assume that used keys are always fully
+   valid. You generally won't use this unless you are using some
+   external validation scheme. This option also suppresses the
+@@ -1684,7 +1688,7 @@ Set what trust model GnuPG should follow. The models are:
+   disabled keys.
+   @item auto
+-  @opindex trust-mode:auto
++  @opindex trust-model:auto
+   Select the trust model depending on whatever the internal trust
+   database says. This is the default model if such a database already
+   exists.
diff --git a/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch b/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
new file mode 100644 (file)
index 0000000..62cbee9
--- /dev/null
@@ -0,0 +1,37 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 13 Mar 2017 17:42:08 +0100
+Subject: gpg: Flush stdout before printing stats with --check-sigs.
+
+* g10/keylist.c (print_signature_stats): Flush stdout.
+(list_keyblock_colon): Use es_flush instead of fflush.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 9a77b3b6e41f97b1209ad61c04b3dd33242ecae8)
+---
+ g10/keylist.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index abdcb9f..4078053 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -465,6 +465,10 @@ print_signature_stats (struct keylist_context *s)
+   if (!s->check_sigs)
+     return;  /* Signature checking was not requested.  */
++  /* Better flush stdout so that the stats are always printed after
++   * the output.  */
++  es_fflush (es_stdout);
++
+   if (s->good_sigs)
+     log_info (ngettext("%d good signature\n",
+                        "%d good signatures\n", s->good_sigs), s->good_sigs);
+@@ -1447,7 +1451,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
+           {
+             PKT_public_key *signer_pk = NULL;
+-            fflush (stdout);
++            es_fflush (es_stdout);
+             if (opt.no_sig_cache)
+               signer_pk = xmalloc_clear (sizeof (PKT_public_key));
diff --git a/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch b/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
new file mode 100644 (file)
index 0000000..c30365b
--- /dev/null
@@ -0,0 +1,44 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 17 Mar 2017 12:46:09 +0100
+Subject: dirmngr: Ignore warning alerts in the GNUTLS handshake.
+
+* dirmngr/http.c (send_request) [GNUTLS]: Don't bail out on warning
+alerts.
+--
+
+GnuPG-bug-id: 2833
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 69c521df422a6c9a6b0a93e45c9373a8b6ceb28e)
+---
+ dirmngr/http.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index fe9c3c7..c9c16df 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -1847,6 +1847,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
+       gnutls_transport_set_push_function (hd->session->tls_session,
+                                           my_gnutls_write);
++    handshake_again:
+       do
+         {
+           rc = gnutls_handshake (hd->session->tls_session);
+@@ -1862,10 +1863,15 @@ send_request (http_t hd, const char *httphost, const char *auth,
+               alertno = gnutls_alert_get (hd->session->tls_session);
+               alertstr = gnutls_alert_get_name (alertno);
+-              log_info ("TLS handshake failed: %s (alert %d)\n",
++              log_info ("TLS handshake %s: %s (alert %d)\n",
++                        rc == GNUTLS_E_WARNING_ALERT_RECEIVED
++                        ? "warning" : "failed",
+                         alertstr, (int)alertno);
+               if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
+                 log_info ("  (sent server name '%s')\n", server);
++
++              if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
++                goto handshake_again;
+             }
+           else
+             log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
diff --git a/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch b/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
new file mode 100644 (file)
index 0000000..0a11a8e
--- /dev/null
@@ -0,0 +1,72 @@
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Fri, 17 Mar 2017 13:36:51 +0100
+Subject: gpg: Make sure the conflict set includes the current key.
+
+* g10/tofu.c (get_trust): Sanity check CONFLICT_SET after calling
+get_policy.  If POLICY is 'auto' and the default policy is 'ask', make
+sure CONFLICT_SET includes the current key.
+
+--
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+GnuPG-bug-id: 2959
+Debian-bug-id: 854829
+
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+(cherry picked from commit b1106b4d640325c60a7212a4a44e4f67c0e3312d)
+---
+ g10/tofu.c | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 449e921..39457a5 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2304,9 +2304,14 @@ build_conflict_set (tofu_dbs_t dbs,
+ /* Return the effective policy for the binding <FINGERPRINT, EMAIL>
+- * (email has already been normalized) and any conflict information in
+- * *CONFLICT_SETP, if CONFLICT_SETP is not NULL.  Returns
+- * _tofu_GET_POLICY_ERROR if an error occurs.
++ * (email has already been normalized).  Returns
++ * _tofu_GET_POLICY_ERROR if an error occurs.  Returns any conflict
++ * information in *CONFLICT_SETP if CONFLICT_SETP is not NULL and the
++ * returned policy is TOFU_POLICY_ASK (consequently, if there is a
++ * conflict, but the user set the policy to good *CONFLICT_SETP will
++ * empty).  Note: as per build_conflict_set, which is used to build
++ * the conflict information, the conflict information includes the
++ * current user id as the first element of the linked list.
+  *
+  * This function registers the binding in the bindings table if it has
+  * not yet been registered.
+@@ -2689,6 +2694,15 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+   policy = get_policy (dbs, pk, fingerprint, user_id, email,
+                        &conflict_set, now);
++  if (policy == TOFU_POLICY_ASK)
++    /* The conflict set should always contain at least one element:
++     * the current key.  */
++    log_assert (conflict_set);
++  else
++    /* If the policy is not TOFU_POLICY_ASK, then conflict_set will be
++     * NULL.  */
++    log_assert (! conflict_set);
++
+   /* If the key is ultimately trusted, there is nothing to do.  */
+   {
+     u32 kid[2];
+@@ -2710,6 +2724,14 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+                    " auto (default: %s).\n",
+                  fingerprint, email,
+                  tofu_policy_str (opt.tofu_default_policy));
++
++      if (policy == TOFU_POLICY_ASK)
++        /* The default policy is ASK, but there is no conflict (policy
++         * was 'auto').  In this case, we need to make sure the
++         * conflict set includes at least the current user id.  */
++        {
++          add_to_strlist (&conflict_set, fingerprint);
++        }
+     }
+   switch (policy)
+     {
diff --git a/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch b/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch
new file mode 100644 (file)
index 0000000..aae341c
--- /dev/null
@@ -0,0 +1,60 @@
+From: Justus Winter <justus@g10code.com>
+Date: Tue, 21 Mar 2017 14:18:25 +0100
+Subject: dirmngr: Load the hosts file into libdns.
+
+* dirmngr/dns-stuff.c (libdns_init): Actually load the hosts file into
+libdns.
+--
+
+Previously, connecting to key servers specified in /etc/hosts was not
+possible because libdns' hosts structure was initialized, but not
+filled with the content of the hosts file.
+
+GnuPG-bug-id: 2977
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 88f1505f0613894d5544290a170119eb538921e5)
+---
+ dirmngr/dns-stuff.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index bc2e071..35e6c82 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -533,11 +533,35 @@ libdns_init (void)
+   ld.hosts = dns_hosts_open (&derr);
+   if (!ld.hosts)
+     {
+-      log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+       err = libdns_error_to_gpg_error (derr);
++      log_error ("failed to initialize hosts file: %s\n", gpg_strerror (err));
+       goto leave;
+     }
++
++  {
++#if HAVE_W32_SYSTEM
++    char *hosts_path = xtryasprintf ("%s\System32\drivers\etc\hosts",
++                                     getenv ("SystemRoot"));
++    if (! hosts_path)
++      {
++        err = gpg_error_from_syserror ();
++        goto leave;
++      }
++
++    derr = dns_hosts_loadpath (ld.hosts, hosts_path);
++    xfree (hosts_path);
++#else
++    derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
++#endif
++    if (derr)
++      {
++        err = libdns_error_to_gpg_error (derr);
++        log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
++        goto leave;
++      }
++  }
++
+   /* dns_hints_local for stub mode, dns_hints_root for recursive.  */
+   ld.hints = (recursive_resolver
+               ? dns_hints_root  (ld.resolv_conf, &derr)
diff --git a/patches/0054-dirmngr-Fix-error-handling.patch b/patches/0054-dirmngr-Fix-error-handling.patch
new file mode 100644 (file)
index 0000000..5b1d359
--- /dev/null
@@ -0,0 +1,26 @@
+From: Justus Winter <justus@g10code.com>
+Date: Tue, 21 Mar 2017 14:22:13 +0100
+Subject: dirmngr: Fix error handling.
+
+* dirmngr/dns-stuff.c (libdns_init): Convert error before printing it.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 483c1288a8f86dc6bf93d0d3f2865ecc246aecba)
+---
+ dirmngr/dns-stuff.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 35e6c82..c79a9c7 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -568,8 +568,8 @@ libdns_init (void)
+               : dns_hints_local (ld.resolv_conf, &derr));
+   if (!ld.hints)
+     {
+-      log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
+       err = libdns_error_to_gpg_error (derr);
++      log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
+       goto leave;
+     }
diff --git a/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch b/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
new file mode 100644 (file)
index 0000000..f7d7608
--- /dev/null
@@ -0,0 +1,65 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Thu, 23 Mar 2017 09:38:19 +0100
+Subject: common: Implicitly do a gpgconf --create-socketdir.
+
+* common/homedir.c (_gnupg_socketdir_internal): Create the
+sub-directory.
+--
+
+Although there is no auto cleanup (yet) this should be helpful.  Let's
+see whether possibly leaving stale directories around is better than
+running into trouble when --create-socketdir was not used.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 26086b362ff47d21b1abefaf674a6464bf0a8921)
+---
+ common/homedir.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/common/homedir.c b/common/homedir.c
+index 6b40bb6..c41cbdc 100644
+--- a/common/homedir.c
++++ b/common/homedir.c
+@@ -542,7 +542,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+   /* If a non default homedir is used, we check whether an
+    * corresponding sub directory below the socket dir is available
+-   * and use that.  We has the non default homedir to keep the new
++   * and use that.  We hash the non default homedir to keep the new
+    * subdir short enough.  */
+   if (non_default_homedir)
+     {
+@@ -566,16 +566,27 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+           goto leave;
+         }
+-      /* Stat that directory and check constraints.  Note that we
+-       * do not auto create such a directory because we would not
+-       * have a way to remove it.  Thus the directory needs to be
+-       * pre-created.  The command
+-       *    gpgconf --create-socketdir
+-       * can be used tocreate that directory.  */
++      /* Stat that directory and check constraints.
++       * The command
++       *    gpgconf --remove-socketdir
++       * can be used to remove that directory.  */
+       if (stat (name, &sb))
+         {
+           if (errno != ENOENT)
+             *r_info |= 1; /* stat failed. */
++          else if (!skip_checks)
++            {
++              /* Try to create the directory and check again.  */
++              if (gnupg_mkdir (name, "-rwx"))
++                *r_info |= 16; /* mkdir failed.  */
++              else if (stat (prefix, &sb))
++                {
++                  if (errno != ENOENT)
++                    *r_info |= 1; /* stat failed. */
++                  else
++                    *r_info |= 64; /* Subdir does not exist.  */
++                }
++            }
+           else
+             *r_info |= 64; /* Subdir does not exist.  */
+           if (!skip_checks)
diff --git a/patches/0056-common-Fix-connecting-to-the-agent.patch b/patches/0056-common-Fix-connecting-to-the-agent.patch
new file mode 100644 (file)
index 0000000..4923afb
--- /dev/null
@@ -0,0 +1,34 @@
+From: Justus Winter <justus@g10code.com>
+Date: Mon, 27 Mar 2017 16:14:20 +0200
+Subject: common: Fix connecting to the agent.
+
+* common/homedir.c (_gnupg_socketdir_internal): Fix error handling.
+--
+
+Prior to 26086b36 the non-existance of the socket directory was
+considered an error if a non-default home directory is used.  Since
+26086b36 we now create the directory on demand, but the function still
+returned the fallback path.  This made the agent bind the socket in
+the socket directory, and the client trying to connect to the socket
+in the home directory.
+
+Fixes-commit: 26086b362ff47d21b1abefaf674a6464bf0a8921
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit caf00915532e6e8e509738962964edcd14fb0654)
+---
+ common/homedir.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/common/homedir.c b/common/homedir.c
+index c41cbdc..4571aac 100644
+--- a/common/homedir.c
++++ b/common/homedir.c
+@@ -586,6 +586,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+                   else
+                     *r_info |= 64; /* Subdir does not exist.  */
+                 }
++              else
++                goto leave; /* Success!  */
+             }
+           else
+             *r_info |= 64; /* Subdir does not exist.  */
diff --git a/patches/0057-g10-Fix-memory-leak.patch b/patches/0057-g10-Fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..d6e074f
--- /dev/null
@@ -0,0 +1,33 @@
+From: Justus Winter <justus@g10code.com>
+Date: Tue, 28 Mar 2017 12:10:28 +0200
+Subject: g10: Fix memory leak.
+
+* g10/decrypt-data.c (decrypt_data): Free 'filename'.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 6d3edfd972c1114f43f6b35773dc25e0256f48f4)
+---
+ g10/decrypt-data.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
+index 585b150..f5843d6 100644
+--- a/g10/decrypt-data.c
++++ b/g10/decrypt-data.c
+@@ -222,7 +222,7 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+   if (opt.unwrap_encryption)
+     {
+-      char *filename;
++      char *filename = NULL;
+       estream_t fp;
+       rc = get_output_file ("", 0, ed->buf, &filename, &fp);
+       if (! rc)
+@@ -248,6 +248,7 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+           if (afx)
+             release_armor_context (afx);
+         }
++      xfree (filename);
+     }
+   else
+     proc_packets (ctrl, procctx, ed->buf );
diff --git a/patches/0058-common-Avoid-undefined-behavior.patch b/patches/0058-common-Avoid-undefined-behavior.patch
new file mode 100644 (file)
index 0000000..ad46b22
--- /dev/null
@@ -0,0 +1,26 @@
+From: Justus Winter <justus@g10code.com>
+Date: Thu, 30 Mar 2017 15:44:35 +0200
+Subject: common: Avoid undefined behavior.
+
+* common/iobuf.c (iobuf_read_line): Do not consider 'length' if
+'buffer' is NULL.
+
+Signed-off-by: Justus Winter <justus@g10code.com>
+(cherry picked from commit 214fa9012296d796b78f1a3106d656639cf50aef)
+---
+ common/iobuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/common/iobuf.c b/common/iobuf.c
+index d346027..b8baf7f 100644
+--- a/common/iobuf.c
++++ b/common/iobuf.c
+@@ -2552,7 +2552,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
+      NUL character in the buffer.  This requires at least 2 bytes.  We
+      don't complicate the code by handling the stupid corner case, but
+      simply assert that it can't happen.  */
+-  assert (length >= 2 || maxlen >= 2);
++  assert (!buffer || length >= 2 || maxlen >= 2);
+   if (!buffer || length <= 1)
+     /* must allocate a new buffer */
diff --git a/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch b/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
new file mode 100644 (file)
index 0000000..8d958d5
--- /dev/null
@@ -0,0 +1,31 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 3 Apr 2017 08:51:52 +0200
+Subject: gpg: Handle critical marked 'Reason for Revocation'.
+
+* g10/parse-packet.c (can_handle_critical): Add
+SIGSUBPKT_REVOC_REASON.
+--
+
+Some software seems to mark that subpacket as criticial.  Although gpg
+has no special treatment for a revocation reasons (except for
+--list-packets) we can accept a criticial marked anyway.  There are no
+mandatary rules specified on how to handle a revocation reason.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 3f6d949011f485613bb4bd3e06a2643be79cce40)
+---
+ g10/parse-packet.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/g10/parse-packet.c b/g10/parse-packet.c
+index 7f44ce5..bbb784a 100644
+--- a/g10/parse-packet.c
++++ b/g10/parse-packet.c
+@@ -1572,6 +1572,7 @@ can_handle_critical (const byte * buffer, size_t n, int type)
+       /* Is it enough to show the policy or keyserver? */
+     case SIGSUBPKT_POLICY:
+     case SIGSUBPKT_PREF_KS:
++    case SIGSUBPKT_REVOC_REASON: /* At least we know about it.  */
+       return 1;
+     default:
diff --git a/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch b/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
new file mode 100644 (file)
index 0000000..7cec8ae
--- /dev/null
@@ -0,0 +1,61 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 3 Apr 2017 19:10:50 +0200
+Subject: dirmngr: Do not assume that /etc/hosts exists.
+
+* dirmngr/dns-stuff.c (libdns_init): Do not bail out.
+--
+
+A standard Windows installation does not have a hosts file and thus we
+can't bail out here.  We should also not bail out on a Unix system
+because /etc/hosts is just one method in  nsswitch.conf.
+
+Fixes-commit: 88f1505f0613894d5544290a170119eb538921e5
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 5d873f288e86edfb684f4dd57ac36466b06494a4)
+---
+ dirmngr/dns-stuff.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index c79a9c7..c2d5488 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -538,10 +538,9 @@ libdns_init (void)
+       goto leave;
+     }
+-
+   {
+ #if HAVE_W32_SYSTEM
+-    char *hosts_path = xtryasprintf ("%s\System32\drivers\etc\hosts",
++    char *hosts_path = xtryasprintf ("%s\\System32\\drivers\\etc\\hosts",
+                                      getenv ("SystemRoot"));
+     if (! hosts_path)
+       {
+@@ -551,15 +550,24 @@ libdns_init (void)
+     derr = dns_hosts_loadpath (ld.hosts, hosts_path);
+     xfree (hosts_path);
++    if (derr)
++      {
++        err = libdns_error_to_gpg_error (derr);
++        /* Most Windows systems don't have a hosts files.  So do not
++         * report in this case.  */
++        if (gpg_err_code (err) != GPG_ERR_ENOENT)
++          log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
++        err = 0; /* Do not bail out.  */
++      }
+ #else
+     derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
+-#endif
+     if (derr)
+       {
+         err = libdns_error_to_gpg_error (derr);
+         log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+-        goto leave;
++        err = 0; /* Do not bail out - having no /etc/hosts is legal.  */
+       }
++#endif
+   }
+   /* dns_hints_local for stub mode, dns_hints_root for recursive.  */
diff --git a/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch b/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
new file mode 100644 (file)
index 0000000..ecf484e
--- /dev/null
@@ -0,0 +1,49 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 3 Apr 2017 20:20:27 +0200
+Subject: dirmngr: Always print a warning for a missing /etc/hosts.
+
+* dirmngr/dns-stuff.c (libdns_init): No Windows specific handling of a
+missing /etc/hosts.
+--
+
+My last comment on this was flawed.  Windows seems to always have its
+version of /etc/hosts.  Only the en passant fixed bad escaping led me
+assume that this was the case.  Thanks to Andre for complaining about
+my comment remark.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 35c843c815306f36d1efbc52f5e2f6bac3f67aec)
+---
+ dirmngr/dns-stuff.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index c2d5488..150237e 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -550,24 +550,15 @@ libdns_init (void)
+     derr = dns_hosts_loadpath (ld.hosts, hosts_path);
+     xfree (hosts_path);
+-    if (derr)
+-      {
+-        err = libdns_error_to_gpg_error (derr);
+-        /* Most Windows systems don't have a hosts files.  So do not
+-         * report in this case.  */
+-        if (gpg_err_code (err) != GPG_ERR_ENOENT)
+-          log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+-        err = 0; /* Do not bail out.  */
+-      }
+ #else
+     derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
++#endif
+     if (derr)
+       {
+         err = libdns_error_to_gpg_error (derr);
+         log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+         err = 0; /* Do not bail out - having no /etc/hosts is legal.  */
+       }
+-#endif
+   }
+   /* dns_hints_local for stub mode, dns_hints_root for recursive.  */
diff --git a/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch b/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
new file mode 100644 (file)
index 0000000..9a53665
--- /dev/null
@@ -0,0 +1,26 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 3 Apr 2017 20:23:18 +0200
+Subject: dirmngr: Handle EIO which is sometimes returned by cookie functions.
+
+* dirmngr/ks-engine-hkp.c (handle_send_request_error): Handle EIO.
+--
+
+Suggested-by: Andre Heinecke
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit cc32ddbcba8c53d3e2cad952d72f62dc73911042)
+---
+ dirmngr/ks-engine-hkp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 32db4bc..66350a7 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -1245,6 +1245,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
+     case GPG_ERR_ENETDOWN:
+     case GPG_ERR_UNKNOWN_HOST:
+     case GPG_ERR_NETWORK:
++    case GPG_ERR_EIO:  /* Sometimes used by estream cookie functions.  */
+       if (mark_host_dead (request) && *tries_left)
+         retry = 1;
+       break;
diff --git a/patches/0063-dirmngr-New-option-disable-ipv6.patch b/patches/0063-dirmngr-New-option-disable-ipv6.patch
new file mode 100644 (file)
index 0000000..6a8ea61
--- /dev/null
@@ -0,0 +1,241 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 3 Apr 2017 20:56:12 +0200
+Subject: dirmngr: New option --disable-ipv6
+
+* dirmngr/dirmngr.h (struct opt): Add field 'disable_ipv6'.
+* dirmngr/dirmngr.c (oDisableIPv6): New const.
+(opts): New option --disable-ipv6.
+(parse_rereadable_options): Set that option.
+* dirmngr/dns-stuff.c (opt_disable_ipv6): New var.
+(set_dns_disable_ipv6): New.
+(resolve_name_standard): Make use of it.
+* dirmngr/ks-engine-finger.c (ks_finger_fetch): Take care of
+OPT.DISABLE_IPV6.
+* dirmngr/ks-engine-hkp.c (map_host): Ditto.
+(send_request): Ditto.
+* dirmngr/ks-engine-http.c (ks_http_fetch): Ditto.
+* dirmngr/ocsp.c (do_ocsp_request): Ditto.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 3533b854408fa93734742b2ee12b62aa0d55ff28)
+---
+ dirmngr/crlfetch.c         |  1 +
+ dirmngr/dirmngr.c          |  4 ++++
+ dirmngr/dirmngr.h          |  3 ++-
+ dirmngr/dns-stuff.c        | 15 +++++++++++++++
+ dirmngr/dns-stuff.h        |  4 ++++
+ dirmngr/ks-engine-finger.c |  3 ++-
+ dirmngr/ks-engine-hkp.c    |  7 +++++--
+ dirmngr/ks-engine-http.c   |  3 ++-
+ dirmngr/ocsp.c             |  3 ++-
+ doc/dirmngr.texi           |  5 +++--
+ 10 files changed, 40 insertions(+), 8 deletions(-)
+
+diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
+index 337fe6e..2700cf9 100644
+--- a/dirmngr/crlfetch.c
++++ b/dirmngr/crlfetch.c
+@@ -200,6 +200,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+                                    |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0)
+                                    |(dirmngr_use_tor()? HTTP_FLAG_FORCE_TOR:0)
+                                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0)
++                                   |(opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6:0)
+                                    ),
+                                   ctrl->http_proxy, NULL, NULL, NULL);
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 43e9cbd..31d3ca2 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -112,6 +112,7 @@ enum cmd_and_opt_values {
+   oDisableHTTP,
+   oDisableLDAP,
+   oDisableIPv4,
++  oDisableIPv6,
+   oIgnoreLDAPDP,
+   oIgnoreHTTPDP,
+   oIgnoreOCSPSvcUrl,
+@@ -228,6 +229,7 @@ static ARGPARSE_OPTS opts[] = {
+   ARGPARSE_s_n (oNoUseTor, "no-use-tor", "@"),
+   ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
++  ARGPARSE_s_n (oDisableIPv6, "disable-ipv6", "@"),
+   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
+@@ -624,6 +626,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+     case oDisableHTTP: opt.disable_http = 1; break;
+     case oDisableLDAP: opt.disable_ldap = 1; break;
+     case oDisableIPv4: opt.disable_ipv4 = 1; break;
++    case oDisableIPv6: opt.disable_ipv6 = 1; break;
+     case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
+     case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
+     case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
+@@ -690,6 +693,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+   set_dns_verbose (opt.verbose, !!DBG_DNS);
+   http_set_verbose (opt.verbose, !!DBG_NETWORK);
+   set_dns_disable_ipv4 (opt.disable_ipv4);
++  set_dns_disable_ipv6 (opt.disable_ipv6);
+   return 1; /* Handled. */
+ }
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index 6a4fd00..4cc2be0 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -97,7 +97,8 @@ struct
+   int disable_http;       /* Do not use HTTP at all.  */
+   int disable_ldap;       /* Do not use LDAP at all.  */
+-  int disable_ipv4;       /* Do not use leagacy IP addresses.  */
++  int disable_ipv4;       /* Do not use legacy IP addresses.  */
++  int disable_ipv6;       /* Do not use standard IP addresses.  */
+   int honor_http_proxy;   /* Honor the http_proxy env variable. */
+   const char *http_proxy; /* The default HTTP proxy.  */
+   const char *ldap_proxy; /* Use given LDAP proxy.  */
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 150237e..ed77742 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -123,6 +123,10 @@ static int opt_timeout;
+  * returned A records.  */
+ static int opt_disable_ipv4;
++/* The flag to disable IPv6 access - right now this only skips
++ * returned AAAA records.  */
++static int opt_disable_ipv6;
++
+ /* If set force the use of the standard resolver.  */
+ static int standard_resolver;
+@@ -248,6 +252,15 @@ set_dns_disable_ipv4 (int yes)
+ }
++/* Set the Disable-IPv6 flag so that the name resolver does not return
++ * AAAA addresses.  */
++void
++set_dns_disable_ipv6 (int yes)
++{
++  opt_disable_ipv6 = !!yes;
++}
++
++
+ /* Set the timeout for libdns requests to SECONDS.  A value of 0 sets
+  * the default timeout and values are capped at 10 minutes.  */
+ void
+@@ -934,6 +947,8 @@ resolve_name_standard (const char *name, unsigned short port,
+         continue;
+       if (opt_disable_ipv4 && ai->ai_family == AF_INET)
+         continue;
++      if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
++        continue;
+       dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
+       dai->family = ai->ai_family;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index 9b8303c..71605b7 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -99,6 +99,10 @@ void set_dns_verbose (int verbose, int debug);
+  * A addresses.  */
+ void set_dns_disable_ipv4 (int yes);
++/* Set the Disable-IPv6 flag so that the name resolver does not return
++ * AAAA addresses.  */
++void set_dns_disable_ipv6 (int yes);
++
+ /* Set the timeout for libdns requests to SECONDS.  */
+ void set_dns_timeout (int seconds);
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index 811b72d..8a21c9f 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -84,7 +84,8 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+   err = http_raw_connect (&http, server, 79,
+                           ((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0)
+-                           | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++                           | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++                           | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+                           NULL);
+   if (err)
+     {
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 66350a7..7c91b6a 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -568,6 +568,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+                 continue;
+               if (opt.disable_ipv4 && ai->family == AF_INET)
+                 continue;
++              if (opt.disable_ipv6 && ai->family == AF_INET6)
++                continue;
+               dirmngr_tick (ctrl);
+               add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
+@@ -649,7 +651,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+         {
+           for (ai = aibuf; ai; ai = ai->next)
+             {
+-              if (ai->family == AF_INET6
++              if ((!opt.disable_ipv6 && ai->family == AF_INET6)
+                   || (!opt.disable_ipv4 && ai->family == AF_INET))
+                 {
+                   err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+@@ -1102,7 +1104,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+                    (httpflags
+                     |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                     |(dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+-                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++                    |(opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+                    ctrl->http_proxy,
+                    session,
+                    NULL,
+diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
+index 69642ff..6de0616 100644
+--- a/dirmngr/ks-engine-http.c
++++ b/dirmngr/ks-engine-http.c
+@@ -89,7 +89,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+                    /* fixme: AUTH */ NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                     | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+-                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++                    | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+                    ctrl->http_proxy,
+                    session,
+                    NULL,
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index aff8e32..22391c3 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -175,7 +175,8 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+   err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+                    ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+                     | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+-                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++                    | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++                    | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+                    ctrl->http_proxy, NULL, NULL, NULL);
+   if (err)
+     {
+diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
+index b00c2d3..9a7238f 100644
+--- a/doc/dirmngr.texi
++++ b/doc/dirmngr.texi
+@@ -313,9 +313,10 @@ a numerical IP address must be given (IPv6 or IPv4) and that no error
+ checking is done for @var{ipaddr}.
+ @item --disable-ipv4
++@item --disable-ipv6
+ @opindex disable-ipv4
+-Disable the use of all IPv4 addresses.  This option is mainly useful
+-for debugging.
++@opindex disable-ipv6
++Disable the use of all IPv4 or IPv6 addresses.
+ @item --disable-ldap
+ @opindex disable-ldap
diff --git a/patches/0064-agent-Serialize-access-to-passphrase-cache.patch b/patches/0064-agent-Serialize-access-to-passphrase-cache.patch
new file mode 100644 (file)
index 0000000..8231848
--- /dev/null
@@ -0,0 +1,220 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Apr 2017 08:39:26 +0900
+Subject: agent: Serialize access to passphrase cache.
+
+* agent/cache.c (encryption_lock): Remove.
+(cache_lock): New.  Now, we have coarse grain lock to serialize
+entire cache access.
+(initialize_module_cache): Use CACHE_LOCK.
+(init_encryption, new_data): Remove ENCRYPTION_LOCK.
+(agent_flush_cache, agent_put_cache, agent_get_cache): Lock the cache.
+
+--
+
+GnuPG-bug-id: 3027
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit ebe12be034f052cdec871f0d8ad1bfab85d7b943)
+---
+ agent/cache.c | 73 ++++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 37 insertions(+), 36 deletions(-)
+
+diff --git a/agent/cache.c b/agent/cache.c
+index 2483682..fead737 100644
+--- a/agent/cache.c
++++ b/agent/cache.c
+@@ -31,9 +31,8 @@
+ /* The size of the encryption key in bytes.  */
+ #define ENCRYPTION_KEYSIZE (128/8)
+-/* A mutex used to protect the encryption.  This is required because
+-   we use one context to do all encryption and decryption.  */
+-static npth_mutex_t encryption_lock;
++/* A mutex used to serialize access to the cache.  */
++static npth_mutex_t cache_lock;
+ /* The encryption context.  This is the only place where the
+    encryption key for all cached entries is available.  It would be nice
+    to keep this (or just the key) in some hardware device, for example
+@@ -76,7 +75,7 @@ initialize_module_cache (void)
+ {
+   int err;
+-  err = npth_mutex_init (&encryption_lock, NULL);
++  err = npth_mutex_init (&cache_lock, NULL);
+   if (err)
+     log_fatal ("error initializing cache module: %s\n", strerror (err));
+@@ -102,15 +101,10 @@ init_encryption (void)
+ {
+   gpg_error_t err;
+   void *key;
+-  int res;
+   if (encryption_handle)
+     return 0; /* Shortcut - Already initialized.  */
+-  res = npth_mutex_lock (&encryption_lock);
+-  if (res)
+-    log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res));
+-
+   err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
+                           GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
+   if (!err)
+@@ -133,10 +127,6 @@ init_encryption (void)
+     log_error ("error initializing cache encryption context: %s\n",
+                gpg_strerror (err));
+-  res = npth_mutex_unlock (&encryption_lock);
+-  if (res)
+-    log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+-
+   return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
+ }
+@@ -155,7 +145,6 @@ new_data (const char *string, struct secret_data_s **r_data)
+   struct secret_data_s *d, *d_enc;
+   size_t length;
+   int total;
+-  int res;
+   *r_data = NULL;
+@@ -186,17 +175,9 @@ new_data (const char *string, struct secret_data_s **r_data)
+     }
+   d_enc->totallen = total;
+-  res = npth_mutex_lock (&encryption_lock);
+-  if (res)
+-    log_fatal ("failed to acquire cache encryption mutex: %s\n",
+-               strerror (res));
+-
+   err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
+                              d->data, total - 8);
+   xfree (d);
+-  res = npth_mutex_unlock (&encryption_lock);
+-  if (res)
+-    log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+   if (err)
+     {
+       xfree (d_enc);
+@@ -281,10 +262,15 @@ void
+ agent_flush_cache (void)
+ {
+   ITEM r;
++  int res;
+   if (DBG_CACHE)
+     log_debug ("agent_flush_cache\n");
++  res = npth_mutex_lock (&cache_lock);
++  if (res)
++    log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
++
+   for (r=thecache; r; r = r->next)
+     {
+       if (r->pw)
+@@ -296,6 +282,10 @@ agent_flush_cache (void)
+           r->accessed = 0;
+         }
+     }
++
++  res = npth_mutex_unlock (&cache_lock);
++  if (res)
++    log_fatal ("failed to release cache mutex: %s\n", strerror (res));
+ }
+@@ -321,6 +311,11 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+ {
+   gpg_error_t err = 0;
+   ITEM r;
++  int res;
++
++  res = npth_mutex_lock (&cache_lock);
++  if (res)
++    log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
+   if (DBG_CACHE)
+     log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
+@@ -336,7 +331,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+         }
+     }
+   if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
+-    return 0;
++    goto out;
+   for (r=thecache; r; r = r->next)
+     {
+@@ -386,6 +381,12 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+       if (err)
+         log_error ("error inserting cache item: %s\n", gpg_strerror (err));
+     }
++
++ out:
++  res = npth_mutex_unlock (&cache_lock);
++  if (res)
++    log_fatal ("failed to release cache mutex: %s\n", strerror (res));
++
+   return err;
+ }
+@@ -405,15 +406,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+   if (cache_mode == CACHE_MODE_IGNORE)
+     return NULL;
++  res = npth_mutex_lock (&cache_lock);
++  if (res)
++    log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
++
+   if (!key)
+     {
+       key = last_stored_cache_key;
+       if (!key)
+-        return NULL;
++        goto out;
+       last_stored = 1;
+     }
+-
+   if (DBG_CACHE)
+     log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
+                key, cache_mode,
+@@ -440,17 +444,9 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+             err = gpg_error_from_syserror ();
+           else
+             {
+-              res = npth_mutex_lock (&encryption_lock);
+-              if (res)
+-                log_fatal ("failed to acquire cache encryption mutex: %s\n",
+-                         strerror (res));
+               err = gcry_cipher_decrypt (encryption_handle,
+                                          value, r->pw->totallen - 8,
+                                          r->pw->data, r->pw->totallen);
+-              res = npth_mutex_unlock (&encryption_lock);
+-              if (res)
+-                log_fatal ("failed to release cache encryption mutex: %s\n",
+-                         strerror (res));
+             }
+           if (err)
+             {
+@@ -459,13 +455,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+               log_error ("retrieving cache entry '%s' failed: %s\n",
+                          key, gpg_strerror (err));
+             }
+-          return value;
++          break;
+         }
+     }
+-  if (DBG_CACHE)
++  if (DBG_CACHE && value == NULL)
+     log_debug ("... miss\n");
+-  return NULL;
++ out:
++  res = npth_mutex_unlock (&cache_lock);
++  if (res)
++    log_fatal ("failed to release cache mutex: %s\n", strerror (res));
++
++  return value;
+ }
diff --git a/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch b/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch
new file mode 100644 (file)
index 0000000..4c17652
--- /dev/null
@@ -0,0 +1,27 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 7 Apr 2017 10:11:07 +0200
+Subject: gpg: Fix printing of offline taken subkey.
+
+* g10/keylist.c (list_keyblock_print): Set SECRET to 2 and not 0x32.
+--
+
+Reported-by: Danielle McLean <dani@00dani.me>
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 547bc01d57528ecc27b3b5e16797967a7f88fecf)
+---
+ g10/keylist.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 4078053..1998ee9 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -1017,7 +1017,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
+               if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
+                 secret = serialno? 3 : 1;
+               else
+-                secret = '2';  /* Key not found.  */
++                secret = 2;  /* Key not found.  */
+             }
+           /* Print the "sub" line.  */
diff --git a/patches/0066-doc-Explain-the-in-a-key-listing.patch b/patches/0066-doc-Explain-the-in-a-key-listing.patch
new file mode 100644 (file)
index 0000000..aba3532
--- /dev/null
@@ -0,0 +1,34 @@
+From: Werner Koch <wk@gnupg.org>
+Date: Fri, 7 Apr 2017 10:26:55 +0200
+Subject: doc: Explain the '>' in a key listing.
+
+--
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 9c9fde1495be4accf4526a2626110876fd9d788d)
+---
+ doc/gpg.texi | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index d658737..c591049 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -301,10 +301,13 @@ and other programs.
+ @itemx -K
+ @opindex list-secret-keys
+ List the specified secret keys.  If no keys are specified, then all
+-known secret keys are listed.  A @code{#} after the letters @code{sec}
+-means that the secret key is not usable (for example, if it was
+-exported using @option{--export-secret-subkeys}).  See also
+-@option{--list-keys}.
++known secret keys are listed.  A @code{#} after the intial tags
++@code{sec} or @code{ssb} means that the secret key or subkey is
++currently not usable.  We also say that this key has been taken
++offline (for example, a primary key can be taken offline by exported
++the key using the command @option{--export-secret-subkeys}).  A
++@code{>} after these tags indicate that the key is stored on a
++smartcard.  See also @option{--list-keys}.
+ @item --list-signatures
+ @opindex list-signatures
diff --git a/patches/0067-dirmngr-Fix-possible-null-reference.patch b/patches/0067-dirmngr-Fix-possible-null-reference.patch
new file mode 100644 (file)
index 0000000..d71c926
--- /dev/null
@@ -0,0 +1,28 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Wed, 12 Apr 2017 15:58:11 +0900
+Subject: dirmngr: Fix possible null reference.
+
+* dirmngr/dns.c (dns_error_t dns_trace_fput): Check NULL.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 7ae1857c90ab43ad9e31f0fb6dbd37f25cc37278)
+---
+ dirmngr/dns.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/dirmngr/dns.c b/dirmngr/dns.c
+index 869e7ed..ebfd4c3 100644
+--- a/dirmngr/dns.c
++++ b/dirmngr/dns.c
+@@ -4594,8 +4594,9 @@ dns_error_t dns_trace_fput(const struct dns_trace_event *te, const void *data, s
+       if (fwrite(&tmp, 1, headsize, fp) < headsize)
+               return errno;
+-      if (fwrite(data, 1, datasize, fp) < datasize)
+-              return errno;
++      if (data)
++              if (fwrite(data, 1, datasize, fp) < datasize)
++                      return errno;
+       if (fflush(fp))
+               return errno;
diff --git a/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch b/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch
new file mode 100644 (file)
index 0000000..821d0a9
--- /dev/null
@@ -0,0 +1,30 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Wed, 12 Apr 2017 16:01:16 +0900
+Subject: tools: Fix condition for gpg-connect-agent.
+
+* tools/gpg-connect-agent.c (start_agent): Add paren.
+
+--
+
+The intention is comparing the error code depending opt.use_dirmngr.
+Considering C Operator Precedence, we should have paren here.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit f52f6af834cc488d11612e349e4af023d69a45f4)
+---
+ tools/gpg-connect-agent.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
+index a5413cf..5af1465 100644
+--- a/tools/gpg-connect-agent.c
++++ b/tools/gpg-connect-agent.c
+@@ -2237,7 +2237,7 @@ start_agent (void)
+     {
+       if (!opt.autostart
+           && (gpg_err_code (err)
+-              == opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT))
++              == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT)))
+         {
+           /* In the no-autostart case we don't make gpg-connect-agent
+              fail on a missing server.  */
diff --git a/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch b/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch
new file mode 100644 (file)
index 0000000..ef6e2ce
--- /dev/null
@@ -0,0 +1,155 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Thu, 13 Apr 2017 14:33:33 +0900
+Subject: dirmngr: Fix alignment of ADDR.
+
+* dirmngr/dns-stuff.h (dns_addrinfo_s): Use struct sockaddr_storage
+for size and alignment.
+* dirmngr/dns-stuff.c (resolve_name_libdns): Follow the change.
+(resolve_dns_name): Use struct sockaddr_storage.
+(resolve_addr_standard, resolve_dns_addr): Likewise.
+(resolve_dns_addr): Likewise.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 892b33bb2c57785927ea6652091191da2deed464)
+---
+ dirmngr/dns-stuff.c | 31 +++++++++++++++++--------------
+ dirmngr/dns-stuff.h |  4 ++--
+ 2 files changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index ed77742..c63d958 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -827,7 +827,7 @@ resolve_name_libdns (const char *name, unsigned short port,
+             (*r_canonname)[strlen (*r_canonname)-1] = 0;
+         }
+-      dai = xtrymalloc (sizeof *dai + ent->ai_addrlen -1);
++      dai = xtrymalloc (sizeof *dai);
+       if (dai == NULL)
+         {
+           err = gpg_error_from_syserror ();
+@@ -950,7 +950,7 @@ resolve_name_standard (const char *name, unsigned short port,
+       if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
+         continue;
+-      dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
++      dai = xtrymalloc (sizeof *dai);
+       dai->family = ai->ai_family;
+       dai->socktype = ai->ai_socktype;
+       dai->protocol = ai->ai_protocol;
+@@ -1018,7 +1018,7 @@ resolve_dns_name (const char *name, unsigned short port,
+ #ifdef USE_LIBDNS
+ /* Resolve an address using libdns.  */
+ static gpg_error_t
+-resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
++resolve_addr_libdns (const struct sockaddr_storage *addr, int addrlen,
+                      unsigned int flags, char **r_name)
+ {
+   gpg_error_t err;
+@@ -1032,13 +1032,13 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+   /* First we turn ADDR into a DNS name (with ".arpa" suffix).  */
+   err = 0;
+-  if (addr->sa_family == AF_INET6)
++  if (addr->ss_family == AF_INET6)
+     {
+       const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr;
+       if (!dns_aaaa_arpa (host, sizeof host, (void*)&a6->sin6_addr))
+         err = gpg_error (GPG_ERR_INV_OBJ);
+     }
+-  else if (addr->sa_family == AF_INET)
++  else if (addr->ss_family == AF_INET)
+     {
+       const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr;
+       if (!dns_a_arpa (host, sizeof host, (void*)&a4->sin_addr))
+@@ -1126,18 +1126,19 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+       buflen = sizeof ptr.host;
+       p = buffer;
+-      if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++      if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+         {
+           *p++ = '[';
+           buflen -= 2;
+         }
+-      ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
++      ec = getnameinfo ((const struct sockaddr *)addr,
++                        addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
+       if (ec)
+         {
+           err = map_eai_to_gpg_error (ec);
+           goto leave;
+         }
+-      if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++      if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+         strcat (buffer, "]");
+     }
+@@ -1151,7 +1152,7 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+ /* Resolve an address using the standard system function.  */
+ static gpg_error_t
+-resolve_addr_standard (const struct sockaddr *addr, int addrlen,
++resolve_addr_standard (const struct sockaddr_storage *addr, int addrlen,
+                        unsigned int flags, char **r_name)
+ {
+   gpg_error_t err;
+@@ -1169,20 +1170,22 @@ resolve_addr_standard (const struct sockaddr *addr, int addrlen,
+   if ((flags & DNS_NUMERICHOST) || tor_mode)
+     ec = EAI_NONAME;
+   else
+-    ec = getnameinfo (addr, addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
++    ec = getnameinfo ((const struct sockaddr *)addr,
++                      addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
+   if (!ec && *buffer == '[')
+     ec = EAI_FAIL;  /* A name may never start with a bracket.  */
+   else if (ec == EAI_NONAME)
+     {
+       p = buffer;
+-      if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++      if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+         {
+           *p++ = '[';
+           buflen -= 2;
+         }
+-      ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
+-      if (!ec && addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++      ec = getnameinfo ((const struct sockaddr *)addr,
++                        addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
++      if (!ec && addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+         strcat (buffer, "]");
+     }
+@@ -1211,7 +1214,7 @@ resolve_addr_standard (const struct sockaddr *addr, int addrlen,
+ /* A wrapper around getnameinfo.  */
+ gpg_error_t
+-resolve_dns_addr (const struct sockaddr *addr, int addrlen,
++resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+                   unsigned int flags, char **r_name)
+ {
+   gpg_error_t err;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index 71605b7..adb0b80 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -78,7 +78,7 @@ struct dns_addrinfo_s
+   int socktype;
+   int protocol;
+   int addrlen;
+-  struct sockaddr addr[1];
++  struct sockaddr_storage addr[1];
+ };
+@@ -142,7 +142,7 @@ gpg_error_t resolve_dns_name (const char *name, unsigned short port,
+                               dns_addrinfo_t *r_dai, char **r_canonname);
+ /* Function similar to getnameinfo.  */
+-gpg_error_t resolve_dns_addr (const struct sockaddr *addr, int addrlen,
++gpg_error_t resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+                               unsigned int flags, char **r_name);
+ /* Return true if NAME is a numerical IP address.  */
diff --git a/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch b/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
new file mode 100644 (file)
index 0000000..a87e7b2
--- /dev/null
@@ -0,0 +1,70 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Thu, 13 Apr 2017 14:46:57 +0900
+Subject: dirmngr: Fix http.c for sockaddr_storage.
+
+dirmngr/http.c (use_socks): Use sockaddr_storage.
+(my_sock_new_for_addr, connect_server): Likewise.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 86dcb03134fd4957d51ebaa06b7991239f9ee56a)
+---
+ dirmngr/http.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index c9c16df..674cb3d 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -2415,13 +2415,13 @@ start_server ()
+  * This function is basically a copy of the same internal fucntion in
+  * Libassuan.  */
+ static int
+-use_socks (struct sockaddr *addr)
++use_socks (struct sockaddr_storage *addr)
+ {
+   int mode;
+   if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
+     return 0;  /* Not in Tor mode.  */
+-  else if (addr->sa_family == AF_INET6)
++  else if (addr->ss_family == AF_INET6)
+     {
+       struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
+       const unsigned char *s;
+@@ -2436,7 +2436,7 @@ use_socks (struct sockaddr *addr)
+       return 0; /* This is the loopback address.  */
+     }
+-  else if (addr->sa_family == AF_INET)
++  else if (addr->ss_family == AF_INET)
+     {
+       struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+@@ -2453,7 +2453,7 @@ use_socks (struct sockaddr *addr)
+ /* Wrapper around assuan_sock_new which takes the domain from an
+  * address parameter.  */
+ static assuan_fd_t
+-my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
++my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
+ {
+   int domain;
+@@ -2464,7 +2464,7 @@ my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
+       domain = AF_INET;
+     }
+   else
+-    domain = addr->sa_family;
++    domain = addr->ss_family;
+   return assuan_sock_new (domain, type, proto);
+ }
+@@ -2589,7 +2589,8 @@ connect_server (const char *server, unsigned short port,
+             }
+           anyhostaddr = 1;
+-          if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
++          if (assuan_sock_connect (sock, (struct sockaddr *)ai->addr,
++                                   ai->addrlen))
+             {
+               last_err = gpg_err_make (default_errsource,
+                                        gpg_err_code_from_syserror ());
diff --git a/patches/0071-g10-Fix-import-export-filter-property-match.patch b/patches/0071-g10-Fix-import-export-filter-property-match.patch
new file mode 100644 (file)
index 0000000..5c96039
--- /dev/null
@@ -0,0 +1,25 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Mon, 17 Apr 2017 09:08:31 +0900
+Subject: g10: Fix import/export filter property match.
+
+* g10/import.c (impex_filter_getval): Fix to "else if".
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit af5f8ecf51f5e1f33e832d4946d02313b78a0536)
+---
+ g10/import.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index 4e6f692..125b994 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1235,7 +1235,7 @@ impex_filter_getval (void *cookie, const char *propname)
+           snprintf (numbuf, sizeof numbuf, "%d", pk->pubkey_algo);
+           result = numbuf;
+         }
+-      if (!strcmp (propname, "key_created"))
++      else if (!strcmp (propname, "key_created"))
+         {
+           snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->timestamp);
+           result = numbuf;
diff --git a/patches/0072-g10-Minor-fixes.patch b/patches/0072-g10-Minor-fixes.patch
new file mode 100644 (file)
index 0000000..774e57d
--- /dev/null
@@ -0,0 +1,66 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Mon, 17 Apr 2017 09:15:13 +0900
+Subject: g10: Minor fixes.
+
+* g10/export.c (cleartext_secret_key_to_openpgp): No initialization.
+(do_export_one_keyblock): Initialize with GPG_ERR_NOT_FOUND.
+* g10/getkey.c (get_best_pubkey_byname): Add non-null check.
+* g10/tofu.c (tofu_set_policy): ERR initialize to 0.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 0dec0cc281dfa26db89f8cc5ee002dea5c2b2e81)
+---
+ g10/export.c | 4 ++--
+ g10/getkey.c | 3 ++-
+ g10/tofu.c   | 2 +-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/g10/export.c b/g10/export.c
+index 207f994..ea9ffb4 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -580,7 +580,7 @@ canon_pk_algo (enum gcry_pk_algos algo)
+ static gpg_error_t
+ cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
+ {
+-  gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
++  gpg_error_t err;
+   gcry_sexp_t top_list;
+   gcry_sexp_t key = NULL;
+   char *key_type = NULL;
+@@ -1524,7 +1524,7 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
+                         KEYDB_SEARCH_DESC *desc, size_t ndesc,
+                         size_t descindex, gcry_cipher_hd_t cipherhd)
+ {
+-  gpg_error_t err;
++  gpg_error_t err = gpg_error (GPG_ERR_NOT_FOUND);
+   char *cache_nonce = NULL;
+   subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
+   int skip_until_subkey = 0;
+diff --git a/g10/getkey.c b/g10/getkey.c
+index 21dcf08..961d7de 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -1640,7 +1640,8 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+                   if (! ctx->kr_handle)
+                     {
+                       xfree (ctx);
+-                      *retctx = NULL;
++                      if (retctx)
++                        *retctx = NULL;
+                       rc = gpg_error_from_syserror ();
+                     }
+                   else
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 39457a5..c3a4988 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -3857,7 +3857,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+ gpg_error_t
+ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy)
+ {
+-  gpg_error_t err;
++  gpg_error_t err = 0;
+   time_t now = gnupg_get_time ();
+   tofu_dbs_t dbs;
+   PKT_public_key *pk;
diff --git a/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch b/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
new file mode 100644 (file)
index 0000000..0963208
--- /dev/null
@@ -0,0 +1,52 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Tue, 18 Apr 2017 09:04:11 +0900
+Subject: dirmngr: Fix final close of LISTEN_FD.
+
+* dirmngr/dirmngr.c (handle_connections): Close LISTEN_FD.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 4b2581dc0ea1d03e70023bb0748aa0c21c0a2173)
+---
+ dirmngr/dirmngr.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 31d3ca2..513e2a6 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -1905,7 +1905,6 @@ handle_connections (assuan_fd_t listen_fd)
+ #endif
+   struct sockaddr_un paddr;
+   socklen_t plen = sizeof( paddr );
+-  gnupg_fd_t fd;
+   int nfd, ret;
+   fd_set fdset, read_fdset;
+   int saved_errno;
+@@ -2030,6 +2029,8 @@ handle_connections (assuan_fd_t listen_fd)
+       if (FD_ISSET (FD2INT (listen_fd), &read_fdset))
+       {
++          gnupg_fd_t fd;
++
+           plen = sizeof paddr;
+         fd = INT2FD (npth_accept (FD2INT(listen_fd),
+                                   (struct sockaddr *)&paddr, &plen));
+@@ -2058,7 +2059,6 @@ handle_connections (assuan_fd_t listen_fd)
+                 }
+             npth_setname_np (thread, threadname);
+             }
+-          fd = GNUPG_INVALID_FD;
+       }
+     }
+@@ -2067,8 +2067,8 @@ handle_connections (assuan_fd_t listen_fd)
+     close (my_inotify_fd);
+ #endif /*HAVE_INOTIFY_INIT*/
+   npth_attr_destroy (&tattr);
+-  if (listen_fd != -1)
+-    assuan_sock_close (fd);
++  if (listen_fd != GNUPG_INVALID_FD)
++    assuan_sock_close (listen_fd);
+   cleanup ();
+   log_info ("%s %s stopped\n", strusage(11), strusage(13));
+ }
diff --git a/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch b/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch
new file mode 100644 (file)
index 0000000..e366af1
--- /dev/null
@@ -0,0 +1,41 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Tue, 25 Apr 2017 07:48:51 +0900
+Subject: g10: invalidate the fd cache for keyring.
+
+* g10/keyring.c (keyring_search_reset): Don't keep the FD cache.
+
+--
+
+GnuPG-bug-id: 3096
+Fixes-commit: 5556eca5acd46983bff0b38a1ffbc2f07fbaba9f
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 116cfd60779fbb3540da629db54dc2e148f4a3a2)
+---
+ g10/keyring.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keyring.c b/g10/keyring.c
+index 328290e..d75fdbc 100644
+--- a/g10/keyring.c
++++ b/g10/keyring.c
+@@ -692,7 +692,6 @@ keyring_search_reset (KEYRING_HANDLE hd)
+ {
+     log_assert (hd);
+-    hd->current.kr = NULL;
+     iobuf_close (hd->current.iobuf);
+     hd->current.iobuf = NULL;
+     hd->current.eof = 0;
+@@ -700,6 +699,12 @@ keyring_search_reset (KEYRING_HANDLE hd)
+     hd->found.kr = NULL;
+     hd->found.offset = 0;
++
++    if (hd->current.kr)
++      iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0,
++                   (char*)hd->current.kr->fname);
++    hd->current.kr = NULL;
++
+     return 0;
+ }
diff --git a/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch b/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
new file mode 100644 (file)
index 0000000..07c2b54
--- /dev/null
@@ -0,0 +1,89 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Tue, 25 Apr 2017 21:00:41 +0900
+Subject: dirmngr: Fix aliasing problem in dns.c.
+
+* dirmngr/dns.c (dns_ai_setent): Care about aliasing.
+
+--
+
+Co-authored-by: Tomas Mraz
+GnuPG-bug-id: 3105
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 247932f367f856e7ce91528e14f0aaf838150857)
+---
+ dirmngr/dns.c | 34 ++++++++++++++++++----------------
+ 1 file changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/dns.c b/dirmngr/dns.c
+index ebfd4c3..866f69d 100644
+--- a/dirmngr/dns.c
++++ b/dirmngr/dns.c
+@@ -9440,29 +9440,31 @@ void dns_ai_close(struct dns_addrinfo *ai) {
+ static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_type type, struct dns_addrinfo *ai) {
+-      struct sockaddr *saddr;
+-      struct sockaddr_in sin;
+-      struct sockaddr_in6 sin6;
++      union u {
++              struct sockaddr_in sin;
++              struct sockaddr_in6 sin6;
++              struct sockaddr_storage ss;
++      } addr;
+       const char *cname;
+       size_t clen;
+       switch (type) {
+       case DNS_T_A:
+-              saddr   = memset(&sin, '\0', sizeof sin);
++              memset(&addr.sin, '\0', sizeof addr.sin);
+-              sin.sin_family  = AF_INET;
+-              sin.sin_port    = htons(ai->port);
++              addr.sin.sin_family     = AF_INET;
++              addr.sin.sin_port       = htons(ai->port);
+-              memcpy(&sin.sin_addr, any, sizeof sin.sin_addr);
++              memcpy(&addr.sin.sin_addr, any, sizeof addr.sin.sin_addr);
+               break;
+       case DNS_T_AAAA:
+-              saddr   = memset(&sin6, '\0', sizeof sin6);
++              memset(&addr.sin6, '\0', sizeof addr.sin6);
+-              sin6.sin6_family        = AF_INET6;
+-              sin6.sin6_port          = htons(ai->port);
++              addr.sin6.sin6_family   = AF_INET6;
++              addr.sin6.sin6_port     = htons(ai->port);
+-              memcpy(&sin6.sin6_addr, any, sizeof sin6.sin6_addr);
++              memcpy(&addr.sin6.sin6_addr, any, sizeof addr.sin6.sin6_addr);
+               break;
+       default:
+@@ -9477,20 +9479,20 @@ static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_typ
+               clen    = 0;
+       }
+-      if (!(*ent = malloc(sizeof **ent + dns_sa_len(saddr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0))))
++      if (!(*ent = malloc(sizeof **ent + dns_sa_len(&addr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0))))
+               return dns_syerr();
+       memset(*ent, '\0', sizeof **ent);
+-      (*ent)->ai_family       = saddr->sa_family;
++      (*ent)->ai_family       = addr.ss.ss_family;
+       (*ent)->ai_socktype     = ai->hints.ai_socktype;
+       (*ent)->ai_protocol     = ai->hints.ai_protocol;
+-      (*ent)->ai_addr         = memcpy((unsigned char *)*ent + sizeof **ent, saddr, dns_sa_len(saddr));
+-      (*ent)->ai_addrlen      = dns_sa_len(saddr);
++      (*ent)->ai_addr         = memcpy((unsigned char *)*ent + sizeof **ent, &addr, dns_sa_len(&addr));
++      (*ent)->ai_addrlen      = dns_sa_len(&addr);
+       if (ai->hints.ai_flags & AI_CANONNAME)
+-              (*ent)->ai_canonname    = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(saddr), cname, clen + 1);
++              (*ent)->ai_canonname    = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(&addr), cname, clen + 1);
+       ai->found++;
diff --git a/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch b/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch
new file mode 100644 (file)
index 0000000..d0d7921
--- /dev/null
@@ -0,0 +1,39 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Fri, 5 May 2017 22:37:23 -0400
+Subject: gpg: Avoid spurious warnings about trust packets.
+
+* g10/keydb.c (parse_keyblock_image): Do not emit a warning when
+skipping a trust packet.
+
+--
+
+2.1.20 and later store trust packets in the keybox.  If an older
+version (like 2.1.18) ends up accessing a keybox that 2.1.20 or later
+has used, it produces many spurious warnings like:
+
+    gpg: skipped packet of type 12 in keybox
+
+This is a temporary cleanup to avoid these specific warnings; it can
+be dropped when moving to 2.1.20 or later.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ g10/keydb.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/g10/keydb.c b/g10/keydb.c
+index aab90e3..81dd32e 100644
+--- a/g10/keydb.c
++++ b/g10/keydb.c
+@@ -1205,8 +1205,9 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
+         default:
+           /* Note that can't allow ring trust packets here and some of
+              the other GPG specific packets don't make sense either.  */
+-          log_error ("skipped packet of type %d in keybox\n",
+-                     (int)pkt->pkttype);
++          if (pkt->pkttype != PKT_RING_TRUST)
++            log_error ("skipped packet of type %d in keybox\n",
++                       (int)pkt->pkttype);
+           free_packet(pkt);
+           init_packet(pkt);
+           continue;
diff --git a/patches/block-ptrace-on-agent/0002-Avoid-simple-memory-dumps-via-ptrace.patch b/patches/block-ptrace-on-agent/0002-Avoid-simple-memory-dumps-via-ptrace.patch
new file mode 100644 (file)
index 0000000..96a8e0d
--- /dev/null
@@ -0,0 +1,60 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Tue, 11 Aug 2015 20:28:26 -0400
+Subject: Avoid simple memory dumps via ptrace
+
+This avoids needing to setgid gpg-agent.  It probably doesn't defend
+against all possible attacks, but it defends against one specific (and
+easy) one.  If there are other protections we should do them too.
+
+This will make it slightly harder to debug the agent because the
+normal user won't be able to attach gdb to it directly while it runs.
+
+The remaining options for debugging are:
+
+ * launch the agent from gdb directly
+ * connect gdb to a running agent as the superuser
+
+Upstream bug: https://bugs.gnupg.org/gnupg/issue1211
+---
+ agent/gpg-agent.c | 8 ++++++++
+ configure.ac      | 1 +
+ 2 files changed, 9 insertions(+)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index c0208cc88..31bf3370a 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -48,6 +48,9 @@
+ # include <signal.h>
+ #endif
+ #include <npth.h>
++#ifdef HAVE_PRCTL
++# include <sys/prctl.h>
++#endif
+ #define GNUPG_COMMON_NEED_AFLOCAL
+ #include "agent.h"
+@@ -949,6 +952,11 @@ main (int argc, char **argv )
+   early_system_init ();
++#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
++  /* Disable ptrace on Linux without sgid bit */
++  prctl(PR_SET_DUMPABLE, 0);
++#endif
++
+   /* Before we do anything else we save the list of currently open
+      file descriptors and the signal mask.  This info is required to
+      do the exec call properly.  We don't need it on Windows.  */
+diff --git a/configure.ac b/configure.ac
+index f929cb60f..f2b6a70d2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1335,6 +1335,7 @@ AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap canonicalize_file_name])
+ AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r strtoull])
+ AC_CHECK_FUNCS([setenv unsetenv fcntl ftruncate inet_ntop])
+ AC_CHECK_FUNCS([canonicalize_file_name])
++AC_CHECK_FUNCS([prctl])
+ AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime])
+ AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale])
+ AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo])
diff --git a/patches/debian-packaging/0001-avoid-beta-warning.patch b/patches/debian-packaging/0001-avoid-beta-warning.patch
new file mode 100644 (file)
index 0000000..ea08ce8
--- /dev/null
@@ -0,0 +1,44 @@
+From: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
+Date: Tue, 14 Apr 2015 10:02:31 -0400
+Subject: avoid-beta-warning
+
+avoid self-describing as a beta
+
+Using autoreconf against the source as distributed in tarball form
+invariably results in a package that thinks it's a "beta" package,
+which produces the "THIS IS A DEVELOPMENT VERSION" warning string.
+
+since we use dh_autoreconf, i need this patch to avoid producing
+builds that announce themselves as DEVELOPMENT VERSIONs.
+
+See discussion at:
+
+ http://lists.gnupg.org/pipermail/gnupg-devel/2014-November/029065.html
+---
+ autogen.sh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/autogen.sh b/autogen.sh
+index e5ba5bf05..d7bab0383 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -229,7 +229,7 @@ if [ "$myhost" = "find-version" ]; then
+     esac
+     beta=no
+-    if [ -e .git ]; then
++    if false; then
+       ingit=yes
+       tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null)
+       tmp=$(echo "$tmp" | sed s/^"$package"//)
+@@ -245,8 +245,8 @@ if [ "$myhost" = "find-version" ]; then
+       rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null)))
+     else
+       ingit=no
+-      beta=yes
+-      tmp="-unknown"
++      beta=no
++      tmp=""
+       rev="0000000"
+       rvd="0"
+     fi
diff --git a/patches/debian-packaging/0003-avoid-regenerating-defsincdate-use-shipped-file.patch b/patches/debian-packaging/0003-avoid-regenerating-defsincdate-use-shipped-file.patch
new file mode 100644 (file)
index 0000000..c141e4f
--- /dev/null
@@ -0,0 +1,37 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Mon, 29 Aug 2016 12:34:42 -0400
+Subject: avoid regenerating defsincdate (use shipped file)
+
+upstream ships doc/defsincdate in its tarballs.  but doc/Makefile.am
+tries to rewrite doc/defsincdate if it notices that any of the files
+have been modified more recently, and it does so assuming that we're
+running from a git repo.
+
+However, we'd rather ship the documents cleanly without regenerating
+defsincdate -- we don't have a git repo available (debian builds from
+upstream tarballs) and any changes to the texinfo files (e.g. from
+debian/patches/) might result in different dates on the files than we
+expect after they're applied by dpkg or quilt or whatever, which makes
+the datestamp unreproducible.
+---
+ doc/Makefile.am | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index 0c2f2c9dc..65b941ca7 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -167,13 +167,6 @@ $(myman_pages) gnupg.7 : yat2m-stamp defs.inc
+ dist-hook: defsincdate
+-defsincdate: $(gnupg_TEXINFOS)
+-      : >defsincdate ; \
+-      if test -e $(top_srcdir)/.git; then \
+-        (cd $(srcdir) && git log -1 --format='%ct' \
+-               -- $(gnupg_TEXINFOS) 2>/dev/null) >>defsincdate; \
+-      fi
+-
+ defs.inc : defsincdate Makefile mkdefsinc
+       incd="`test -f defsincdate || echo '$(srcdir)/'`defsincdate"; \
+       ./mkdefsinc -C $(srcdir) --date "`cat $$incd 2>/dev/null`" \
diff --git a/patches/dirmngr-idling/0001-dirmngr-hkp-Avoid-potential-race-condition-when-some.patch b/patches/dirmngr-idling/0001-dirmngr-hkp-Avoid-potential-race-condition-when-some.patch
new file mode 100644 (file)
index 0000000..f1bcde3
--- /dev/null
@@ -0,0 +1,77 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sat, 29 Oct 2016 01:25:05 -0400
+Subject: dirmngr: hkp: Avoid potential race condition when some hosts die.
+
+* dirmngr/ks-engine-hkp.c (select_random_host): Use atomic pass
+through the host table instead of risking out-of-bounds write.
+
+--
+
+Multiple threads may write to hosttable[x]->dead while
+select_random_host() is running.  For example, a housekeeping thread
+might clear the ->dead bit on some entries, or another connection to
+dirmngr might manually mark a host as alive.
+
+If one or more hosts are resurrected between the two loops over a
+given table in select_random_host(), then the allocation of tbl might
+not be large enough, resulting in a write past the end of tbl on the
+second loop.
+
+This change collapses the two loops into a single loop to avoid this
+discrepancy: each host's "dead" bit is now only checked once.
+
+As Werner points out, this isn't currently strictly necessary, since
+npth will not switch threads unless a blocking system call is made,
+and no blocking system call is made in these two loops.
+
+However, in a subsequent change in this series, we will call a
+function in this loop, and that function may sometimes write(2), or
+call other functions, which may themselves block.  Keeping this as a
+single-pass loop avoids the need to keep track of what might block and
+what might not.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ dirmngr/ks-engine-hkp.c | 21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 45965cecc..57e7529f3 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -209,25 +209,24 @@ host_in_pool_p (int *pool, int tblidx)
+ static int
+ select_random_host (int *table)
+ {
+-  int *tbl;
+-  size_t tblsize;
++  int *tbl = NULL;
++  size_t tblsize = 0;
+   int pidx, idx;
+   /* We create a new table so that we randomly select only from
+      currently alive hosts.  */
+-  for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
++  for (idx=0; (pidx = table[idx]) != -1; idx++)
+     if (hosttable[pidx] && !hosttable[pidx]->dead)
+-      tblsize++;
++      {
++        tblsize++;
++        tbl = xtryrealloc(tbl, tblsize * sizeof *tbl);
++        if (!tbl)
++          return -1; /* memory allocation failed! */
++        tbl[tblsize-1] = pidx;
++      }
+   if (!tblsize)
+     return -1; /* No hosts.  */
+-  tbl = xtrymalloc (tblsize * sizeof *tbl);
+-  if (!tbl)
+-    return -1;
+-  for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
+-    if (hosttable[pidx] && !hosttable[pidx]->dead)
+-      tbl[tblsize++] = pidx;
+-
+   if (tblsize == 1)  /* Save a get_uint_nonce.  */
+     pidx = tbl[0];
+   else
diff --git a/patches/dirmngr-idling/0002-dimrngr-Avoid-need-for-hkp-housekeeping.patch b/patches/dirmngr-idling/0002-dimrngr-Avoid-need-for-hkp-housekeeping.patch
new file mode 100644 (file)
index 0000000..c23485c
--- /dev/null
@@ -0,0 +1,225 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sat, 29 Oct 2016 02:00:50 -0400
+Subject: dimrngr: Avoid need for hkp housekeeping.
+
+* dirmngr/ks-engine-hkp.c (host_is_alive): New function.  Test whether
+host is alive and resurrects it if it has been dead long enough.
+(select_random_host, map_host, ks_hkp_mark_host): Use host_is_alive
+instead of testing hostinfo_t->dead directly.
+(ks_hkp_housekeeping): Remove function, no longer needed.
+* dirmngr/dirmngr.c (housekeeping_thread): Remove call to
+ks_hkp_housekeeping.
+
+--
+
+Rather than resurrecting hosts upon scheduled resurrection times, test
+whether hosts should be resurrected as they're inspected for being
+dead.  This removes the need for explicit housekeeping, and makes host
+resurrections happen "just in time", rather than being clustered on
+HOUSEKEEPING_INTERVAL seconds.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ dirmngr/dirmngr.c       |  3 --
+ dirmngr/dirmngr.h       |  1 -
+ dirmngr/ks-engine-hkp.c | 73 ++++++++++++++++++++++++-------------------------
+ 3 files changed, 36 insertions(+), 41 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 061cfc300..a8be56fa4 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -1771,12 +1771,10 @@ static void *
+ housekeeping_thread (void *arg)
+ {
+   static int sentinel;
+-  time_t curtime;
+   struct server_control_s ctrlbuf;
+   (void)arg;
+-  curtime = gnupg_get_time ();
+   if (sentinel)
+     {
+       log_info ("housekeeping is already going on\n");
+@@ -1789,7 +1787,6 @@ housekeeping_thread (void *arg)
+   memset (&ctrlbuf, 0, sizeof ctrlbuf);
+   dirmngr_init_default_ctrl (&ctrlbuf);
+-  ks_hkp_housekeeping (curtime);
+   if (network_activity_seen)
+     {
+       network_activity_seen = 0;
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index 35bc000fb..acd4c636d 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -193,7 +193,6 @@ const char* dirmngr_get_current_socket_name (void);
+ /*-- Various housekeeping functions.  --*/
+-void ks_hkp_housekeeping (time_t curtime);
+ void ks_hkp_reload (void);
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 57e7529f3..2b90441e2 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -203,6 +203,25 @@ host_in_pool_p (int *pool, int tblidx)
+ }
++static int
++host_is_alive (hostinfo_t hi, time_t curtime)
++{
++  if (!hi)
++    return 0;
++  if (!hi->dead)
++    return 1;
++  if (!hi->died_at)
++    return 0; /* manually marked dead */
++  if (hi->died_at + RESURRECT_INTERVAL <= curtime
++      || hi->died_at > curtime)
++    {
++      hi->dead = 0;
++      log_info ("resurrected host '%s'", hi->name);
++      return 1;
++    }
++  return 0;
++}
++
+ /* Select a random host.  Consult TABLE which indices into the global
+    hosttable.  Returns index into TABLE or -1 if no host could be
+    selected.  */
+@@ -212,11 +231,13 @@ select_random_host (int *table)
+   int *tbl = NULL;
+   size_t tblsize = 0;
+   int pidx, idx;
++  time_t curtime;
++  curtime = gnupg_get_time ();
+   /* We create a new table so that we randomly select only from
+      currently alive hosts.  */
+   for (idx=0; (pidx = table[idx]) != -1; idx++)
+-    if (hosttable[pidx] && !hosttable[pidx]->dead)
++    if (hosttable[pidx] && host_is_alive (hosttable[pidx], curtime))
+       {
+         tblsize++;
+         tbl = xtryrealloc(tbl, tblsize * sizeof *tbl);
+@@ -395,6 +416,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+   gpg_error_t err = 0;
+   hostinfo_t hi;
+   int idx;
++  time_t curtime;
+   *r_host = NULL;
+   if (r_httpflags)
+@@ -531,6 +553,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+         xfree (reftbl);
+     }
++  curtime = gnupg_get_time ();
+   hi = hosttable[idx];
+   if (hi->pool)
+     {
+@@ -547,7 +570,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+       if (force_reselect)
+         hi->poolidx = -1;
+       else if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
+-               && hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
++               && hosttable[hi->poolidx] && !host_is_alive (hosttable[hi->poolidx], curtime))
+         hi->poolidx = -1;
+       /* Select a host if needed.  */
+@@ -599,7 +622,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+       free_dns_addrinfo (aibuf);
+     }
+-  if (hi->dead)
++  if (!host_is_alive (hi, curtime))
+     {
+       log_error ("host '%s' marked as dead\n", hi->name);
+       if (r_httphost)
+@@ -704,7 +727,8 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
+ {
+   gpg_error_t err = 0;
+   hostinfo_t hi, hi2;
+-  int idx, idx2, idx3, n;
++  int idx, idx2, idx3, n, is_alive;
++  time_t curtime;
+   if (!name || !*name || !strcmp (name, "localhost"))
+     return 0;
+@@ -713,13 +737,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
+   if (idx == -1)
+     return gpg_error (GPG_ERR_NOT_FOUND);
++  curtime = gnupg_get_time ();
+   hi = hosttable[idx];
+-  if (alive && hi->dead)
++  is_alive = host_is_alive (hi, curtime);
++  if (alive && !is_alive)
+     {
+       hi->dead = 0;
+       err = ks_printf_help (ctrl, "marking '%s' as alive", name);
+     }
+-  else if (!alive && !hi->dead)
++  else if (!alive && is_alive)
+     {
+       hi->dead = 1;
+       hi->died_at = 0; /* Manually set dead.  */
+@@ -751,14 +777,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
+           hi2 = hosttable[n];
+           if (!hi2)
+-            ;
+-          else if (alive && hi2->dead)
++            continue;
++          is_alive = host_is_alive (hi2, curtime);
++          if (alive && !is_alive)
+             {
+               hi2->dead = 0;
+               err = ks_printf_help (ctrl, "marking '%s' as alive",
+                                     hi2->name);
+             }
+-          else if (!alive && !hi2->dead)
++          else if (!alive && is_alive)
+             {
+               hi2->dead = 1;
+               hi2->died_at = 0; /* Manually set dead. */
+@@ -974,34 +1001,6 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
+ }
+-/* Housekeeping function called from the housekeeping thread.  It is
+-   used to mark dead hosts alive so that they may be tried again after
+-   some time.  */
+-void
+-ks_hkp_housekeeping (time_t curtime)
+-{
+-  int idx;
+-  hostinfo_t hi;
+-
+-  for (idx=0; idx < hosttable_size; idx++)
+-    {
+-      hi = hosttable[idx];
+-      if (!hi)
+-        continue;
+-      if (!hi->dead)
+-        continue;
+-      if (!hi->died_at)
+-        continue; /* Do not resurrect manually shot hosts.  */
+-      if (hi->died_at + RESURRECT_INTERVAL <= curtime
+-          || hi->died_at > curtime)
+-        {
+-          hi->dead = 0;
+-          log_info ("resurrected host '%s'", hi->name);
+-        }
+-    }
+-}
+-
+-
+ /* Reload (SIGHUP) action for this module.  We mark all host alive
+  * even those which have been manually shot.  */
+ void
diff --git a/patches/dirmngr-idling/0004-dirmngr-Avoid-automatically-checking-upstream-swdb.patch b/patches/dirmngr-idling/0004-dirmngr-Avoid-automatically-checking-upstream-swdb.patch
new file mode 100644 (file)
index 0000000..7791852
--- /dev/null
@@ -0,0 +1,69 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sun, 20 Nov 2016 23:09:24 -0500
+Subject: dirmngr: Avoid automatically checking upstream swdb.
+
+* dirmngr/dirmngr.c (housekeeping_thread): Avoid automatically
+checking upstream's software database.  In Debian, software updates
+should be handled by the distro mechanism, and additional upstream
+checks only confuse the user.
+* doc/dirmngr.texi: document that --allow-version-check does nothing.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ dirmngr/dirmngr.c | 13 -------------
+ doc/dirmngr.texi  | 11 +++++------
+ 2 files changed, 5 insertions(+), 19 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index a8be56fa4..746f43d10 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -1771,7 +1771,6 @@ static void *
+ housekeeping_thread (void *arg)
+ {
+   static int sentinel;
+-  struct server_control_s ctrlbuf;
+   (void)arg;
+@@ -1784,18 +1783,6 @@ housekeeping_thread (void *arg)
+   if (opt.verbose > 1)
+     log_info ("starting housekeeping\n");
+-  memset (&ctrlbuf, 0, sizeof ctrlbuf);
+-  dirmngr_init_default_ctrl (&ctrlbuf);
+-
+-  if (network_activity_seen)
+-    {
+-      network_activity_seen = 0;
+-      if (opt.use_tor || opt.allow_version_check)
+-        dirmngr_load_swdb (&ctrlbuf, 0);
+-    }
+-
+-  dirmngr_deinit_default_ctrl (&ctrlbuf);
+-
+   if (opt.verbose > 1)
+     log_info ("ready with housekeeping\n");
+   sentinel--;
+diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
+index e27157c00..dd104273d 100644
+--- a/doc/dirmngr.texi
++++ b/doc/dirmngr.texi
+@@ -266,12 +266,11 @@ seconds.
+ @item --allow-version-check
+ @opindex allow-version-check
+ Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get
+-the list of current software versions.  If this option is enabled, or
+-if @option{use-tor} is active, the list is retrieved when the local
+-copy does not exist or is older than 5 to 7 days.  See the option
+-@option{--query-swdb} of the command @command{gpgconf} for more
+-details.  Note, that regardless of this option a version check can
+-always be triggered using this command:
++the list of current software versions.  On debian-packaged versions,
++this option does nothing since software updates should be handled by
++the distribution.  See the option @option{--query-swdb} of the command
++@command{gpgconf} for more details.  Note, that regardless of this
++option a version check can always be triggered using this command:
+ @example
+        gpg-connect-agent --dirmngr 'loadswdb --force' /bye
diff --git a/patches/dirmngr-idling/0005-dirmngr-Drop-useless-housekeeping.patch b/patches/dirmngr-idling/0005-dirmngr-Drop-useless-housekeeping.patch
new file mode 100644 (file)
index 0000000..69bdc9d
--- /dev/null
@@ -0,0 +1,199 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Sat, 29 Oct 2016 02:15:08 -0400
+Subject: dirmngr: Drop useless housekeeping.
+
+* dirmngr/dirmngr.c (handle_tick, time_for_housekeeping_p,
+housekeeping_thread): Remove, no longer needed.
+(handle_connections): Drop any attempt at a timeout, since no
+housekeeping is necessary.
+
+--
+
+The housekeeping thread no longer does anything, and the main loop was
+waking up every 60 seconds for no good reason.  The code is simpler
+and the runtime is more efficient if we drop this.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ dirmngr/dirmngr.c | 113 +++---------------------------------------------------
+ 1 file changed, 5 insertions(+), 108 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 746f43d10..8d9de9e5a 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -304,13 +304,6 @@ static int active_connections;
+  * thread to run background network tasks.  */
+ static int network_activity_seen;
+-/* The timer tick used for housekeeping stuff.  */
+-#define TIMERTICK_INTERVAL         (60)
+-
+-/* How oft to run the housekeeping.  */
+-#define HOUSEKEEPING_INTERVAL      (600)
+-
+-
+ /* This union is used to avoid compiler warnings in case a pointer is
+    64 bit and an int 32 bit.  We store an integer in a pointer and get
+    it back later (npth_getspecific et al.).  */
+@@ -1766,83 +1759,6 @@ handle_signal (int signo)
+ #endif /*!HAVE_W32_SYSTEM*/
+-/* Thread to do the housekeeping.  */
+-static void *
+-housekeeping_thread (void *arg)
+-{
+-  static int sentinel;
+-
+-  (void)arg;
+-
+-  if (sentinel)
+-    {
+-      log_info ("housekeeping is already going on\n");
+-      return NULL;
+-    }
+-  sentinel++;
+-  if (opt.verbose > 1)
+-    log_info ("starting housekeeping\n");
+-
+-  if (opt.verbose > 1)
+-    log_info ("ready with housekeeping\n");
+-  sentinel--;
+-  return NULL;
+-
+-}
+-
+-
+-#if GPGRT_GCC_HAVE_PUSH_PRAGMA
+-# pragma GCC push_options
+-# pragma GCC optimize ("no-strict-overflow")
+-#endif
+-static int
+-time_for_housekeeping_p (time_t curtime)
+-{
+-  static time_t last_housekeeping;
+-
+-  if (!last_housekeeping)
+-    last_housekeeping = curtime;
+-
+-  if (last_housekeeping + HOUSEKEEPING_INTERVAL <= curtime
+-      || last_housekeeping > curtime /*(be prepared for y2038)*/)
+-    {
+-      last_housekeeping = curtime;
+-      return 1;
+-    }
+-  return 0;
+-}
+-#if GPGRT_GCC_HAVE_PUSH_PRAGMA
+-# pragma GCC pop_options
+-#endif
+-
+-
+-/* This is the worker for the ticker.  It is called every few seconds
+-   and may only do fast operations. */
+-static void
+-handle_tick (void)
+-{
+-  if (time_for_housekeeping_p (gnupg_get_time ()))
+-    {
+-      npth_t thread;
+-      npth_attr_t tattr;
+-      int err;
+-
+-      err = npth_attr_init (&tattr);
+-      if (err)
+-        log_error ("error preparing housekeeping thread: %s\n", strerror (err));
+-      else
+-        {
+-          npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+-          err = npth_create (&thread, &tattr, housekeeping_thread, NULL);
+-          if (err)
+-            log_error ("error spawning housekeeping thread: %s\n",
+-                       strerror (err));
+-          npth_attr_destroy (&tattr);
+-        }
+-    }
+-}
+-
+-
+ /* Check the nonce on a new connection.  This is a NOP unless we are
+    using our Unix domain socket emulation under Windows.  */
+ static int
+@@ -1943,9 +1859,6 @@ handle_connections (assuan_fd_t listen_fd)
+   gnupg_fd_t fd;
+   int nfd, ret;
+   fd_set fdset, read_fdset;
+-  struct timespec abstime;
+-  struct timespec curtime;
+-  struct timespec timeout;
+   int saved_errno;
+   int my_inotify_fd = -1;
+@@ -1985,9 +1898,7 @@ handle_connections (assuan_fd_t listen_fd)
+ #endif /*HAVE_INOTIFY_INIT*/
+-  /* Setup the fdset.  It has only one member.  This is because we use
+-     pth_select instead of pth_accept to properly sync timeouts with
+-     to full second.  */
++  /* Setup the fdset.  */
+   FD_ZERO (&fdset);
+   FD_SET (FD2INT (listen_fd), &fdset);
+   nfd = FD2INT (listen_fd);
+@@ -1998,9 +1909,6 @@ handle_connections (assuan_fd_t listen_fd)
+         nfd = my_inotify_fd;
+     }
+-  npth_clock_gettime (&abstime);
+-  abstime.tv_sec += TIMERTICK_INTERVAL;
+-
+   /* Main loop.  */
+   for (;;)
+     {
+@@ -2011,7 +1919,7 @@ handle_connections (assuan_fd_t listen_fd)
+             break; /* ready */
+           /* Do not accept new connections but keep on running the
+-           * loop to cope with the timer events.
++           * select loop to wait for signals (e.g. SIGCHLD).
+            *
+            * Note that we do not close the listening socket because a
+            * client trying to connect to that socket would instead
+@@ -2031,24 +1939,14 @@ handle_connections (assuan_fd_t listen_fd)
+       /* Take a copy of the fdset.  */
+       read_fdset = fdset;
+-      npth_clock_gettime (&curtime);
+-      if (!(npth_timercmp (&curtime, &abstime, <)))
+-      {
+-        /* Timeout.  */
+-        handle_tick ();
+-        npth_clock_gettime (&abstime);
+-        abstime.tv_sec += TIMERTICK_INTERVAL;
+-      }
+-      npth_timersub (&abstime, &curtime, &timeout);
+-
+ #ifndef HAVE_W32_SYSTEM
+-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
++      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, NULL, npth_sigev_sigmask());
+       saved_errno = errno;
+       while (npth_sigev_get_pending(&signo))
+       handle_signal (signo);
+ #else
+-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
++      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, NULL, NULL, NULL);
+       saved_errno = errno;
+ #endif
+@@ -2062,8 +1960,7 @@ handle_connections (assuan_fd_t listen_fd)
+       if (ret <= 0)
+         {
+-          /* Interrupt or timeout.  Will be handled when calculating the
+-             next timeout.  */
++          /* Interrupt.  Will be handled at the top of the next loop.  */
+           continue;
+         }
diff --git a/patches/gpg-agent-idling/0001-agent-Create-framework-of-scheduled-timers.patch b/patches/gpg-agent-idling/0001-agent-Create-framework-of-scheduled-timers.patch
new file mode 100644 (file)
index 0000000..05817dd
--- /dev/null
@@ -0,0 +1,192 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Mon, 31 Oct 2016 21:27:36 -0400
+Subject: agent: Create framework of scheduled timers.
+
+agent/gpg-agent.c (handle_tick): Remove intermittent call to
+check_own_socket.
+(tv_is_set): Add inline helper function for readability.
+(handle_connections) Create general table of pending scheduled
+timeouts.
+
+--
+
+handle_tick() does fine-grained, rapid activity.  check_own_socket()
+is supposed to happen at a different interval.
+
+Mixing the two of them makes it a requirement that one interval be a
+multiple of the other, which isn't ideal if there are different delay
+strategies that we might want in the future.
+
+Creating an extensible regular timer framework in handle_connections
+should make it possible to have any number of cadenced timers fire
+regularly, without requiring that they happen in cadences related to
+each other.
+
+It should also make it possible to dynamically change the cadence of
+any regularly-scheduled timeout.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ agent/gpg-agent.c | 87 ++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 58 insertions(+), 29 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 31bf3370a..25aae6af0 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -2282,11 +2282,6 @@ create_directories (void)
+ static void
+ handle_tick (void)
+ {
+-  static time_t last_minute;
+-
+-  if (!last_minute)
+-    last_minute = time (NULL);
+-
+   /* Check whether the scdaemon has died and cleanup in this case. */
+   agent_scd_check_aliveness ();
+@@ -2305,16 +2300,6 @@ handle_tick (void)
+         }
+     }
+ #endif /*HAVE_W32_SYSTEM*/
+-
+-  /* Code to be run from time to time.  */
+-#if CHECK_OWN_SOCKET_INTERVAL > 0
+-  if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
+-    {
+-      check_own_socket ();
+-      last_minute = time (NULL);
+-    }
+-#endif
+-
+ }
+@@ -2711,6 +2696,15 @@ start_connection_thread_ssh (void *arg)
+ }
++/* helper function for readability: test whether a given struct
++   timespec is set to all-zeros */
++static inline int
++tv_is_set (struct timespec tv)
++{
++  return tv.tv_sec || tv.tv_nsec;
++}
++
++
+ /* Connection handler loop.  Wait for connection requests and spawn a
+    thread after accepting a connection.  */
+ static void
+@@ -2728,9 +2722,11 @@ handle_connections (gnupg_fd_t listen_fd,
+   gnupg_fd_t fd;
+   int nfd;
+   int saved_errno;
++  int idx;
+   struct timespec abstime;
+   struct timespec curtime;
+   struct timespec timeout;
++  struct timespec *select_timeout;
+ #ifdef HAVE_W32_SYSTEM
+   HANDLE events[2];
+   unsigned int events_set;
+@@ -2746,6 +2742,14 @@ handle_connections (gnupg_fd_t listen_fd,
+     { "browser", start_connection_thread_browser },
+     { "ssh",    start_connection_thread_ssh   }
+   };
++  struct {
++    struct timespec interval;
++    void (*func) (void);
++    struct timespec next;
++  } timertbl[] = {
++    { { TIMERTICK_INTERVAL, 0 }, handle_tick },
++    { { CHECK_OWN_SOCKET_INTERVAL, 0 }, check_own_socket }
++  };
+   ret = npth_attr_init(&tattr);
+@@ -2835,9 +2839,6 @@ handle_connections (gnupg_fd_t listen_fd,
+   listentbl[2].l_fd = listen_fd_browser;
+   listentbl[3].l_fd = listen_fd_ssh;
+-  npth_clock_gettime (&abstime);
+-  abstime.tv_sec += TIMERTICK_INTERVAL;
+-
+   for (;;)
+     {
+       /* Shutdown test.  */
+@@ -2866,18 +2867,47 @@ handle_connections (gnupg_fd_t listen_fd,
+          thus a simple assignment is fine to copy the entire set.  */
+       read_fdset = fdset;
++      /* loop through all timers, fire any registered functions, and
++         plan next timer to trigger */
+       npth_clock_gettime (&curtime);
+-      if (!(npth_timercmp (&curtime, &abstime, <)))
+-      {
+-        /* Timeout.  */
+-        handle_tick ();
+-        npth_clock_gettime (&abstime);
+-        abstime.tv_sec += TIMERTICK_INTERVAL;
+-      }
+-      npth_timersub (&abstime, &curtime, &timeout);
++      abstime.tv_sec = abstime.tv_nsec = 0;
++      for (idx=0; idx < DIM(timertbl); idx++)
++        {
++          /* schedule any unscheduled timers */
++          if ((!tv_is_set (timertbl[idx].next)) && tv_is_set (timertbl[idx].interval))
++            npth_timeradd (&timertbl[idx].interval, &curtime, &timertbl[idx].next);
++          /* if a timer is due, fire it ... */
++          if (tv_is_set (timertbl[idx].next))
++            {
++              if (!(npth_timercmp (&curtime, &timertbl[idx].next, <)))
++                {
++                  timertbl[idx].func ();
++                  npth_clock_gettime (&curtime);
++                  /* ...and reschedule it, if desired: */
++                  if (tv_is_set (timertbl[idx].interval))
++                    npth_timeradd (&timertbl[idx].interval, &curtime, &timertbl[idx].next);
++                  else
++                    timertbl[idx].next.tv_sec = timertbl[idx].next.tv_nsec = 0;
++                }
++            }
++          /* accumulate next timer to come due in abstime: */
++          if (tv_is_set (timertbl[idx].next) &&
++              ((!tv_is_set (abstime)) ||
++               (npth_timercmp (&abstime, &timertbl[idx].next, >))))
++            abstime = timertbl[idx].next;
++        }
++      /* choose a timeout for the select loop: */
++      if (tv_is_set (abstime))
++        {
++          npth_timersub (&abstime, &curtime, &timeout);
++          select_timeout = &timeout;
++        }
++      else
++          select_timeout = NULL;
++      
+ #ifndef HAVE_W32_SYSTEM
+-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
++      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, select_timeout,
+                           npth_sigev_sigmask ());
+       saved_errno = errno;
+@@ -2887,7 +2917,7 @@ handle_connections (gnupg_fd_t listen_fd,
+           handle_signal (signo);
+       }
+ #else
+-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
++      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, select_timeout,
+                           events, &events_set);
+       saved_errno = errno;
+@@ -2910,7 +2940,6 @@ handle_connections (gnupg_fd_t listen_fd,
+       if (!shutdown_pending)
+         {
+-          int idx;
+           ctrl_t ctrl;
+           npth_t thread;
diff --git a/patches/gpg-agent-idling/0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch b/patches/gpg-agent-idling/0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch
new file mode 100644 (file)
index 0000000..317cea5
--- /dev/null
@@ -0,0 +1,93 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Tue, 1 Nov 2016 00:45:23 -0400
+Subject: agent: Allow threads to interrupt main select loop with SIGCONT.
+
+* agent/gpg-agent.c (interrupt_main_thread_loop): New function on
+non-windows platforms, allows other threads to interrupt the main loop
+if there's something that the main loop might be interested in.
+
+--
+
+For example, the main loop might be interested in changes in program
+state that affect the timers it expects to see.
+
+I don't know how to do this on Windows platforms, but i welcome any
+proposed improvements.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ agent/agent.h     |  1 +
+ agent/gpg-agent.c | 18 +++++++++++++++++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/agent/agent.h b/agent/agent.h
+index 2db5a5c74..4e75b2a56 100644
+--- a/agent/agent.h
++++ b/agent/agent.h
+@@ -345,6 +345,7 @@ void *get_agent_scd_notify_event (void);
+ #endif
+ void agent_sighup_action (void);
+ int map_pk_openpgp_to_gcry (int openpgp_algo);
++void interrupt_main_thread_loop (void);
+ /*-- command.c --*/
+ gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid,
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 25aae6af0..73cd560aa 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -384,6 +384,9 @@ static char *current_logfile;
+    watched. */
+ static pid_t parent_pid = (pid_t)(-1);
++/* Record the pid of the main thread, for easier signalling */
++static pid_t main_thread_pid = (pid_t)(-1);
++
+ /* Number of active connections.  */
+ static int active_connections;
+@@ -2032,7 +2035,7 @@ get_agent_scd_notify_event (void)
+                                  GetCurrentProcess(), &h2,
+                                  EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
+         {
+-          log_error ("setting syncronize for scd notify event failed: %s\n",
++          log_error ("setting synchronize for scd notify event failed: %s\n",
+                      w32_strerror (-1) );
+           CloseHandle (h);
+         }
+@@ -2358,6 +2361,10 @@ handle_signal (int signo)
+       agent_sigusr2_action ();
+       break;
++      /* nothing to do here, just take an extra cycle on the select loop */
++    case SIGCONT:
++      break;
++
+     case SIGTERM:
+       if (!shutdown_pending)
+         log_info ("SIGTERM received - shutting down ...\n");
+@@ -2696,6 +2703,13 @@ start_connection_thread_ssh (void *arg)
+ }
++void interrupt_main_thread_loop (void)
++{
++#ifndef HAVE_W32_SYSTEM
++  kill (main_thread_pid, SIGCONT);
++#endif
++}
++
+ /* helper function for readability: test whether a given struct
+    timespec is set to all-zeros */
+ static inline int
+@@ -2764,8 +2778,10 @@ handle_connections (gnupg_fd_t listen_fd,
+   npth_sigev_add (SIGUSR1);
+   npth_sigev_add (SIGUSR2);
+   npth_sigev_add (SIGINT);
++  npth_sigev_add (SIGCONT);
+   npth_sigev_add (SIGTERM);
+   npth_sigev_fini ();
++  main_thread_pid = getpid ();
+ #else
+ # ifdef HAVE_W32CE_SYSTEM
+   /* Use a dummy event. */
diff --git a/patches/gpg-agent-idling/0003-agent-Avoid-tight-timer-tick-when-possible.patch b/patches/gpg-agent-idling/0003-agent-Avoid-tight-timer-tick-when-possible.patch
new file mode 100644 (file)
index 0000000..f107e78
--- /dev/null
@@ -0,0 +1,112 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Tue, 1 Nov 2016 00:14:10 -0400
+Subject: agent: Avoid tight timer tick when possible.
+
+* agent/gpg-agent.c (need_tick): Evaluate whether the short-phase
+handle_tick() is needed.
+(handle_connections): On each cycle of the select loop, adjust whether
+we should call handle_tick() or not.
+(start_connection_thread_ssh, do_start_connection_thread): Signal the
+main loop when the child terminates.
+* agent/call-scd.c (start_scd): Call interrupt_main_thread_loop() once
+the scdaemon thread context has started up.
+
+--
+
+With this change, an idle gpg-agent that has no scdaemon running only
+wakes up once a minute (to check_own_socket).
+
+Thanks to Ian Jackson and NIIBE Yutaka who helped me improve some of
+the blocking and corner cases.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ agent/call-scd.c  |  4 +++-
+ agent/gpg-agent.c | 31 ++++++++++++++++++++++++++++---
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/agent/call-scd.c b/agent/call-scd.c
+index 15a2ba529..0bf603084 100644
+--- a/agent/call-scd.c
++++ b/agent/call-scd.c
+@@ -407,7 +407,9 @@ start_scd (ctrl_t ctrl)
+   primary_scd_ctx = ctx;
+   primary_scd_ctx_reusable = 0;
+-
++  /* notify the main loop that something has changed */
++  interrupt_main_thread_loop ();
++  
+  leave:
+   xfree (abs_homedir);
+   if (err)
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 73cd560aa..b33de7d39 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -2279,6 +2279,26 @@ create_directories (void)
+ }
++static int
++need_tick (void)
++{
++#ifdef HAVE_W32_SYSTEM
++  /* We do not know how to interrupt the select loop on Windows, so we
++     always need a short tick there. */
++  return 1;
++#else
++  /* if we were invoked like "gpg-agent cmd arg1 arg2" then we need to
++     watch our parent. */
++  if (parent_pid != (pid_t)(-1))
++    return 1;
++  /* if scdaemon is running, we need to check that it's alive */
++  if (agent_scd_check_running ())
++    return 1;
++  /* otherwise, nothing fine-grained to do. */
++  return 0;
++#endif /*HAVE_W32_SYSTEM*/
++}
++
+ /* This is the worker for the ticker.  It is called every few seconds
+    and may only do fast operations. */
+@@ -2337,7 +2357,7 @@ agent_sigusr2_action (void)
+ #ifndef HAVE_W32_SYSTEM
+ /* The signal handler for this program.  It is expected to be run in
+-   its own trhead and not in the context of a signal handler.  */
++   its own thread and not in the context of a signal handler.  */
+ static void
+ handle_signal (int signo)
+ {
+@@ -2618,7 +2638,8 @@ do_start_connection_thread (ctrl_t ctrl)
+   agent_deinit_default_ctrl (ctrl);
+   xfree (ctrl);
+-  active_connections--;
++  if (--active_connections == 0)
++    interrupt_main_thread_loop();
+   return NULL;
+ }
+@@ -2698,7 +2719,8 @@ start_connection_thread_ssh (void *arg)
+   agent_deinit_default_ctrl (ctrl);
+   xfree (ctrl);
+-  active_connections--;
++  if (--active_connections == 0)
++    interrupt_main_thread_loop();
+   return NULL;
+ }
+@@ -2883,6 +2905,9 @@ handle_connections (gnupg_fd_t listen_fd,
+          thus a simple assignment is fine to copy the entire set.  */
+       read_fdset = fdset;
++      /* avoid a fine-grained timer if we don't need one: */
++      timertbl[0].interval.tv_sec = need_tick () ? TIMERTICK_INTERVAL : 0;
++
+       /* loop through all timers, fire any registered functions, and
+          plan next timer to trigger */
+       npth_clock_gettime (&curtime);
diff --git a/patches/gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch b/patches/gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
new file mode 100644 (file)
index 0000000..557deff
--- /dev/null
@@ -0,0 +1,26 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Tue, 1 Nov 2016 00:57:44 -0400
+Subject: agent: Avoid scheduled checks on socket when inotify is working.
+
+* agent/gpg-agent.c (handle_connections): When inotify is working, we
+do not need to schedule a timer to evaluate whether we control our own
+socket or not.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ agent/gpg-agent.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index b33de7d39..56c28a679 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -2907,6 +2907,8 @@ handle_connections (gnupg_fd_t listen_fd,
+       /* avoid a fine-grained timer if we don't need one: */
+       timertbl[0].interval.tv_sec = need_tick () ? TIMERTICK_INTERVAL : 0;
++      /* avoid waking up to check sockets if we can count on inotify */
++      timertbl[1].interval.tv_sec = (my_inotify_fd == -1) ? CHECK_OWN_SOCKET_INTERVAL : 0;
+       /* loop through all timers, fire any registered functions, and
+          plan next timer to trigger */
diff --git a/patches/series b/patches/series
new file mode 100644 (file)
index 0000000..4ec24b8
--- /dev/null
@@ -0,0 +1,78 @@
+debian-packaging/0001-avoid-beta-warning.patch
+block-ptrace-on-agent/0002-Avoid-simple-memory-dumps-via-ptrace.patch
+debian-packaging/0003-avoid-regenerating-defsincdate-use-shipped-file.patch
+dirmngr-idling/0001-dirmngr-hkp-Avoid-potential-race-condition-when-some.patch
+dirmngr-idling/0002-dimrngr-Avoid-need-for-hkp-housekeeping.patch
+dirmngr-idling/0004-dirmngr-Avoid-automatically-checking-upstream-swdb.patch
+dirmngr-idling/0005-dirmngr-Drop-useless-housekeeping.patch
+gpg-agent-idling/0001-agent-Create-framework-of-scheduled-timers.patch
+gpg-agent-idling/0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch
+gpg-agent-idling/0003-agent-Avoid-tight-timer-tick-when-possible.patch
+gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
+0012-tools-Fix-memory-leak.patch
+0013-tools-Improve-error-handling.patch
+0014-dirmngr-New-option-disable-ipv4.patch
+0015-dirmngr-Simplify-error-returning-inside-http.c.patch
+0016-gpg-Print-a-warning-on-Tor-problems.patch
+0017-agent-Fix-double-free.patch
+0018-gpg-Fix-searching-for-mail-addresses-in-keyrings.patch
+0019-dirmngr-New-option-no-use-tor-and-internal-changes.patch
+0020-gpg-Remove-period-at-end-of-warning.patch
+0021-gpg-Add-newline-to-output.patch
+0022-gpg-Only-print-out-TOFU-statistics-for-conflicts-in-.patch
+0023-gpg-If-there-is-a-TOFU-conflict-elide-the-too-few-me.patch
+0024-gpg-Ensure-TOFU-bindings-associated-with-UTKs-are-re.patch
+0025-gpg-Don-t-assume-that-strtoul-interprets-as-0.patch
+0026-gpg-More-diagnostics-for-a-launched-pinentry.patch
+0027-doc-Clarify-abbreviation-of-help.patch
+0028-scd-Backport-two-fixes-from-master.patch
+0029-scd-Fix-use-case-of-PC-SC.patch
+0030-scd-Fix-factory-reset.patch
+0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch
+0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
+0033-common-Avoid-warning-about-implicit-declaration-of-g.patch
+0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch
+0035-gpg-Print-a-warning-if-no-command-has-been-given.patch
+0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch
+0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch
+0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch
+0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch
+0040-gpgv-w32-Fix-status-fd.patch
+0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
+0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
+0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
+0044-gpg-Make-export-options-work-with-export-secret-keys.patch
+0045-common-tools-Always-escape-newlines-when-escaping-da.patch
+0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
+0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
+0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
+0049-doc-Add-a-note-to-the-trust-model-direct.patch
+0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
+0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
+0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
+0053-dirmngr-Load-the-hosts-file-into-libdns.patch
+0054-dirmngr-Fix-error-handling.patch
+0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
+0056-common-Fix-connecting-to-the-agent.patch
+0057-g10-Fix-memory-leak.patch
+0058-common-Avoid-undefined-behavior.patch
+0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
+0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
+0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
+0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
+0063-dirmngr-New-option-disable-ipv6.patch
+0064-agent-Serialize-access-to-passphrase-cache.patch
+0065-gpg-Fix-printing-of-offline-taken-subkey.patch
+0066-doc-Explain-the-in-a-key-listing.patch
+0067-dirmngr-Fix-possible-null-reference.patch
+0068-tools-Fix-condition-for-gpg-connect-agent.patch
+0069-dirmngr-Fix-alignment-of-ADDR.patch
+0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
+0071-g10-Fix-import-export-filter-property-match.patch
+0072-g10-Minor-fixes.patch
+0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
+0074-g10-invalidate-the-fd-cache-for-keyring.patch
+0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
+skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch
+skel-file-removal/0077-g10-remove-skeleton-options-files.patch
+avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch
diff --git a/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch b/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch
new file mode 100644 (file)
index 0000000..55e63f0
--- /dev/null
@@ -0,0 +1,440 @@
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Date: Mon, 17 Apr 2017 10:51:55 -0400
+Subject: g10: remove skeleton options files
+
+* build-aux/speed/w32/inst.nsi: stop installing skeleton files.
+* doc/gpg.texi: stop documenting skeleton files.
+* g10/Makefile.am: stop installing skeleton files.
+* g10/openfile.c (copy_options_file): Remove.
+(try_make_homedir): do not call copy_options_file()
+
+The defaults for gpg and dirmngr are good.  Both programs should work
+fine for the simple case without any config file.  The skeleton config
+files were being copied at first use (when the defaults are fine).
+But when the user needs to fiddle with them (after they've become
+sophisticated users), they're likely out of date because gpg has been
+upgraded since then.  So they're used for documentation, but they're
+stale documentation, which is probably worse than a clean empty file.
+
+--
+
+GnuPG-bug-id: 3086
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ build-aux/speedo/w32/inst.nsi |   2 -
+ doc/gpg.texi                  |   4 --
+ g10/Makefile.am               |   8 +--
+ g10/dirmngr-conf.skel         |  69 ---------------------
+ g10/openfile.c                | 102 -------------------------------
+ g10/options.skel              | 139 ------------------------------------------
+ 6 files changed, 1 insertion(+), 323 deletions(-)
+ delete mode 100644 g10/dirmngr-conf.skel
+ delete mode 100644 g10/options.skel
+
+diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi
+index 164e26b..779c759 100644
+--- a/build-aux/speedo/w32/inst.nsi
++++ b/build-aux/speedo/w32/inst.nsi
+@@ -607,8 +607,6 @@ Section "GnuPG" SEC_gnupg
+       Rename /REBOOTOK scdaemon.exe.tmp scdaemon.exe
+   SetOutPath "$INSTDIR\share\gnupg"
+-  File "share/gnupg/gpg-conf.skel"
+-  File "share/gnupg/dirmngr-conf.skel"
+   File "share/gnupg/distsigkey.gpg"
+   SetOutPath "$INSTDIR\share\locale\ca\LC_MESSAGES"
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index c591049..a7d78c4 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -3452,10 +3452,6 @@ files; They all live in in the current home directory (@pxref{option
+   You should backup all files in this directory and take care to keep
+   this backup closed away.
+-  @item @value{DATADIR}/options.skel
+-  @efindex options.skel
+-  The skeleton options file.
+-
+ @end table
+ Operation is further controlled by a few environment variables:
+diff --git a/g10/Makefile.am b/g10/Makefile.am
+index 604be93..19c5c78 100644
+--- a/g10/Makefile.am
++++ b/g10/Makefile.am
+@@ -18,7 +18,7 @@
+ ## Process this file with automake to produce Makefile.in
+-EXTRA_DIST = options.skel dirmngr-conf.skel distsigkey.gpg \
++EXTRA_DIST = distsigkey.gpg \
+            ChangeLog-2011 gpg-w32info.rc \
+            gpg.w32-manifest.in test.c t-keydb-keyring.kbx \
+            t-keydb-get-keyblock.gpg t-stutter-data.asc
+@@ -238,18 +238,12 @@ install-exec-hook:
+ install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+-      $(INSTALL_DATA) $(srcdir)/options.skel \
+-                              $(DESTDIR)$(pkgdatadir)/gpg-conf.skel
+-      $(INSTALL_DATA) $(srcdir)/dirmngr-conf.skel \
+-                              $(DESTDIR)$(pkgdatadir)/dirmngr-conf.skel
+       $(INSTALL_DATA) $(srcdir)/distsigkey.gpg \
+                               $(DESTDIR)$(pkgdatadir)/distsigkey.gpg
+ # NB: For uninstalling gpg and gpgv we use -local because there is
+ # no need for a specific order the targets need to be run.
+ uninstall-local:
+-      -@rm $(DESTDIR)$(pkgdatadir)/gpg-conf.skel
+-      -@rm $(DESTDIR)$(pkgdatadir)/dirmngr-conf.skel
+       -@rm $(DESTDIR)$(pkgdatadir)/distsigkey.gpg
+       -@files=`for p in $(gpg2_hack_uninst); do echo "$$p"; done | \
+         sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+diff --git a/g10/dirmngr-conf.skel b/g10/dirmngr-conf.skel
+deleted file mode 100644
+index fbb730b..0000000
+--- a/g10/dirmngr-conf.skel
++++ /dev/null
+@@ -1,69 +0,0 @@
+-# dirmngr-conf.skel - Skeleton to create dirmngr.conf.
+-# (Note that the first three lines are not copied.)
+-#
+-# dirmngr.conf - Options for Dirmngr
+-# Written in 2015 by The GnuPG Project <https://gnupg.org>
+-#
+-# To the extent possible under law, the authors have dedicated all
+-# copyright and related and neighboring rights to this file to the
+-# public domain worldwide.  This file is distributed without any
+-# warranty.  You should have received a copy of the CC0 Public Domain
+-# Dedication along with this file. If not, see
+-# <http://creativecommons.org/publicdomain/zero/1.0/>.
+-#
+-#
+-# Unless you specify which option file to use (with the command line
+-# option "--options filename"), the file ~/.gnupg/dirmngr.conf is used
+-# by dirmngr.  The file can contain any long options which are valid
+-# for Dirmngr.  If the first non white space character of a line is a
+-# '#', the line is ignored.  Empty lines are also ignored.  See the
+-# dirmngr man page or the manual for a list of options.
+-#
+-
+-# --keyserver URI
+-#
+-# GPG can send and receive keys to and from a keyserver.  These
+-# servers can be HKP, Email, or LDAP (if GnuPG is built with LDAP
+-# support).
+-#
+-# Example HKP keyservers:
+-#      hkp://keys.gnupg.net
+-#
+-# Example HKP keyserver using a Tor OnionBalance service
+-#      hkp://jirk5u4osbsr34t5.onion
+-#
+-# Example HKPS keyservers (see --hkp-cacert below):
+-#       hkps://hkps.pool.sks-keyservers.net
+-#
+-# Example LDAP keyservers:
+-#      ldap://pgp.surfnet.nl:11370
+-#
+-# Regular URL syntax applies, and you can set an alternate port
+-# through the usual method:
+-#      hkp://keyserver.example.net:22742
+-#
+-# Most users just set the name and type of their preferred keyserver.
+-# Note that most servers (with the notable exception of
+-# ldap://keyserver.pgp.com) synchronize changes with each other.  Note
+-# also that a single server name may actually point to multiple
+-# servers via DNS round-robin.  hkp://keys.gnupg.net is an example of
+-# such a "server", which spreads the load over a number of physical
+-# servers.
+-#
+-# If exactly two keyservers are configured and only one is a Tor hidden
+-# service, Dirmngr selects the keyserver to use depending on whether
+-# Tor is locally running or not (on a per session base).
+-
+-keyserver hkp://jirk5u4osbsr34t5.onion
+-keyserver hkp://keys.gnupg.net
+-
+-# --hkp-cacert FILENAME
+-#
+-# For the "hkps" scheme (keyserver access over TLS), Dirmngr needs to
+-# know the root certificates for verification of the TLS certificates
+-# used for the connection.  Enter the full name of a file with the
+-# root certificates here.  If that file is in PEM format a ".pem"
+-# suffix is expected.  This option may be given multiple times to add
+-# more root certificates.  Tilde expansion is supported.
+-
+-#hkp-cacert /path/to/CA/sks-keyservers.netCA.pem
+diff --git a/g10/openfile.c b/g10/openfile.c
+index f62deec..2e8c102 100644
+--- a/g10/openfile.c
++++ b/g10/openfile.c
+@@ -36,12 +36,6 @@
+ #include "status.h"
+ #include "i18n.h"
+-#ifdef USE_ONLY_8DOT3
+-#define SKELEXT ".skl"
+-#else
+-#define SKELEXT EXTSEP_S "skel"
+-#endif
+-
+ #ifdef HAVE_W32_SYSTEM
+ #define NAME_OF_DEV_NULL "nul"
+ #else
+@@ -373,93 +367,6 @@ open_sigfile (const char *sigfilename, progress_filter_context_t *pfx)
+ }
+-/****************
+- * Copy the option file skeleton for NAME to the given directory.
+- * Returns true if the new option file has any option.
+- */
+-static int
+-copy_options_file (const char *destdir, const char *name)
+-{
+-  const char *datadir = gnupg_datadir ();
+-  char *fname;
+-  FILE *src, *dst;
+-  int linefeeds=0;
+-  int c;
+-  mode_t oldmask;
+-  int esc = 0;
+-  int any_option = 0;
+-
+-  if (opt.dry_run)
+-    return 0;
+-
+-  fname = xstrconcat (datadir, DIRSEP_S, name, "-conf", SKELEXT, NULL);
+-  src = fopen (fname, "r");
+-  if (src && is_secured_file (fileno (src)))
+-    {
+-      fclose (src);
+-      src = NULL;
+-      gpg_err_set_errno (EPERM);
+-    }
+-  if (!src)
+-    {
+-      log_info (_("can't open '%s': %s\n"), fname, strerror(errno));
+-      xfree(fname);
+-      return 0;
+-    }
+-  xfree (fname);
+-  fname = xstrconcat (destdir, DIRSEP_S, name, EXTSEP_S, "conf", NULL);
+-
+-  oldmask = umask (077);
+-  if (is_secured_filename (fname))
+-    {
+-      dst = NULL;
+-      gpg_err_set_errno (EPERM);
+-    }
+-  else
+-    dst = fopen( fname, "w" );
+-  umask (oldmask);
+-
+-  if (!dst)
+-    {
+-      log_info (_("can't create '%s': %s\n"), fname, strerror(errno) );
+-      fclose (src);
+-      xfree (fname);
+-      return 0;
+-    }
+-
+-  while ((c = getc (src)) != EOF)
+-    {
+-      if (linefeeds < 3)
+-        {
+-          if (c == '\n')
+-            linefeeds++;
+-      }
+-      else
+-        {
+-          putc (c, dst);
+-          if (c== '\n')
+-            esc = 1;
+-          else if (esc == 1)
+-            {
+-              if (c == ' ' || c == '\t')
+-                ;
+-              else if (c == '#')
+-                esc = 2;
+-              else
+-                any_option = 1;
+-            }
+-        }
+-    }
+-
+-  fclose (dst);
+-  fclose (src);
+-
+-  log_info (_("new configuration file '%s' created\n"), fname);
+-  xfree (fname);
+-  return any_option;
+-}
+-
+-
+ void
+ try_make_homedir (const char *fname)
+ {
+@@ -489,15 +396,6 @@ try_make_homedir (const char *fname)
+                     fname, strerror(errno) );
+       else if (!opt.quiet )
+         log_info ( _("directory '%s' created\n"), fname );
+-
+-      /* Note that we also copy a dirmngr.conf file here.  This is
+-         because gpg is likely the first invoked tool and thus creates
+-         the directory.  */
+-      copy_options_file (fname, DIRMNGR_NAME);
+-      if (copy_options_file (fname, GPG_NAME))
+-        log_info (_("WARNING: options in '%s'"
+-                    " are not yet active during this run\n"),
+-                  fname);
+     }
+ }
+diff --git a/g10/options.skel b/g10/options.skel
+deleted file mode 100644
+index 87fc627..0000000
+--- a/g10/options.skel
++++ /dev/null
+@@ -1,139 +0,0 @@
+-# These first three lines are not copied to the gpg.conf file in
+-# the users home directory.
+-# $Id$
+-# Options for GnuPG
+-# Copyright 1998-2003, 2010 Free Software Foundation, Inc.
+-# Copyright 1998-2003, 2010 Werner Koch
+-#
+-# This file is free software; as a special exception the author gives
+-# unlimited permission to copy and/or distribute it, with or without
+-# modifications, as long as this notice is preserved.
+-#
+-# This file is distributed in the hope that it will be useful, but
+-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+-#
+-# Unless you specify which option file to use (with the command line
+-# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf
+-# by default.
+-#
+-# An options file can contain any long options which are available in
+-# GnuPG. If the first non white space character of a line is a '#',
+-# this line is ignored.  Empty lines are also ignored.
+-#
+-# See the gpg man page for a list of options.
+-
+-
+-# If you have more than 1 secret key in your keyring, you may want to
+-# uncomment the following option and set your preferred keyid.
+-
+-#default-key 621CC013
+-
+-
+-# If you do not pass a recipient to gpg, it will ask for one.  Using
+-# this option you can encrypt to a default key.  Key validation will
+-# not be done in this case.  The second form uses the default key as
+-# default recipient.
+-
+-#default-recipient some-user-id
+-#default-recipient-self
+-
+-
+-# Group names may be defined like this:
+-#   group mynames = paige 0x12345678 joe patti
+-#
+-# Any time "mynames" is a recipient (-r or --recipient), it will be
+-# expanded to the names "paige", "joe", and "patti", and the key ID
+-# "0x12345678".  Note there is only one level of expansion - you
+-# cannot make an group that points to another group.  Note also that
+-# if there are spaces in the recipient name, this will appear as two
+-# recipients.  In these cases it is better to use the key ID.
+-
+-#group mynames = paige 0x12345678 joe patti
+-
+-
+-# GnuPG can automatically locate and retrieve keys as needed using
+-# this option.  This happens when encrypting to an email address (in
+-# the "user@@example.com" form) and there are no keys matching
+-# "user@example.com" in the local keyring.  This option takes any
+-# number mechanisms which are tried in the given order.  The default
+-# is "--auto-key-locate local" to search for keys only in the local
+-# key database.  Uncomment the next line to locate a missing key using
+-# two DNS based mechanisms.
+-
+-#auto-key-locate local,pka,dane
+-
+-
+-# Common options for keyserver functions:
+-# (Note that the --keyserver option has been moved to dirmngr.conf)
+-#
+-# include-disabled = when searching, include keys marked as "disabled"
+-#                    on the keyserver (not all keyservers support this).
+-#
+-# no-include-revoked = when searching, do not include keys marked as
+-#                      "revoked" on the keyserver.
+-#
+-# verbose = show more information as the keys are fetched.
+-#           Can be used more than once to increase the amount
+-#           of information shown.
+-#
+-# auto-key-retrieve = automatically fetch keys as needed from the keyserver
+-#                     when verifying signatures or when importing keys that
+-#                     have been revoked by a revocation key that is not
+-#                     present on the keyring.
+-#
+-# no-include-attributes = do not include attribute IDs (aka "photo IDs")
+-#                         when sending keys to the keyserver.
+-
+-#keyserver-options auto-key-retrieve
+-
+-
+-# Uncomment this line to display photo user IDs in key listings and
+-# when a signature from a key with a photo is verified.
+-
+-#show-photos
+-
+-
+-# Use this program to display photo user IDs
+-#
+-# %i is expanded to a temporary file that contains the photo.
+-# %I is the same as %i, but the file isn't deleted afterwards by GnuPG.
+-# %k is expanded to the key ID of the key.
+-# %K is expanded to the long OpenPGP key ID of the key.
+-# %t is expanded to the extension of the image (e.g. "jpg").
+-# %T is expanded to the MIME type of the image (e.g. "image/jpeg").
+-# %f is expanded to the fingerprint of the key.
+-# %% is %, of course.
+-#
+-# If %i or %I are not present, then the photo is supplied to the
+-# viewer on standard input.  If your platform supports it, standard
+-# input is the best way to do this as it avoids the time and effort in
+-# generating and then cleaning up a secure temp file.
+-#
+-# The default program is "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"
+-# On Mac OS X and Windows, the default is to use your regular JPEG image
+-# viewer.
+-#
+-# Some other viewers:
+-# photo-viewer "qiv %i"
+-# photo-viewer "ee %i"
+-# photo-viewer "display -title 'KeyID 0x%k'"
+-#
+-# This one saves a copy of the photo ID in your home directory:
+-# photo-viewer "cat > ~/photoid-for-key-%k.%t"
+-#
+-# Use your MIME handler to view photos:
+-# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG"
+-
+-
+-# Because some mailers change lines starting with "From " to ">From "
+-# it is good to handle such lines in a special way when creating
+-# cleartext signatures; all other PGP versions do it this way too.
+-# To enable full OpenPGP compliance you may want to use this option.
+-
+-#no-escape-from-lines
+-
+-
+-# Uncomment the following option to get rid of the copyright notice
+-
+-#no-greeting
diff --git a/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch b/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch
new file mode 100644 (file)
index 0000000..628565d
--- /dev/null
@@ -0,0 +1,51 @@
+From: Simon Arlott <simon@arlott.org>
+Date: Sun, 5 Feb 2017 16:31:35 -0500
+Subject: g10: Skip signing keys where no secret key is available.
+
+* g10/getkey.c (finish_lookup): When requiring PUBKEY_USAGE_SIG, skip
+over keys where no signing key is available.
+
+--
+
+This should only be relevant when gpg is required to choose which key
+to sign with -- if verifying signatures, we already know which subkey
+to look at, and indeed gpg doesn't seem to have a problem with this.
+
+This patch comes from
+https://bugs.gnupg.org/gnupg/file793/sign-fix.patch
+
+I (dkg) have reviewed and tested it with missing local keys, and it
+makes sense to me as the default behavior.  If the user has the secret
+key for a signing-capable subkey available and the command is --sign,
+it should be used.
+
+If the user has explicitly specified a subkey that happens to be
+missing (e.g. with the trailing ! for --default-key 0x${FPR}!) then
+this does not override that behavior (the signature will still fail).
+
+GnuPG-bug-id: 1967
+Debian-bug-id: 834922
+
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ g10/getkey.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/g10/getkey.c b/g10/getkey.c
+index 961d7de..bb31dfb 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -3529,6 +3529,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
+             continue;
+           }
++        if ((req_usage & PUBKEY_USAGE_SIG) && agent_probe_secret_key (NULL, pk))
++          {
++            if (DBG_LOOKUP)
++              log_debug ("\tno secret key for signing\n");
++            continue;
++          }
++
+         if (DBG_LOOKUP)
+           log_debug ("\tsubkey might be fine\n");
+         /* In case a key has a timestamp of 0 set, we make sure
diff --git a/rules b/rules
new file mode 100755 (executable)
index 0000000..241cead
--- /dev/null
+++ b/rules
@@ -0,0 +1,67 @@
+#!/usr/bin/make -f
+# debian/rules file - for GnuPG
+# Copyright 1994,1995 by Ian Jackson.
+# Copyright 1998-2003 by James Troup.
+# Copyright 2003-2004 by Matthias Urlichs.
+# 
+# I hereby give you perpetual unlimited permission to copy,
+# modify and relicense this file, provided that you do not remove
+# my name from the file itself.  (I assert my moral right of
+# paternity under the Copyright, Designs and Patents Act 1988.)
+# This file may have to be extensively modified
+
+include /usr/share/dpkg/architecture.mk
+
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# avoid -pie for gpgv-static on hppa, kfreebsd-amd64, and x32
+# platforms, which cannot support it by default:
+ifeq (,$(filter $(DEB_HOST_ARCH), hppa kfreebsd-amd64 x32))
+GPGV_STATIC_HARDENING = "-pie"
+else
+GPGV_STATIC_HARDENING = ""
+endif
+
+%:
+       dh $@ --with=autoreconf --builddirectory=build
+
+GPGV_UDEB_UNNEEDED = gpgtar bzip2 gpgsm scdaemon dirmngr doc tofu exec ldap gnutls sqlite libdns
+
+WIN32_FLAGS=LDFLAGS="-Xlinker --no-insert-timestamp -static" CFLAGS="-g -Os" CPPFLAGS=
+
+override_dh_auto_configure:
+       dh_auto_configure --builddirectory=build-gpgv-udeb -- \
+               --enable-gpg2-is-gpg \
+               $(foreach x, $(GPGV_UDEB_UNNEEDED), --disable-$(x))
+       dh_auto_configure --builddirectory=build -- --libexecdir=\$${prefix}/lib/gnupg \
+               --enable-gpg2-is-gpg \
+               --enable-symcryptrun --enable-large-secmem
+
+override_dh_auto_build-arch:
+       dh_auto_build --builddirectory=build-gpgv-udeb
+       dh_auto_build --builddirectory=build
+       cp -a build-gpgv-udeb build-gpgv-static
+       rm -f build-gpgv-static/g10/gpgv
+       cd build-gpgv-static/g10 && $(MAKE) LDFLAGS="$$LDFLAGS $(GPGV_STATIC_HARDENING) -static" gpgv
+       mv build-gpgv-static/g10/gpgv build-gpgv-static/g10/gpgv-static
+
+override_dh_auto_build-indep:
+       mkdir -p build-gpgv-win32
+       cd build-gpgv-win32 && $(WIN32_FLAGS) ../configure \
+               $(foreach x, $(GPGV_UDEB_UNNEEDED), --disable-$(x)) \
+               $(foreach x, libgpg-error libgcrypt libassuan ksba npth, --with-$x-prefix=/usr/i686-w64-mingw32) \
+               --enable-gpg2-is-gpg \
+               --with-zlib=/usr/i686-w64-mingw \
+               --prefix=/usr/i686-w64-mingw32 \
+               --host i686-w64-mingw32
+       cd build-gpgv-win32/common && $(WIN32_FLAGS) $(MAKE) libcommon.a
+       cd build-gpgv-win32/common && $(WIN32_FLAGS) $(MAKE) libgpgrl.a
+       cd build-gpgv-win32/common && $(WIN32_FLAGS) $(MAKE) libsimple-pwquery.a
+       cd build-gpgv-win32/kbx && $(WIN32_FLAGS) $(MAKE) libkeybox.a
+       cd build-gpgv-win32/g10 && $(WIN32_FLAGS) $(MAKE) gpgv.exe
+       strip build-gpgv-win32/g10/gpgv.exe
+
+override_dh_shlibdeps:
+# Make ldap a recommends rather than a hard dependency.
+       dpkg-shlibdeps -Tdebian/dirmngr.substvars -dRecommends debian/dirmngr/usr/lib/gnupg/dirmngr_ldap -dDepends debian/dirmngr/usr/bin/dirmngr*
+       dh_shlibdeps -Ndirmngr
diff --git a/scdaemon.examples b/scdaemon.examples
new file mode 100644 (file)
index 0000000..29f41a8
--- /dev/null
@@ -0,0 +1 @@
+doc/examples/scd-event
diff --git a/scdaemon.install b/scdaemon.install
new file mode 100644 (file)
index 0000000..a2a79aa
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/lib/gnupg/scdaemon
diff --git a/scdaemon.lintian-overrides b/scdaemon.lintian-overrides
new file mode 100644 (file)
index 0000000..b575cb1
--- /dev/null
@@ -0,0 +1,4 @@
+# there is actually a function for interacting with the smartcard
+# called "writen" that writes n octets; it is in the binary because it
+# can be emitted in debug output:
+scdaemon: spelling-error-in-binary usr/lib/gnupg/scdaemon writen written
diff --git a/scdaemon.manpages b/scdaemon.manpages
new file mode 100644 (file)
index 0000000..9efee23
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/share/man/man1/scdaemon.1
diff --git a/scdaemon.udev b/scdaemon.udev
new file mode 100644 (file)
index 0000000..dd076df
--- /dev/null
@@ -0,0 +1,63 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM!="usb", GOTO="gnupg_rules_end"
+ACTION!="add", GOTO="gnupg_rules_end"
+
+# USB SmartCard Readers
+## Cherry GmbH (XX33, ST2000)
+ATTR{idVendor}=="046a", ATTR{idProduct}=="0005", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="046a", ATTR{idProduct}=="0010", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="046a", ATTR{idProduct}=="003e", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## SCM Microsystems, Inc (SCR331-DI, SCR335, SCR3320, SCR331, SCR3310 and SPR532)
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="5111", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="5115", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="5116", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="5117", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="e001", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="04e6", ATTR{idProduct}=="e003", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Omnikey AG (CardMan 3821, CardMan 6121)
+ATTR{idVendor}=="076b", ATTR{idProduct}=="3821", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="076b", ATTR{idProduct}=="6622", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Gemalto
+ATTR{idVendor}=="08e6", ATTR{idProduct}=="3437", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="08e6", ATTR{idProduct}=="3438", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="08e6", ATTR{idProduct}=="3478", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="08e6", ATTR{idProduct}=="34c2", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="08e6", ATTR{idProduct}=="34ec", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Reiner (SCT cyberJack)
+ATTR{idVendor}=="0c4b", ATTR{idProduct}=="0500", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Kobil (KAAN)
+ATTR{idVendor}=="0d46", ATTR{idProduct}=="2012", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## VASCO (DIGIPASS 920)
+ATTR{idVendor}=="1a44", ATTR{idProduct}=="0920", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Crypto Stick
+ATTR{idVendor}=="20a0", ATTR{idProduct}=="4107", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Nitrokey
+ATTR{idVendor}=="20a0", ATTR{idProduct}=="4108", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="20a0", ATTR{idProduct}=="4109", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+ATTR{idVendor}=="20a0", ATTR{idProduct}=="4211", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Gnuk Token
+ATTR{idVendor}=="234b", ATTR{idProduct}=="0000", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Alcor Micro Corp cardreader (in ThinkPad X250)
+ATTR{idVendor}=="058f", ATTR{idProduct}=="9540", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Fujitsu Siemens
+ATTR{idVendor}=="0bf8", ATTR{idProduct}=="1006", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+## Yubico
+# Yubikey NEO OTP+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0111", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey NEO CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0112", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey NEO U2F+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0115", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey NEO OTP+U2F+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0116", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey 4 CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0404", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey 4 OTP+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0405", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey 4 U2F+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0406", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+# Yubikey 4 OTP+U2F+CCID
+ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
+
+LABEL="gnupg_rules_end"
diff --git a/source/format b/source/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/source/lintian-overrides b/source/lintian-overrides
new file mode 100644 (file)
index 0000000..b5221c7
--- /dev/null
@@ -0,0 +1,4 @@
+# doc merely references / cites IETF RFC: 
+gnupg2 source: license-problem-non-free-RFC doc/OpenPGP
+gnupg2 source: license-problem-non-free-RFC debian/copyright
+
diff --git a/source/options b/source/options
new file mode 100644 (file)
index 0000000..f0f8ede
--- /dev/null
@@ -0,0 +1,3 @@
+# let dpkg-source create a debian.tar.bz2 with maximal compression
+compression = "bzip2"
+compression-level = 9
diff --git a/systemd-user/gpg-agent-browser.socket b/systemd-user/gpg-agent-browser.socket
new file mode 100644 (file)
index 0000000..67690ce
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=GnuPG cryptographic agent (access for web browsers)
+Documentation=man:gpg-agent(1)
+
+[Socket]
+ListenStream=%t/gnupg/S.gpg-agent.browser
+FileDescriptorName=browser
+Service=gpg-agent.service
+SocketMode=0600
+DirectoryMode=0700
+
+[Install]
+WantedBy=sockets.target
diff --git a/tests/control b/tests/control
new file mode 100644 (file)
index 0000000..9178821
--- /dev/null
@@ -0,0 +1,3 @@
+Tests: gpgv-win32
+Depends: gpgv-win32, gnupg2, gpgv2
+Restrictions: needs-root, allow-stderr
diff --git a/tests/gpgv-win32 b/tests/gpgv-win32
new file mode 100755 (executable)
index 0000000..3142a65
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+set -e
+
+export GNUPGHOME=$(mktemp -d)
+
+arch=$(dpkg --print-architecture)
+
+case "$arch" in
+    amd64)
+        if ! dpkg --print-foreign-architectures | grep -Fqx i386; then
+            echo "I: setting up multiarch"
+            dpkg --add-architecture i386
+            apt update # FIXME you might want to try this up to some N times to avoid failures on temporary network issues
+        fi
+    ;;
+    arm64)
+        if ! dpkg --print-foreign-architectures | grep -Fqx armhf; then
+            echo "I: setting up multiarch"
+            dpkg --add-architecture armhf
+            apt update # FIXME you might want to try this up to some N times to avoid failures on temporary network issues
+        fi
+    ;;
+    i386|armel|armhf|powerpc)
+        : nothing, tests should just work
+        ;;
+    *)
+        echo "I: skipping tests on $arch; only works on amd64, i386, arm64, armhf, armel, and powerpc"
+        exit
+        ;;
+esac
+
+if ! dpkg-query --status wine32 | grep -Fqx 'Status: install ok installed'; then
+    DEBIAN_FRONTEND=noninteractive apt install -qy wine32 # FIXME ditto
+fi
+
+echo 'no-allow-loopback-pinentry:16' | gpgconf --change-options gpg-agent
+
+# Generate a minimal signing key:
+gpg2 --batch --debug-quick-random --pinentry-mode loopback --passphrase '' --quick-gen-key   'Test key for gpgv-win32 <test-key@example.com>'
+
+gpg2 -o "$GNUPGHOME/key.gpg" --export test-key@example.com
+
+# Sign this very script
+rm -f "${0}.gpg"
+gpg2 --output "${0}.gpg" --detach-sign "${0}"
+
+# Verify using gpgv
+gpgv2 --keyring "$GNUPGHOME/key.gpg" "${0}.gpg" "${0}"
+
+# Verify using gpgv.exe
+wine /usr/share/win32/gpgv.exe --keyring "Z:\\\\${GNUPGHOME}/key.gpg" "Z:\\\\$(pwd)/${0}.gpg" "Z:\\\\$(pwd)/${0}"
+
+rm -rf "$GNUPGHOME"
diff --git a/upstream/signing-key.asc b/upstream/signing-key.asc
new file mode 100644 (file)
index 0000000..1e57599
--- /dev/null
@@ -0,0 +1,109 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+mQENBE0ti4EBCACqGtKlX9jI/enhlBdy2cyQP6Q7JoyxtaG6/ckAKWHYrqFTQk3I
+Ue8TuDrGT742XFncG9PoMBfJDUNltIPgKFn8E9tYQqAOlpSA25bOb30cA2ADkrjg
+jvDAH8cZ+fkIayWtObTxwqLfPivjFxEM//IdShFFVQj+QHmXYBJggWyEIil8Bje7
+KRw6B5ucs4qSzp5VH4CqDr9PDnLD8lBGHk0x8jpwh4V/yEODJKATY0Vj00793L8u
+qA35ZiyczUvvJSLYvf7STO943GswkxdAfqxXbYifiK2gjE/7SAmB+2jFxsonUDOB
+1BAY5s3FKqrkaxZr3BBjeuGGoCuiSX/cXRIhABEBAAG0Fldlcm5lciBLb2NoIChk
+aXN0IHNpZymJAT4EEwECACgFAk0ti4ECGwMFCRDdnwIGCwkIBwMCBhUIAgkKCwQW
+AgMBAh4BAheAAAoJECSbOdJPJeO2PlMIAJxPtFXf5yozPpFjRbSkSdjsk9eru05s
+hKZOAKw3RUePTU80SRLPdg4AH+vkm1JMWFFpwvHlgfxqnE9rp13o7L/4UwNUwqH8
+5zCwu7SHz9cX3d4UUwzcP6qQP4BQEH9/xlpQS9eTK9b2RMyggqwd/J8mxjvoWzL8
+Klf/wl6jXHn/yP92xG9/YA86lNOL1N3/PhlZzLuJ6bdD9WzsEp/+kh3UDfjkIrOc
+WkqwupB+d01R4bHPu9tvXy8Xut8Sok2zku2xVkEOsV2TXHbwuHO2AGC5pWDX6wgC
+E4F5XeCB/0ovao2/bk22w1TxzP6PMxo6sLkmaF6D0frhM2bl4C/uSsq5AQ0ETS2L
+gQEIAKHwucgbaRj0V7Ht0FnM6RmbqwZ7IFV2lR+YN1gkZaWRRCaJoPEZFKhhPEBX
+1bDVwr/iTPaPPEtpi7oQoHk65yeLrhtOmXXpNVkV/5WQjAJIrWn+JQ3z/ZejxHUL
+hzKsGg5FC6pRYcEyzRXHtv4BO9kBIKNVirZjEkQG4BnIrQgl6e2YFa47GNMqcQH7
+nJdwG1cGQOZOIDQQM41gBzwoSrStMA6DjHkukFegKfcSbSLArBtYNAwTwmW7RqOM
+EJwlo0+NYx2Yn75x66bYwdlsP0FLOgez/O/IxoPRxXr0l4e+uj6dFHqvBi04dx6J
+sPmXEyeAyLiCWSh7Rwq8uIhBUBUAEQEAAYkBJQQYAQIADwUCTS2LgQIbIAUJEN2f
+AgAKCRAkmznSTyXjtrsSCACRNgfGkD0OqOiwYo1/+KyWnrQLusVvSYOw8hN66geU
+3BO8iQ0Koy+m0QKY1kWjaHwewpg8ZebY4E2sHbNIC9Spyiyz29sAJ2invf4/4Mep
+TgpxNiw4+XmykCkN1AfVhvMTQXMzRbO5ZwRtPpjsMr1j5vX1s6U3/RxSAItpAkCu
+1GGTTOH0r12Ochc/um+QGAyO6WUj/IiZ1MX7toXW0SCo8DSl8z5Q7KmJWF6TQLK1
+Lku4bIVG1Huwo1/0WHc2vCad5BxHjgoy8TsKLTmvYQZWtnjWvQGV2UOABYWcacut
+ZXQQ2PPCIY7LlpuS/45CXWbT5Y+mxY3y7dbz4aF+8uyCiJwEEAECAAYFAk0tjQQA
+CgkQU7Yg0BzgxjBGTwQAi5qzI6cJslbyOl+TeDZVnLV0FmPuDg8dojvQrVDPxfem
+IjxZZoMLCVM8ly8AC2JPrIYfN040C343saIc0tTtOwwmVMuy7G/Uex22CdWH/0HB
+MpG4gFuOuQmW9QQDjEdh1DgwU2gAWonX54ZlMybWss+2NCikRwMflVUupH57BauZ
+AQ0EVFA7IwEIAOYQcDfRdzqin/vZlwl1AyuJW+cDI3bYvesRtOIAJ+8FqOzp+nOZ
+7a4mULkXUeRh3HcO91wughXoR3qP3klWIlqgTQQHxPVM25BEvnGPuMA86lWnKoSs
+Xe9F5h0IMiu6aURvzMJC9VMgKwhhgCjejFf9n8zuiBkMN457Ubnt/9jxhpxmorDQ
+Cpb7bR1mfdbsuCmOXwTNfbkAoGXceL/P6z9PskKrFk8CVCr8pseRiHzWgib4Bfr/
+mj68LKcQTH/Y6R16g154eC6PAvxrEDA+hgpVX0I7L781Byh9nqC+KDX5LvlGuQbg
+B2IvrgLs6lfU3aRfTwqUDMj37rmXJTDy3TMAEQEAAbQyTklJQkUgWXV0YWthIChH
+bnVQRyBSZWxlYXNlIEtleSkgPGduaWliZUBmc2lqLm9yZz6JATwEEwEIACYFAlRQ
+OyMCGwMFCQPCZwAFCwcICQMEFQgJCgUWAgMBAAIeAQIXgAAKCRAgcbCKM70/BnX/
+CADQspqXXAVlrwU9SidzYbPAT1iGRmIkHwoD9rtPr/9xbg3jr8azCKpknE3VF0qz
+UH6unsQwxTduGhey0sFwhi96WOqHiU8FYKxNPb786nACaCfOOB1MdymcIxMQ51mS
+0PlIqtOPa1VpZcCVYr9SwQRqcDdy/Oh/Ljifuub4Shrs/VgYIcv74iGyLroSVt6G
+KVNP/HFyQddSOLVcO+hqAQQ0QeTmPhnaaFa2OcZyW+6IGRLhd7N7M0xb988DKllf
+huRRE1sZ3yO2RvcSq35u/5lChID5SS/wA9oDOPyVFLD4JiMPGmgzSO2aI+uT678O
+jjoI5UD8hfbZpg1PZjYqhYlXuQENBFRQOyMBCAC94CWuMHLmP1B7oFxU0FjKv3D6
+RTpLSLqC/nqRWeKVdlSddR4LnO/r9ahRsGgekAEVyeD04SKAD7g3OWMhWvEsK6aY
+gmzc0cLJCJRTsLW+X7kRWo33KUAKIpKYO8VF8iErWejajvo5UgN3y1V/anqlBU45
+DalLk/mu6JXOr6t7u83+IscTrFQTkW17wOxoc6i9zDOU1FoWZFyNU+hxpPCGndfn
+S25qzaEpb1qzxYoHpyttCkGX4R3siX6gAkRLIPhsYK4sZihBZhTBgHdAVYSYkCrK
+hRNWoSb3XpUhdT5l88uPozwxXruXmzk6WCv6ZdCJ+0rGShwJjU1j6g+Fksk9ABEB
+AAGJASUEGAEIAA8FAlRQOyMCGwwFCQPCZwAACgkQIHGwijO9Pwbgqwf7BfdPgAkx
+Mrt0BJeLJu1ItnCQ4cZ8rbuS5gwAxrY80QXDoJquwRWs1AXaBu0VW+9KvWdp0uhQ
+b0Wy7fv40rRtC+T8nuE/1jaf2byMIfQwPVp3ODH+O3WZew1KvrQZquDKimgHxRso
+WH5vq2VjohI8oQuQNN8AYeyxYo74eB8+3WfUrdw4MYiJcKd20MjoZZS16Klb99qm
+LVZfE/dt/+wwZYFB7cpb5vvvE1voqS+ycD2Rt0irRg6ulw7OXoUrJ25sfkrv9otD
+omDl9V//pyJZSp+IiwK4r0xnk8sjXHgXkzUdIyS0AB17Aw1+G2sbUKyX/SdOgzN7
+D8qEd3C7n53TwpkBDQRUUF8HAQgAh1mo8r+kVWVTNsNlyurm2tdZKiQbdeVgpBgc
+DnqI3fAV58C3nC8DVuK5qVGZPB/jbu42jc8BXGP1l6UP+515LQL5GpTtV0pRWUO0
+2WOuTLZBVQcq53vzbg1xVo31rWV96mqGAPs8lGUCm09fpuiVKQojO6/Ihkg7/bnz
+eSbcX5Xk9eKLhyB7tnakuYJeRYm4bjs+YDApK8IFQyevYF8pjTcbLTSNJPW9WLCs
+ozsy11r4xdfRcTWjARVz5VzTnQ+Px8YtsnjQ3qwNJBpsqMLCdDN7YGhh/mlwPjgd
+q/UFf5+bY6f3ew0vshBqInBQycBSmYyoX0Ye3sAS/OR4nu5ZaQARAQABtD5EYXZp
+ZCBTaGF3IChHbnVQRyBSZWxlYXNlIFNpZ25pbmcgS2V5KSA8ZHNoYXdAamFiYmVy
+d29ja3kuY29tPokBPgQTAQIAKAUCVFBfBwIbAwUJCbp27gYLCQgHAwIGFQgCCQoL
+BBYCAwECHgECF4AACgkQBDdvPuCFaVmIoQf+POxCWkCTicRVlq0kust/iwYO1egK
+9FWG130e2Irnv2lAZZN/0S5ibjHCYFp9gfMgmtVTF5oWXjSDAy/kIykQBBcUVx4S
+CJbdMtKSdsSIQMz6P4DxXumxQm79msOsbi5TsdtUwjqdrbu2sHloE7ck/hTXUCkX
+3zuqtxY7W23BCQxVVT5qUaFuAHkkQaaBgAb8gdgixmkIBfu9u8k3k9zUKm/PNfMj
+xClvORkP8gev+XyzNgcXM49h5YYlmDT+Ahv99nUM1wg8yJTjefBAY0fL982Scx30
+nDQO3w7ihALUoj5+TXQjhs3sWPJ8u3pstr9XcfzEZC77/CZmRYNr8g5hBrkBDQRU
+UF8HAQgAodT0id+C6PMV7C8JxE8POGvX2wA6QLw29ESO0Ws8+Jq9EPQ3114mH+sC
++kDsweCDMyaY34i8gvh6hWxG9JfZmSkRUv0QX2zvlcwr8SOZ9dXzrV7ip+QgpzO2
+2eYRnH/RB+KWfFzqSop51sd1Uls41qKphDEm/ZAnnTwxYWX6jElOCpIuemTAiSxp
+qtjPXVftchSEy06/bDRFuC4FevfU5aWTg3FSZEZpk0KF5RZBdzvOfX9PwHf2Fxhg
+QtLkAsdvvWzDToYD0qOecM/MGt1doryBo8IkAiHJ+TRNyVi6/fAq/rig3brF5ETG
+N7W5IRRGoLetY++4YO+1gY7Ea+1tZwARAQABiQElBBgBAgAPBQJUUF8HAhsgBQkJ
+unbuAAoJEAQ3bz7ghWlZ6PAH/iTMC5+H/Ynj7G1KOjhyoufPoM+j+g4Ec8RmEA6v
+YOWIi8F4AU86iS6Sq2HkZXSKxLgAYbWuseFHS6QA/qZPDPdIv8TceE3jMW3ZEmmm
+nCsS6cmkQhpjRCKuWGfaOyZIEV2BT6Ere+MU5jU+wRqkbJGk1BS8myQHkZRN/5dg
+fo5syFYKY4T64Z7DvlbQF70cCARlsIwk4lN6QJ/iqaHR9c2sWtzHfxAvdctApdg5
+w8GRcEpdDMieejha/lBMRTYVWY1vrEg++mkkhvCOkBilDFFCVojOnSdTJy7dNZji
+BlEFwlmcjLq984C5FRwj5+eN0Bev5hZsWobLeRqt8QOGMlG5AQ0EVFBfBwEIAK4b
+kUPSxSlmE8GHAI4FNQDA+QZzIvLPpf1p5JqFULpJeelwfVtbj6qOfPKwXVvam0yH
+OiyrMnffdlZ/6+QXjP665RdbsPzEDPxCH972eGmdw8yV95wmPCVaoyBTH9XBDTX2
+52h0vPjgcbbOLUvUuYBV8C74ir6ESoA20g/rjYEGjJ/UAtgBGIfMo0Vk2Qc6/7wx
+M3jNPxUc/6h5oiggUkgdbFcgzC2sOAUj3nJ0CS01dNPJuAlGPRjig9o61/PiumSO
+Vy98efAetsjLLS00ysAmjxj7eFuxnf73TJOyAItKZPv3i7K4LIgMZXwL71Ox00zU
+dzm6H+/JomSorqtLlOUAEQEAAYkBJQQYAQIADwUCVFBfBwIbDAUJCbp27gAKCRAE
+N28+4IVpWbkxB/0azsvpA9eJPr6oNu3Iw4aCvLQi9I2jodGXpsNg3GN+ATp3PKMi
+21KsneqkYXzwxY+27HAwNSQEmMeyOh37nkPXJMlBgJ0+aV7J2nAj3as310gnV3kY
+Id8NXvLi+YLngqfTyQpxedDhBeSyTYLAP96mDtUuGFQ9/TWBF0wjZkBqFllnsmmU
+Cs9lMmdaFUk1cT1/R1vwiGz1mAaUzyP2NNUnXsoE25TkeXg+Kf95QkxS0C3C9S+c
+A4jCCHXEuGFxMe4+6IbubsVepIUFrlzbUaYpYB8lwFQutoSJ1qLc2jFcW00Qy2Z2
+SOVYJ5oyMhZNei0ZFsgQ9tp2PhtICjm5JfvPmQENBFRDqVIBCAC0k8eZKDmNqdma
+wOlJ/m62L2g8uXT/+/vAEGb1yaib09xI6tfGXzbqlDwrLIZcJsSIT/nt/ajJnIVb
+c3137va4XbwMzsDpAMH4mmiToqk+izEChGm2knzrLwhoflR8aGsKL35QoZT/erdj
+fgPeCRLvf25fHsN2Jb0WIMzC56VkMeFoza+9HZ5hrkemmm+gPvIvhEUopxCyOS8m
+K5WjB4zzIdyDJfkqVpHvafNP0N4LIsedKdyHcj/K3kY4Kejl99GW1z1snBgPamoN
+2/e52Pf6KTw2FjsSGZ72oalcrkBR4wacUizGxKcRD2Y6Xa0g9mwToWdNBQCIII+u
+TzOzq1EDABEBAAG0IVdlcm5lciBLb2NoIChSZWxlYXNlIFNpZ25pbmcgS2V5KYkB
+PQQTAQgAJwUCVEOpUgIbAwUJC6oF9QULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAK
+CRCKhhscfv1g2aH7B/wIW6mVmTmzW2xc1q1MUdssExQBhEeONrbWJ/HiGZP/Maab
+gQ/+wZuThTAwfGM5zFQBOvrBOGURhINU6lYQlcOrVo+V8Z1mNQKFWaKxJaY5Ku1b
+B1OuX9FHLEiMibogHu5fjJIXBE8XrnvueejyFQ5g/uX2xcGgCWlMe49sR3K+lEl3
+n93xTmSNhP52r0gTjMjbqKWKUaIGJ5OcWSrvawdfqLXkxR8phq2AlHHEfxpcZsOp
+9mZirWYQ5jcgGgFP0LYXUw/RnxFpOcrj45qufmyEL9QJKjBV5RaHJbqukefwUInP
+QtVUmINqQxztSh5QxQP2tsUPIeEi5RAoCwLJam8z
+=PXPh
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/watch b/watch
new file mode 100644 (file)
index 0000000..e6d36a1
--- /dev/null
+++ b/watch
@@ -0,0 +1,5 @@
+version=4
+
+opts=pgpsigurlmangle=s/$/.sig/ \
+  https://gnupg.org/ftp/gcrypt/gnupg/gnupg@ANY_VERSION@@ARCHIVE_EXT@ \
+  debian uupdate