[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#863734: unblock: gnupg2/2.1.18-8



On Wed 2017-09-20 23:37:27 +0100, Adam D. Barratt wrote:
> To save digging them out:
>
> <quote>
> I'm assuming that there haven't been any relevant regressions or
> follow-up fixes since the -8 upload?
>
> In any case, we can't simply transplant -8 to p-u, so would need to see
> a debdiff for either a -6+deb9u1 or -8~deb9u1 upload (depending on how
> you structure the changelog), built against and tested on stretch,
> before confirming an upload.
> </quote>

Attached is the debdiff framed as -8~deb9u1 (visible on the "stretch"
branch in https://anonscm.debian.org/git/pkg-gnupg/gnupg2.git/) , which
is basically the same as the debdiff against -8, except for:

 * a new debian/changelog entry
 * updated debian/gbp.conf to point to the relevant branch and be
   buildable from stretch's git-buildpackage
 * updated Vcs-Git: field in debian/control to point to find the
   relevant branch

I've built this against a stretch system and tested it on a stretch
system, and it still works.

Please advise me whether i should make an upload.

   --dkg

diff -Nru gnupg2-2.1.18/debian/changelog gnupg2-2.1.18/debian/changelog
--- gnupg2-2.1.18/debian/changelog	2017-02-13 19:29:34.000000000 -0500
+++ gnupg2-2.1.18/debian/changelog	2017-09-18 16:41:12.000000000 -0400
@@ -1,3 +1,25 @@
+gnupg2 (2.1.18-8~deb9u1) stretch; urgency=medium
+
+  * proposed update to debian stretch
+
+ -- 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 ]
diff -Nru gnupg2-2.1.18/debian/control gnupg2-2.1.18/debian/control
--- gnupg2-2.1.18/debian/control	2017-02-08 19:44:24.000000000 -0500
+++ gnupg2-2.1.18/debian/control	2017-09-18 16:41:12.000000000 -0400
@@ -41,7 +41,7 @@
  libnpth-mingw-w64-dev,
  libz-mingw-w64-dev,
  mingw-w64,
-Vcs-Git: https://anonscm.debian.org/git/pkg-gnupg/gnupg2.git
+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/
 
diff -Nru gnupg2-2.1.18/debian/dirmngr.install gnupg2-2.1.18/debian/dirmngr.install
--- gnupg2-2.1.18/debian/dirmngr.install	2017-02-08 19:44:24.000000000 -0500
+++ gnupg2-2.1.18/debian/dirmngr.install	2017-09-11 12:23:34.000000000 -0400
@@ -1,7 +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/dirmngr-conf.skel
 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 -Nru gnupg2-2.1.18/debian/gbp.conf gnupg2-2.1.18/debian/gbp.conf
--- gnupg2-2.1.18/debian/gbp.conf	2017-02-08 19:44:24.000000000 -0500
+++ gnupg2-2.1.18/debian/gbp.conf	2017-09-18 16:41:12.000000000 -0400
@@ -1,6 +1,10 @@
 [DEFAULT]
 pristine-tar = True
 upstream-vcs-tag = gnupg-%(version)s
+debian-branch = stretch
+
+[buildpackage]
+compression = bzip2
 
 [import-orig]
 filter = [
diff -Nru gnupg2-2.1.18/debian/gnupg.install gnupg2-2.1.18/debian/gnupg.install
--- gnupg2-2.1.18/debian/gnupg.install	2017-02-08 19:44:24.000000000 -0500
+++ gnupg2-2.1.18/debian/gnupg.install	2017-09-18 16:41:12.000000000 -0400
@@ -9,5 +9,4 @@
 debian/tmp/usr/sbin/addgnupghome
 debian/tmp/usr/sbin/applygnupgdefaults
 debian/tmp/usr/share/gnupg/distsigkey.gpg
-debian/tmp/usr/share/gnupg/gpg-conf.skel
 tools/lspgpot usr/bin
diff -Nru gnupg2-2.1.18/debian/patches/0030-scd-Fix-factory-reset.patch gnupg2-2.1.18/debian/patches/0030-scd-Fix-factory-reset.patch
--- gnupg2-2.1.18/debian/patches/0030-scd-Fix-factory-reset.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0030-scd-Fix-factory-reset.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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;
+
+ 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 -Nru gnupg2-2.1.18/debian/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch gnupg2-2.1.18/debian/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch
--- gnupg2-2.1.18/debian/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0031-gpg-Fix-aliases-list-key-list-sig-and-check-sig.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch gnupg2-2.1.18/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
--- gnupg2-2.1.18/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch gnupg2-2.1.18/debian/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch
--- gnupg2-2.1.18/debian/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0033-common-Avoid-warning-about-implicit-declaration-of-g.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch gnupg2-2.1.18/debian/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch
--- gnupg2-2.1.18/debian/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0034-gpg-Fix-memory-leak-in-the-error-case-of-signature-c.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch gnupg2-2.1.18/debian/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch
--- gnupg2-2.1.18/debian/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0035-gpg-Print-a-warning-if-no-command-has-been-given.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch gnupg2-2.1.18/debian/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch
--- gnupg2-2.1.18/debian/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0036-gpgconf-No-ENOENT-warning-with-change-options-et-al.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch gnupg2-2.1.18/debian/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch
--- gnupg2-2.1.18/debian/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch gnupg2-2.1.18/debian/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch
--- gnupg2-2.1.18/debian/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch gnupg2-2.1.18/debian/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch
--- gnupg2-2.1.18/debian/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0040-gpgv-w32-Fix-status-fd.patch gnupg2-2.1.18/debian/patches/0040-gpgv-w32-Fix-status-fd.patch
--- gnupg2-2.1.18/debian/patches/0040-gpgv-w32-Fix-status-fd.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0040-gpgv-w32-Fix-status-fd.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch gnupg2-2.1.18/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
--- gnupg2-2.1.18/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch gnupg2-2.1.18/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
--- gnupg2-2.1.18/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch gnupg2-2.1.18/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
--- gnupg2-2.1.18/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch gnupg2-2.1.18/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch
--- gnupg2-2.1.18/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch gnupg2-2.1.18/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch
--- gnupg2-2.1.18/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch gnupg2-2.1.18/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
--- gnupg2-2.1.18/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch gnupg2-2.1.18/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
--- gnupg2-2.1.18/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch gnupg2-2.1.18/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
--- gnupg2-2.1.18/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch gnupg2-2.1.18/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch
--- gnupg2-2.1.18/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch gnupg2-2.1.18/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
--- gnupg2-2.1.18/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch gnupg2-2.1.18/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
--- gnupg2-2.1.18/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch gnupg2-2.1.18/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
--- gnupg2-2.1.18/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch gnupg2-2.1.18/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch
--- gnupg2-2.1.18/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0054-dirmngr-Fix-error-handling.patch gnupg2-2.1.18/debian/patches/0054-dirmngr-Fix-error-handling.patch
--- gnupg2-2.1.18/debian/patches/0054-dirmngr-Fix-error-handling.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0054-dirmngr-Fix-error-handling.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch gnupg2-2.1.18/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
--- gnupg2-2.1.18/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0056-common-Fix-connecting-to-the-agent.patch gnupg2-2.1.18/debian/patches/0056-common-Fix-connecting-to-the-agent.patch
--- gnupg2-2.1.18/debian/patches/0056-common-Fix-connecting-to-the-agent.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0056-common-Fix-connecting-to-the-agent.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0057-g10-Fix-memory-leak.patch gnupg2-2.1.18/debian/patches/0057-g10-Fix-memory-leak.patch
--- gnupg2-2.1.18/debian/patches/0057-g10-Fix-memory-leak.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0057-g10-Fix-memory-leak.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0058-common-Avoid-undefined-behavior.patch gnupg2-2.1.18/debian/patches/0058-common-Avoid-undefined-behavior.patch
--- gnupg2-2.1.18/debian/patches/0058-common-Avoid-undefined-behavior.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0058-common-Avoid-undefined-behavior.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch gnupg2-2.1.18/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
--- gnupg2-2.1.18/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch gnupg2-2.1.18/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
--- gnupg2-2.1.18/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch gnupg2-2.1.18/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
--- gnupg2-2.1.18/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch gnupg2-2.1.18/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
--- gnupg2-2.1.18/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch gnupg2-2.1.18/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch
--- gnupg2-2.1.18/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch gnupg2-2.1.18/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch
--- gnupg2-2.1.18/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch gnupg2-2.1.18/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch
--- gnupg2-2.1.18/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch gnupg2-2.1.18/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch
--- gnupg2-2.1.18/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch gnupg2-2.1.18/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch
--- gnupg2-2.1.18/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch gnupg2-2.1.18/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch
--- gnupg2-2.1.18/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch gnupg2-2.1.18/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch
--- gnupg2-2.1.18/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch gnupg2-2.1.18/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
--- gnupg2-2.1.18/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch gnupg2-2.1.18/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch
--- gnupg2-2.1.18/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0072-g10-Minor-fixes.patch gnupg2-2.1.18/debian/patches/0072-g10-Minor-fixes.patch
--- gnupg2-2.1.18/debian/patches/0072-g10-Minor-fixes.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0072-g10-Minor-fixes.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch gnupg2-2.1.18/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
--- gnupg2-2.1.18/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch gnupg2-2.1.18/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch
--- gnupg2-2.1.18/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch gnupg2-2.1.18/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
--- gnupg2-2.1.18/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch gnupg2-2.1.18/debian/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch
--- gnupg2-2.1.18/debian/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/avoid-spurious-warnings/0078-gpg-Avoid-spurious-warnings-about-trust-packets.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/series gnupg2-2.1.18/debian/patches/series
--- gnupg2-2.1.18/debian/patches/series	2017-02-13 09:12:56.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/series	2017-09-18 16:41:12.000000000 -0400
@@ -27,3 +27,52 @@
 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 -Nru gnupg2-2.1.18/debian/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch gnupg2-2.1.18/debian/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch
--- gnupg2-2.1.18/debian/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/skel-file-removal/0077-g10-remove-skeleton-options-files.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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 -Nru gnupg2-2.1.18/debian/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch gnupg2-2.1.18/debian/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch
--- gnupg2-2.1.18/debian/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch	1969-12-31 19:00:00.000000000 -0500
+++ gnupg2-2.1.18/debian/patches/skip-missing-signing-keys/0076-g10-Skip-signing-keys-where-no-secret-key-is-availab.patch	2017-09-18 16:41:12.000000000 -0400
@@ -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

Attachment: signature.asc
Description: PGP signature


Reply to: