[Pkg-gnupg-commit] [gnupg2] 01/04: more patches from upstream (Closes: #838153)

Daniel Kahn Gillmor dkg at fifthhorseman.net
Fri Oct 7 12:29:40 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit 6287ff67fd77800bdda06fa4a2bc909e475d4fbf
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date:   Tue Oct 4 16:31:38 2016 -0400

    more patches from upstream (Closes: #838153)
    
    Many changes here, but
    0030-gpg-Fix-regression-in-fingerprint-printing.patch in particular
    fixes #838153.
---
 ...22-gpg-Improve-usability-of-quick-gen-key.patch | 224 ++++++++++
 ...llow-use-of-default-algo-for-quick-addkey.patch |  39 ++
 ...t-a-new-error-status-line-in-quick-adduid.patch |  28 ++
 .../0025-tests-gpgscm-Fix-use-of-pointer.patch     |  66 +++
 ...6-scd-Add-support-of-ECC-pubkey-attribute.patch | 208 +++++++++
 ...d-malloc-failure-due-to-no-key-signatures.patch |  58 +++
 .../0028-gpgscm-Fix-gcrypt-version-check.patch     |  25 ++
 ...ence-diagnostics-about-starting-housekeep.patch |  31 ++
 ...pg-Fix-regression-in-fingerprint-printing.patch |  28 ++
 ...31-dirmngr-Open-file-CRL-s-in-binary-mode.patch |  28 ++
 debian/patches/0032-dirmngr-Fix-type.patch         |  24 +
 ...ding-a-user-id-make-sure-the-keyblock-has.patch |  31 ++
 ...Allow-only-specific-digest-size-for-ECDSA.patch |  56 +++
 .../0035-dirmngr-Removal-of-no-libgcrypt.o.patch   |  52 +++
 .../0036-agent-sm-Set-CTX-after-start_agent.patch  | 220 +++++++++
 ...-Correctly-handle-modules-relying-on-npth.patch |  41 ++
 ...o-not-link-gpg-connect-agent-against-npth.patch |  27 ++
 ...re-that-internal-key-import-is-done-with-.patch |  24 +
 ...e-import-filter-data-object-more-flexible.patch | 163 +++++++
 ...import-if-an-import-filter-removed-all-us.patch |  78 ++++
 ...-dirmngr-Fix-STARTTLS-on-LDAP-connections.patch |  26 ++
 ...mime-parser-callbacks-access-to-the-rfc82.patch |  81 ++++
 ...e-restricted-browser-and-ssh-socket-by-de.patch | 114 +++++
 .../0045-build-Fix-build-against-libiconv.patch    |  94 ++++
 ...e-to-allow-disabling-of-the-extra-sockets.patch |  61 +++
 ...e-the-extra-sockets-in-the-standard-socke.patch |  78 ++++
 ...-Remove-the-warning-for-the-GKR-hijacking.patch |  95 ++++
 ...-dirmngr-scd-npth_init-must-be-after-fork.patch | 225 ++++++++++
 ...ols-Ignore-existing-directories-in-gpgtar.patch |  34 ++
 ...lement-supervised-command-for-systemd-etc.patch | 358 +++++++++++++++
 ...t-supervised-mode-for-the-new-default-soc.patch |  80 ++++
 ...t-cleanup-for-supervised-mode.-Fix-for-W3.patch |  88 ++++
 ...agent-Streamline-the-supervised-mode-code.patch | 491 +++++++++++++++++++++
 ...-error-handling-in-map_supervised_sockets.patch |  33 ++
 ...56-agent-Fix-npth-supervised-mode-problem.patch |  29 ++
 ...other-minor-fix-to-map_supervised_sockets.patch |  31 ++
 ...-Don-t-add-user-attributes-to-the-TOFU-DB.patch |  31 ++
 .../0059-g10-Fix-testing-for-debug-flag.patch      |  25 ++
 .../0060-sm-Remove-statement-without-effect.patch  |  24 +
 ...oid-pointer-arithmetic-on-string-literals.patch |  42 ++
 ...nt-dirmngr-scd-Fix-init_common_subsystems.patch |  98 ++++
 .../patches/0063-agent-Fix-get_socket_name.patch   |  45 ++
 debian/patches/series                              |  42 ++
 43 files changed, 3676 insertions(+)

diff --git a/debian/patches/0022-gpg-Improve-usability-of-quick-gen-key.patch b/debian/patches/0022-gpg-Improve-usability-of-quick-gen-key.patch
new file mode 100644
index 0000000..0b49e68
--- /dev/null
+++ b/debian/patches/0022-gpg-Improve-usability-of-quick-gen-key.patch
@@ -0,0 +1,224 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 13 Sep 2016 11:30:54 +0200
+Subject: gpg: Improve usability of --quick-gen-key.
+
+* g10/keygen.c (FUTURE_STD_): New constants.
+(parse_expire_string): Handle special keywords.
+(parse_algo_usage_expire): Allow "future-default".  Simplify call to
+parse_expire_string.
+(quick_generate_keypair): Always allow an expiration date.  Replace
+former "test-default" by "future-default".
+--
+
+Using an expiration date is pretty common, thus we now allow the
+creation of a standard key with expiration date.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ doc/gpg.texi  | 30 ++++++++++++---------
+ g10/keyedit.c |  2 +-
+ g10/keygen.c  | 86 +++++++++++++++++++++++++++++++++++++++++++----------------
+ 3 files changed, 81 insertions(+), 37 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index 11456c2..b9ca8da 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -615,12 +615,14 @@ answer to a ``Continue?'' style confirmation prompt is required.  In
+ case the user id already exists in the key ring a second prompt to
+ force the creation of the key will show up.
+ 
+-If any of the optional arguments are given, only the primary key is
+-created and no prompts are shown.  For a description of these optional
+-arguments see the command @code{--quick-addkey}.  The @code{usage}
+-accepts also the value ``cert'' which can be used to create a
+-certification only primary key; the default is to a create
+-certification and signing key.
++If @code{algo} or @code{usage} are given, only the primary key is
++created and no prompts are shown.  To specify an expiration date but
++still create a primary and subkey use ``default'' or
++``future-default'' for @code{algo} and ``default'' for @code{usage}.
++For a description of these optional arguments see the command
++ at code{--quick-addkey}.  The @code{usage} accepts also the value
++``cert'' which can be used to create a certification only primary key;
++the default is to a create certification and signing key.
+ 
+ If this command is used with @option{--batch},
+ @option{--pinentry-mode} has been set to @code{loopback}, and one of
+@@ -637,13 +639,15 @@ Directly add a subkey to the key identified by the fingerprint
+ added.  If any of the arguments are given a more specific subkey is
+ added.
+ 
+- at code{algo} may be any of the supported algorithms or curve names given
+-in the format as used by key listings.  To use the default algorithm
+-the string ``default'' or ``-'' can be used. Supported algorithms are
+-``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'', and other ECC
+-curves.  For example the string ``rsa'' adds an RSA key with the
+-default key length; a string ``rsa4096'' requests that the key length
+-is 4096 bits.
++ at code{algo} may be any of the supported algorithms or curve names
++given in the format as used by key listings.  To use the default
++algorithm the string ``default'' or ``-'' can be used.  Supported
++algorithms are ``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'',
++and other ECC curves.  For example the string ``rsa'' adds an RSA key
++with the default key length; a string ``rsa4096'' requests that the
++key length is 4096 bits.  The string ``future-default'' is an alias
++for the algorithm which will likely be used as default algorithm in
++future versions of gpg.
+ 
+ Depending on the given @code{algo} the subkey may either be an
+ encryption subkey or a signing subkey.  If an algorithm is capable of
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 4c833f8..baee180 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -3304,7 +3304,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
+       goto leave;
+     }
+ 
+-  /* Create the subkey.  Noet that the called function already prints
++  /* Create the subkey.  Note that the called function already prints
+    * an error message. */
+   if (!generate_subkeypair (ctrl, keyblock, algostr, usagestr, expirestr))
+     modified = 1;
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 2b3d328..e897075 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -58,6 +58,15 @@
+ #define DEFAULT_STD_SUBKEYUSE  PUBKEY_USAGE_ENC
+ #define DEFAULT_STD_SUBCURVE   NULL
+ 
++#define FUTURE_STD_ALGO        PUBKEY_ALGO_EDDSA
++#define FUTURE_STD_KEYSIZE     0
++#define FUTURE_STD_KEYUSE      (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)
++#define FUTURE_STD_CURVE       "Ed25519"
++#define FUTURE_STD_SUBALGO     PUBKEY_ALGO_ECDH
++#define FUTURE_STD_SUBKEYSIZE  0
++#define FUTURE_STD_SUBKEYUSE   PUBKEY_USAGE_ENC
++#define FUTURE_STD_SUBCURVE    "Curve25519"
++
+ /* Flag bits used during key generation.  */
+ #define KEYGEN_FLAG_NO_PROTECTION 1
+ #define KEYGEN_FLAG_TRANSIENT_KEY 2
+@@ -2330,7 +2339,8 @@ parse_expire_string( const char *string )
+   u32 curtime = make_timestamp ();
+   time_t tt;
+ 
+-  if (!*string)
++  if (!string || !*string || !strcmp (string, "none")
++      || !strcmp (string, "never") || !strcmp (string, "-"))
+     seconds = 0;
+   else if (!strncmp (string, "seconds=", 8))
+     seconds = atoi (string+8);
+@@ -2347,7 +2357,7 @@ parse_expire_string( const char *string )
+   return seconds;
+ }
+ 
+-/* Parsean Creation-Date string which is either "1986-04-26" or
++/* Parse a Creation-Date string which is either "1986-04-26" or
+    "19860426T042640".  Returns 0 on error. */
+ static u32
+ parse_creation_string (const char *string)
+@@ -3612,12 +3622,49 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
+   }
+ 
+ 
+-  if (!strcmp (algostr, "test-default"))
++  if ((!*algostr || !strcmp (algostr, "default")
++       || !strcmp (algostr, "future-default"))
++      && (!*usagestr || !strcmp (usagestr, "default")
++          || !strcmp (usagestr, "-")))
+     {
+-      para = quickgen_set_para (para, 0, PUBKEY_ALGO_EDDSA, 0, "Ed25519", 0);
+-      para = quickgen_set_para (para, 1, PUBKEY_ALGO_ECDH,  0, "Curve25519", 0);
++      if (!strcmp (algostr, "future-default"))
++        {
++          para = quickgen_set_para (para, 0,
++                                    FUTURE_STD_ALGO, FUTURE_STD_KEYSIZE,
++                                    FUTURE_STD_CURVE, 0);
++          para = quickgen_set_para (para, 1,
++                                    FUTURE_STD_SUBALGO,  FUTURE_STD_SUBKEYSIZE,
++                                    FUTURE_STD_SUBCURVE, 0);
++        }
++      else
++        {
++          para = quickgen_set_para (para, 0,
++                                    DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
++                                    DEFAULT_STD_CURVE, 0);
++          para = quickgen_set_para (para, 1,
++                                    DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
++                                    DEFAULT_STD_SUBCURVE, 0);
++        }
++
++      if (*expirestr)
++        {
++          u32 expire;
++
++          expire = parse_expire_string (expirestr);
++          if (expire == (u32)-1 )
++            {
++              err = gpg_error (GPG_ERR_INV_VALUE);
++              log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
++              goto leave;
++            }
++          r = xmalloc_clear (sizeof *r + 20);
++          r->key = pKEYEXPIRE;
++          r->u.expire = expire;
++          r->next = para;
++          para = r;
++        }
+     }
+-  else if (*algostr || *usagestr || *expirestr)
++  else
+     {
+       /* Extended unattended mode.  Creates only the primary key. */
+       int algo;
+@@ -3641,15 +3688,6 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
+       r->next = para;
+       para = r;
+     }
+-  else
+-    {
+-      para = quickgen_set_para (para, 0,
+-                                DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
+-                                DEFAULT_STD_CURVE, 0);
+-      para = quickgen_set_para (para, 1,
+-                                DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
+-                                DEFAULT_STD_SUBCURVE, 0);
+-    }
+ 
+   /* If the pinentry loopback mode is not and we have a static
+      passphrase (i.e. set with --passphrase{,-fd,-file} while in batch
+@@ -4416,9 +4454,15 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
+   if (!algostr || !*algostr
+       || !strcmp (algostr, "default") || !strcmp (algostr, "-"))
+     {
+-      algo = for_subkey? DEFAULT_STD_SUBALGO : DEFAULT_STD_ALGO;
+-      use = for_subkey?  DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
+-      nbits = for_subkey?DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
++      algo  = for_subkey? DEFAULT_STD_SUBALGO    : DEFAULT_STD_ALGO;
++      use   = for_subkey? DEFAULT_STD_SUBKEYUSE  : DEFAULT_STD_KEYUSE;
++      nbits = for_subkey? DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
++    }
++  else if (!strcmp (algostr, "future-default"))
++    {
++      algo  = for_subkey? FUTURE_STD_SUBALGO    : FUTURE_STD_ALGO;
++      use   = for_subkey? FUTURE_STD_SUBKEYUSE  : FUTURE_STD_KEYUSE;
++      nbits = for_subkey? FUTURE_STD_SUBKEYSIZE : FUTURE_STD_KEYSIZE;
+     }
+   else if (*algostr == '&' && strlen (algostr) == 41)
+     {
+@@ -4490,11 +4534,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
+     return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+ 
+   /* Parse the expire string.  */
+-  if (!expirestr || !*expirestr || !strcmp (expirestr, "none")
+-      || !strcmp (expirestr, "never") || !strcmp (expirestr, "-"))
+-    expire = 0;
+-  else
+-    expire = parse_expire_string (expirestr);
++  expire = parse_expire_string (expirestr);
+   if (expire == (u32)-1 )
+     return gpg_error (GPG_ERR_INV_VALUE);
+ 
diff --git a/debian/patches/0023-gpg-Allow-use-of-default-algo-for-quick-addkey.patch b/debian/patches/0023-gpg-Allow-use-of-default-algo-for-quick-addkey.patch
new file mode 100644
index 0000000..b622874
--- /dev/null
+++ b/debian/patches/0023-gpg-Allow-use-of-default-algo-for-quick-addkey.patch
@@ -0,0 +1,39 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 14 Sep 2016 09:46:10 +0200
+Subject: gpg: Allow use of "default" algo for--quick-addkey.
+
+* g10/keygen.c (quick_generate_keypair): Write a status error.
+(parse_algo_usage_expire): Set a default curve.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/keygen.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/g10/keygen.c b/g10/keygen.c
+index e897075..9cf314d 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -3614,6 +3614,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
+                  || !cpr_get_answer_is_yes_def ("quick_keygen.force",
+                                                 _("Create anyway? (y/N) "), 0))
+           {
++            write_status_error ("genkey", gpg_error (304));
+             log_inc_errorcount ();  /* we used log_info */
+             goto leave;
+           }
+@@ -4457,12 +4458,14 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
+       algo  = for_subkey? DEFAULT_STD_SUBALGO    : DEFAULT_STD_ALGO;
+       use   = for_subkey? DEFAULT_STD_SUBKEYUSE  : DEFAULT_STD_KEYUSE;
+       nbits = for_subkey? DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
++      curve = for_subkey? DEFAULT_STD_SUBCURVE   : DEFAULT_STD_CURVE;
+     }
+   else if (!strcmp (algostr, "future-default"))
+     {
+       algo  = for_subkey? FUTURE_STD_SUBALGO    : FUTURE_STD_ALGO;
+       use   = for_subkey? FUTURE_STD_SUBKEYUSE  : FUTURE_STD_KEYUSE;
+       nbits = for_subkey? FUTURE_STD_SUBKEYSIZE : FUTURE_STD_KEYSIZE;
++      curve = for_subkey? FUTURE_STD_SUBCURVE   : FUTURE_STD_CURVE;
+     }
+   else if (*algostr == '&' && strlen (algostr) == 41)
+     {
diff --git a/debian/patches/0024-gpg-Emit-a-new-error-status-line-in-quick-adduid.patch b/debian/patches/0024-gpg-Emit-a-new-error-status-line-in-quick-adduid.patch
new file mode 100644
index 0000000..fd4276f
--- /dev/null
+++ b/debian/patches/0024-gpg-Emit-a-new-error-status-line-in-quick-adduid.patch
@@ -0,0 +1,28 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 14 Sep 2016 10:59:18 +0200
+Subject: gpg: Emit a new error status line in --quick-adduid.
+
+* g10/keyedit.c (menu_adduid): Emit an ERROR status for an existsing
+user id.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/keyedit.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index baee180..25f61ec 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -4308,7 +4308,10 @@ menu_adduid (ctrl_t ctrl, kbnode_t pub_keyblock,
+   if (!uid)
+     {
+       if (uidstring)
+-        log_error ("%s", _("Such a user ID already exists on this key!\n"));
++        {
++          write_status_error ("adduid", gpg_error (304));
++          log_error ("%s", _("Such a user ID already exists on this key!\n"));
++        }
+       return 0;
+     }
+ 
diff --git a/debian/patches/0025-tests-gpgscm-Fix-use-of-pointer.patch b/debian/patches/0025-tests-gpgscm-Fix-use-of-pointer.patch
new file mode 100644
index 0000000..9a1e0cf
--- /dev/null
+++ b/debian/patches/0025-tests-gpgscm-Fix-use-of-pointer.patch
@@ -0,0 +1,66 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Thu, 15 Sep 2016 09:17:59 +0900
+Subject: tests/gpgscm: Fix use of pointer.
+
+* tests/gpgscm/scheme-private.h (struct scheme): Use (void *) for
+alloc_seg.
+* tests/gpgscm/scheme.c (alloc_cellseg): Use (void *) for cp.  Use
+(void *) for coercion of address calculation.
+
+--
+
+In old C language, (char *) means an address.  In modern C, it's
+specifically an address with alignment=1.  It's good to use (void *) for
+an address, because newer compiler emits warnings.  Note: in this
+particular case, it is just a warning and the code is safe against
+invalid alignment, though.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ tests/gpgscm/scheme-private.h | 2 +-
+ tests/gpgscm/scheme.c         | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tests/gpgscm/scheme-private.h b/tests/gpgscm/scheme-private.h
+index 9eafe76..727e0c0 100644
+--- a/tests/gpgscm/scheme-private.h
++++ b/tests/gpgscm/scheme-private.h
+@@ -78,7 +78,7 @@ int tracing;
+ #ifndef CELL_NSEGMENT
+ #define CELL_NSEGMENT   10    /* # of segments for cells */
+ #endif
+-char *alloc_seg[CELL_NSEGMENT];
++void *alloc_seg[CELL_NSEGMENT];
+ pointer cell_seg[CELL_NSEGMENT];
+ int     last_cell_seg;
+ 
+diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c
+index 987f5af..f5299fe 100644
+--- a/tests/gpgscm/scheme.c
++++ b/tests/gpgscm/scheme.c
+@@ -602,7 +602,7 @@ static int alloc_cellseg(scheme *sc, int n) {
+      pointer newp;
+      pointer last;
+      pointer p;
+-     char *cp;
++     void *cp;
+      long i;
+      int k;
+      int adj=ADJ;
+@@ -614,14 +614,14 @@ static int alloc_cellseg(scheme *sc, int n) {
+      for (k = 0; k < n; k++) {
+          if (sc->last_cell_seg >= CELL_NSEGMENT - 1)
+               return k;
+-         cp = (char*) sc->malloc(CELL_SEGSIZE * sizeof(struct cell)+adj);
++         cp = sc->malloc(CELL_SEGSIZE * sizeof(struct cell)+adj);
+          if (cp == 0)
+               return k;
+          i = ++sc->last_cell_seg ;
+          sc->alloc_seg[i] = cp;
+          /* adjust in TYPE_BITS-bit boundary */
+          if(((unsigned long)cp)%adj!=0) {
+-           cp=(char*)(adj*((unsigned long)cp/adj+1));
++           cp=(void *)(adj*((unsigned long)cp/adj+1));
+          }
+          /* insert new segment in address order */
+          newp=(pointer)cp;
diff --git a/debian/patches/0026-scd-Add-support-of-ECC-pubkey-attribute.patch b/debian/patches/0026-scd-Add-support-of-ECC-pubkey-attribute.patch
new file mode 100644
index 0000000..ee149d0
--- /dev/null
+++ b/debian/patches/0026-scd-Add-support-of-ECC-pubkey-attribute.patch
@@ -0,0 +1,208 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Fri, 16 Sep 2016 15:20:32 +0900
+Subject: scd: Add support of ECC pubkey attribute.
+
+* scd/app-openpgp.c (ECC_FLAG_PUBKEY): New.
+(send_key_attr, get_public_key, ecc_writekey, do_auth, do_decipher)
+(parse_algorithm_attribute): Check ECC_FLAG_DJB_TWEAK.
+(build_ecc_privkey_template): Add ECC_Q and ECC_Q_LEN.
+Support offering public key when ECC_FLAG_PUBKEY sets.
+(ecc_writekey): Supply ECC_Q and ECC_Q_LEN.
+(parse_algorithm_attribute): Parse pubkey-required byte.
+
+--
+
+OpenPGPcard protocol specification version 3.2 supports algorithm
+attributes for ECC key which specifies public key data is required for
+"keytocard" command.  This change supports the feature.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ scd/app-openpgp.c | 61 ++++++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 45 insertions(+), 16 deletions(-)
+
+diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
+index 7dd1566..563a045 100644
+--- a/scd/app-openpgp.c
++++ b/scd/app-openpgp.c
+@@ -236,6 +236,7 @@ struct app_local_s {
+ };
+ 
+ #define ECC_FLAG_DJB_TWEAK (1 << 0)
++#define ECC_FLAG_PUBKEY    (1 << 1)
+ 
+ 
+ /***** Local prototypes  *****/
+@@ -910,7 +911,7 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int keyno)
+       snprintf (buffer, sizeof buffer, "%d %d %s",
+                 keyno+1,
+                 keyno==1? PUBKEY_ALGO_ECDH :
+-                app->app_local->keyattr[keyno].ecc.flags?
++                (app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
+                 PUBKEY_ALGO_EDDSA : PUBKEY_ALGO_ECDSA,
+                 openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 0));
+     }
+@@ -1387,7 +1388,7 @@ get_public_key (app_t app, int keyno)
+ 
+   if ((app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA
+        || (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC
+-           && !app->app_local->keyattr[keyno].ecc.flags))
++           && !(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)))
+       && mlen && (*m & 0x80))
+     {               /* Prepend numbers with a 0 if needed for MPI.  */
+       *mbuf = 0;
+@@ -1395,7 +1396,7 @@ get_public_key (app_t app, int keyno)
+       mlen++;
+     }
+   else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC
+-           && app->app_local->keyattr[keyno].ecc.flags)
++           && (app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK))
+     {               /* Prepend 0x40 prefix.  */
+       *mbuf = 0x40;
+       memcpy (mbuf+1, m, mlen);
+@@ -1429,7 +1430,7 @@ get_public_key (app_t app, int keyno)
+     {
+       char *format;
+ 
+-      if (!app->app_local->keyattr[keyno].ecc.flags)
++      if (!(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK))
+         format = "(public-key(ecc(curve%s)(q%b)))";
+       else if (keyno == 1)
+         format = "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))";
+@@ -2633,9 +2634,10 @@ build_privkey_template (app_t app, int keyno,
+ static gpg_error_t
+ build_ecc_privkey_template (app_t app, int keyno,
+                             const unsigned char *ecc_d, size_t ecc_d_len,
++                            const unsigned char *ecc_q, size_t ecc_q_len,
+                             unsigned char **result, size_t *resultlen)
+ {
+-  unsigned char privkey[2];
++  unsigned char privkey[2+2];
+   size_t privkey_len;
+   unsigned char exthdr[2+2+1];
+   size_t exthdr_len;
+@@ -2645,8 +2647,10 @@ build_ecc_privkey_template (app_t app, int keyno,
+   size_t datalen;
+   unsigned char *template;
+   size_t template_size;
++  int pubkey_required;
+ 
+-  (void)app;
++  pubkey_required = !!(app->app_local->keyattr[keyno].ecc.flags
++                       & ECC_FLAG_PUBKEY);
+ 
+   *result = NULL;
+   *resultlen = 0;
+@@ -2658,8 +2662,15 @@ build_ecc_privkey_template (app_t app, int keyno,
+   tp += add_tlv (tp, 0x92, ecc_d_len);
+   datalen += ecc_d_len;
+ 
++  if (pubkey_required)
++    {
++      tp += add_tlv (tp, 0x99, ecc_q_len);
++      datalen += ecc_q_len;
++    }
++
+   privkey_len = tp - privkey;
+ 
++
+   /* Build the extended header list without the private key template.  */
+   tp = exthdr;
+   *tp++ = keyno ==0 ? 0xb6 : keyno == 1? 0xb8 : 0xa4;
+@@ -2693,6 +2704,12 @@ build_ecc_privkey_template (app_t app, int keyno,
+   memcpy (tp, ecc_d, ecc_d_len);
+   tp += ecc_d_len;
+ 
++  if (pubkey_required)
++    {
++      memcpy (tp, ecc_q, ecc_q_len);
++      tp += ecc_q_len;
++    }
++
+   assert (tp - template == template_size);
+ 
+   *result = template;
+@@ -3348,7 +3365,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+ 
+   if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
+       || app->app_local->keyattr[keyno].ecc.oid != oidstr
+-      || app->app_local->keyattr[keyno].ecc.flags != flag_djb_tweak)
++      || (flag_djb_tweak !=
++          (app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)))
+     {
+       if (app->app_local->extcap.algo_attr_change)
+         {
+@@ -3387,6 +3405,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+ 
+       err = build_ecc_privkey_template (app, keyno,
+                                         ecc_d, ecc_d_len,
++                                        ecc_q, ecc_q_len,
+                                         &template, &template_len);
+       if (err)
+         goto leave;
+@@ -3991,7 +4010,7 @@ do_auth (app_t app, const char *keyidstr,
+ 
+   if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECC)
+     {
+-      if (!app->app_local->keyattr[2].ecc.flags
++      if (!(app->app_local->keyattr[2].ecc.flags & ECC_FLAG_DJB_TWEAK)
+           && (indatalen == 51 || indatalen == 67 || indatalen == 83))
+         {
+           const char *p = (const char *)indata + 19;
+@@ -4190,7 +4209,7 @@ do_decipher (app_t app, const char *keyidstr,
+     {
+       int old_format_len = 0;
+ 
+-      if (app->app_local->keyattr[1].ecc.flags)
++      if ((app->app_local->keyattr[1].ecc.flags & ECC_FLAG_DJB_TWEAK))
+         {
+           if (indatalen > 32 && (indatalen % 2))
+             { /*
+@@ -4258,7 +4277,7 @@ do_decipher (app_t app, const char *keyidstr,
+                          outdata, outdatalen);
+   xfree (fixbuf);
+   if (app->app_local->keyattr[1].key_type == KEY_TYPE_ECC
+-      && app->app_local->keyattr[1].ecc.flags)
++      && (app->app_local->keyattr[1].ecc.flags & ECC_FLAG_DJB_TWEAK))
+     { /* Add the prefix 0x40 */
+       fixbuf = xtrymalloc (*outdatalen + 1);
+       if (!fixbuf)
+@@ -4550,7 +4569,19 @@ parse_algorithm_attribute (app_t app, int keyno)
+   else if (*buffer == PUBKEY_ALGO_ECDH || *buffer == PUBKEY_ALGO_ECDSA
+            || *buffer == PUBKEY_ALGO_EDDSA)
+     {
+-      const char *oid = ecc_oid (buffer + 1, buflen - 1);
++      const char *oid;
++      int oidlen = buflen - 1;
++
++      app->app_local->keyattr[keyno].ecc.flags = 0;
++
++      if (buffer[buflen-1] == 0x00 || buffer[buflen-1] == 0xff)
++        { /* Found "pubkey required"-byte for private key template.  */
++          oidlen--;
++          if (buffer[buflen-1] == 0xff)
++            app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_PUBKEY;
++        }
++
++      oid = ecc_oid (buffer + 1, oidlen);
+ 
+       if (!oid)
+         log_printhex ("Curve with OID not supported: ", buffer+1, buflen-1);
+@@ -4562,14 +4593,12 @@ parse_algorithm_attribute (app_t app, int keyno)
+               || (*buffer == PUBKEY_ALGO_ECDH
+                   && !strcmp (app->app_local->keyattr[keyno].ecc.oid,
+                               "1.3.6.1.4.1.3029.1.5.1")))
+-            app->app_local->keyattr[keyno].ecc.flags = ECC_FLAG_DJB_TWEAK;
+-          else
+-            app->app_local->keyattr[keyno].ecc.flags = 0;
++            app->app_local->keyattr[keyno].ecc.flags |= ECC_FLAG_DJB_TWEAK;
+           if (opt.verbose)
+             log_printf
+               ("ECC, curve=%s%s\n", app->app_local->keyattr[keyno].ecc.oid,
+-               !app->app_local->keyattr[keyno].ecc.flags ? "":
+-               keyno==1? " (djb-tweak)": " (eddsa)");
++               !(app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)?
++               "": keyno==1? " (djb-tweak)": " (eddsa)");
+         }
+     }
+   else if (opt.verbose)
diff --git a/debian/patches/0027-gpg-Avoid-malloc-failure-due-to-no-key-signatures.patch b/debian/patches/0027-gpg-Avoid-malloc-failure-due-to-no-key-signatures.patch
new file mode 100644
index 0000000..b293be4
--- /dev/null
+++ b/debian/patches/0027-gpg-Avoid-malloc-failure-due-to-no-key-signatures.patch
@@ -0,0 +1,58 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 19 Sep 2016 08:27:23 +0200
+Subject: gpg: Avoid malloc failure due to no key signatures
+
+* g10/keyedit.c (check_all_keysigs): Check early for no key
+signatures.  Use xtrycalloc.
+--
+
+GnuPG-bug-id: 2690
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/keyedit.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 25f61ec..26b25aa 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -408,20 +408,31 @@ check_all_keysigs (KBNODE kb, int only_selected, int only_selfsigs)
+ 
+   /* First we look for duplicates.  */
+   {
+-    int nsigs = 0;
+-    KBNODE *sigs;
++    int nsigs;
++    kbnode_t *sigs;
+     int i;
+     int last_i;
+ 
+     /* Count the sigs.  */
+-    for (n = kb; n; n = n->next)
+-      if (is_deleted_kbnode (n))
+-        continue;
+-      else if (n->pkt->pkttype == PKT_SIGNATURE)
+-        nsigs ++;
++    for (nsigs = 0, n = kb; n; n = n->next)
++      {
++        if (is_deleted_kbnode (n))
++          continue;
++        else if (n->pkt->pkttype == PKT_SIGNATURE)
++          nsigs ++;
++      }
++
++    if (!nsigs)
++      return 0; /* No signatures at all.  */
+ 
+     /* Add them all to the SIGS array.  */
+-    sigs = xmalloc_clear (sizeof (*sigs) * nsigs);
++    sigs = xtrycalloc (nsigs, sizeof *sigs);
++    if (!sigs)
++      {
++        log_error (_("error allocating memory: %s\n"),
++                   gpg_strerror (gpg_error_from_syserror ()));
++        return 0;
++      }
+ 
+     i = 0;
+     for (n = kb; n; n = n->next)
diff --git a/debian/patches/0028-gpgscm-Fix-gcrypt-version-check.patch b/debian/patches/0028-gpgscm-Fix-gcrypt-version-check.patch
new file mode 100644
index 0000000..b5d90f4
--- /dev/null
+++ b/debian/patches/0028-gpgscm-Fix-gcrypt-version-check.patch
@@ -0,0 +1,25 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 19 Sep 2016 08:41:51 +0200
+Subject: gpgscm: Fix gcrypt version check.
+
+* tests/gpgscm/main.c (main): Check against required and not installed
+version.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ tests/gpgscm/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c
+index 34ebb9f..6dcc923 100644
+--- a/tests/gpgscm/main.c
++++ b/tests/gpgscm/main.c
+@@ -222,7 +222,7 @@ main (int argc, char **argv)
+   i18n_init ();
+   init_common_subsystems (&argc, &argv);
+ 
+-  if (!gcry_check_version (GCRYPT_VERSION))
++  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+     {
+       fputs ("libgcrypt version mismatch\n", stderr);
+       exit (2);
diff --git a/debian/patches/0029-dirmngr-Silence-diagnostics-about-starting-housekeep.patch b/debian/patches/0029-dirmngr-Silence-diagnostics-about-starting-housekeep.patch
new file mode 100644
index 0000000..a09115a
--- /dev/null
+++ b/debian/patches/0029-dirmngr-Silence-diagnostics-about-starting-housekeep.patch
@@ -0,0 +1,31 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 19 Sep 2016 11:47:29 +0200
+Subject: dirmngr: Silence diagnostics about starting housekeeping.
+
+* dirmngr/dirmngr.c (housekeeping_thread): Print info only in very
+verbose mode.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ dirmngr/dirmngr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 4a9e638..7be18cc 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -1715,12 +1715,12 @@ housekeeping_thread (void *arg)
+       return NULL;
+     }
+   sentinel++;
+-  if (opt.verbose)
++  if (opt.verbose > 1)
+     log_info ("starting housekeeping\n");
+ 
+   ks_hkp_housekeeping (curtime);
+ 
+-  if (opt.verbose)
++  if (opt.verbose > 1)
+     log_info ("ready with housekeeping\n");
+   sentinel--;
+   return NULL;
diff --git a/debian/patches/0030-gpg-Fix-regression-in-fingerprint-printing.patch b/debian/patches/0030-gpg-Fix-regression-in-fingerprint-printing.patch
new file mode 100644
index 0000000..853da97
--- /dev/null
+++ b/debian/patches/0030-gpg-Fix-regression-in-fingerprint-printing.patch
@@ -0,0 +1,28 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 19 Sep 2016 17:47:56 +0200
+Subject: gpg: Fix regression in fingerprint printing.
+
+* g10/keylist.c (list_keyblock_print): Do not depend calling
+print_fingerprint on opt.keyid_format.
+--
+
+Regression-due-to: d757009a24eb856770fc3a3729e2f21f54d2a618
+Debian-bug-id: 838153
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/keylist.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index a71effc..ad744d4 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -909,7 +909,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
+   /* Print the "pub" line and in KF_NONE mode the fingerprint.  */
+   print_key_line (es_stdout, pk, secret);
+ 
+-  if (fpr && opt.keyid_format != KF_NONE)
++  if (fpr)
+     print_fingerprint (NULL, pk, 0);
+ 
+   if (opt.with_keygrip && hexgrip)
diff --git a/debian/patches/0031-dirmngr-Open-file-CRL-s-in-binary-mode.patch b/debian/patches/0031-dirmngr-Open-file-CRL-s-in-binary-mode.patch
new file mode 100644
index 0000000..13965cf
--- /dev/null
+++ b/debian/patches/0031-dirmngr-Open-file-CRL-s-in-binary-mode.patch
@@ -0,0 +1,28 @@
+From: Andre Heinecke <aheinecke at intevation.de>
+Date: Thu, 25 Aug 2016 18:15:52 +0200
+Subject: dirmngr: Open file CRL's in binary mode
+
+* dirmngr/crlcache.c (crl_cache_load): Open file in binary mode.
+
+--
+This fixes conversion bugs with binary CRL's on Windows.
+
+GnuPG-bug-id: issue2448
+Signed-off-by: Andre Heinecke <aheinecke at intevation.de>
+---
+ dirmngr/crlcache.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c
+index 388754b..94d5f5f 100644
+--- a/dirmngr/crlcache.c
++++ b/dirmngr/crlcache.c
+@@ -2408,7 +2408,7 @@ crl_cache_load (ctrl_t ctrl, const char *filename)
+   estream_t fp;
+   ksba_reader_t reader;
+ 
+-  fp = es_fopen (filename, "r");
++  fp = es_fopen (filename, "rb");
+   if (!fp)
+     {
+       err = gpg_error_from_errno (errno);
diff --git a/debian/patches/0032-dirmngr-Fix-type.patch b/debian/patches/0032-dirmngr-Fix-type.patch
new file mode 100644
index 0000000..3f08bf5
--- /dev/null
+++ b/debian/patches/0032-dirmngr-Fix-type.patch
@@ -0,0 +1,24 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 20 Sep 2016 10:19:44 +0200
+Subject: dirmngr: Fix type.
+
+* dirmngr/dns-stuff.c (get_dns_cert): Fix type in fallback code.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ 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 191719e..ac295b0 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -990,7 +990,7 @@ get_dns_cert (const char *name, int want_certtype,
+   if (r_key)
+     *r_key = NULL;
+   if (r_keylen)
+-    *r_keylen = NULL;
++    *r_keylen = 0;
+   *r_fpr = NULL;
+   *r_fprlen = 0;
+   *r_url = NULL;
diff --git a/debian/patches/0033-g10-When-adding-a-user-id-make-sure-the-keyblock-has.patch b/debian/patches/0033-g10-When-adding-a-user-id-make-sure-the-keyblock-has.patch
new file mode 100644
index 0000000..ddd075d
--- /dev/null
+++ b/debian/patches/0033-g10-When-adding-a-user-id-make-sure-the-keyblock-has.patch
@@ -0,0 +1,31 @@
+From: "Neal H. Walfield" <neal at g10code.com>
+Date: Thu, 22 Sep 2016 21:32:31 +0200
+Subject: g10: When adding a user id, make sure the keyblock has been prepared.
+
+* g10/keyedit.c (keyedit_quick_adduid): Call merge_keys_and_selfsig on
+KEYBLOCK before adding the user id.
+
+--
+Signed-off-by: Neal H. Walfield <neal at g10code.com>
+GnuPG-bug-id: 2697
+
+this is cherry-picked from upstream commit
+df5353b95eefc13135e7df50a7c197f270d6080d, but without the addition to
+the test suite.
+---
+ g10/keyedit.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 26b25aa..39c3572 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -2932,6 +2932,8 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
+ 
+   fix_keyblock (&keyblock);
+ 
++  merge_keys_and_selfsig (keyblock);
++
+   if (menu_adduid (ctrl, keyblock, 0, NULL, uidstring))
+     {
+       err = keydb_update_keyblock (kdbhd, keyblock);
diff --git a/debian/patches/0034-agent-Allow-only-specific-digest-size-for-ECDSA.patch b/debian/patches/0034-agent-Allow-only-specific-digest-size-for-ECDSA.patch
new file mode 100644
index 0000000..b2416bf
--- /dev/null
+++ b/debian/patches/0034-agent-Allow-only-specific-digest-size-for-ECDSA.patch
@@ -0,0 +1,56 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 27 Sep 2016 14:01:18 +0900
+Subject: agent: Allow only specific digest size for ECDSA.
+
+* agent/pksign.c (do_encode_dsa): Fix validation of digest size.
+
+--
+
+Thanks to Steven Noonan <steven at uplinklabs.net> who offers patches
+and a test case.
+
+GnuPG-bug-id: 2702
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ agent/pksign.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/agent/pksign.c b/agent/pksign.c
+index 9011be2..17f2704 100644
+--- a/agent/pksign.c
++++ b/agent/pksign.c
+@@ -189,25 +189,21 @@ do_encode_dsa (const byte *md, size_t mdlen, int pkalgo, gcry_sexp_t pkey,
+       return gpg_error (GPG_ERR_INV_LENGTH);
+     }
+ 
++  /* ECDSA 521 is special has it is larger than the largest hash
++     we have (SHA-512).  Thus we chnage the size for further
++     processing to 512.  */
++  if (pkalgo == GCRY_PK_ECDSA && qbits > 512)
++    qbits = 512;
++
+   /* Check if we're too short.  Too long is safe as we'll
+-   * automatically left-truncate.
+-   *
+-   * This check would require the use of SHA512 with ECDSA 512. I
+-   * think this is overkill to fail in this case.  Therefore, relax
+-   * the check, but only for ECDSA keys.  We may need to adjust it
+-   * later for general case.  (Note that the check is really a bug for
+-   * ECDSA 521 as the only hash that matches it is SHA 512, but 512 <
+-   * 521 ).
+-   */
+-  if (mdlen < ((pkalgo==GCRY_PK_ECDSA && qbits > 521) ? 512 : qbits)/8)
++     automatically left-truncate.  */
++  if (mdlen < qbits/8)
+     {
+       log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"),
+                  mdlen*8,
+                  gcry_pk_get_nbits (pkey),
+                  gcry_pk_algo_name (pkalgo));
+-      /* FIXME: we need to check the requirements for ECDSA.  */
+-      if (mdlen < 20 || pkalgo == GCRY_PK_DSA)
+-        return gpg_error (GPG_ERR_INV_LENGTH);
++      return gpg_error (GPG_ERR_INV_LENGTH);
+     }
+ 
+   /* Truncate.  */
diff --git a/debian/patches/0035-dirmngr-Removal-of-no-libgcrypt.o.patch b/debian/patches/0035-dirmngr-Removal-of-no-libgcrypt.o.patch
new file mode 100644
index 0000000..a584ab5
--- /dev/null
+++ b/debian/patches/0035-dirmngr-Removal-of-no-libgcrypt.o.patch
@@ -0,0 +1,52 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 27 Sep 2016 14:21:08 +0900
+Subject: dirmngr: Removal of no-libgcrypt.o.
+
+* dirmngr/Makefile.am (dirmngr_ldap_LDADD): Remove no-libgcrypt.o.
+
+--
+
+Thanks to Rainer Perske who located the issue.
+
+GnuPG-bug-id: 2698
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+
+This is a fix for the commit: 49829c29e541546084950b8a153067db371d101a
+---
+ dirmngr/Makefile.am | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
+index 6b0a1e1..6c85886 100644
+--- a/dirmngr/Makefile.am
++++ b/dirmngr/Makefile.am
+@@ -40,10 +40,6 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS)	\
+             $(LIBGNUTLS_CFLAGS)
+ 
+ 
+-BUILT_SOURCES = no-libgcrypt.c
+-
+-CLEANFILES = no-libgcrypt.c
+-
+ if HAVE_W32_SYSTEM
+ ldap_url = ldap-url.h ldap-url.c
+ else
+@@ -93,7 +89,7 @@ if USE_LDAPWRAPPER
+ dirmngr_ldap_SOURCES = dirmngr_ldap.c $(ldap_url)
+ dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS)
+ dirmngr_ldap_LDFLAGS =
+-dirmngr_ldap_LDADD = $(libcommon) no-libgcrypt.o \
++dirmngr_ldap_LDADD = $(libcommon) \
+ 		     $(GPG_ERROR_LIBS) $(LIBGCRYPT_LIBS) $(LDAPLIBS) \
+ 		     $(LBER_LIBS) $(LIBINTL) $(LIBICONV)
+ endif
+@@ -104,9 +100,6 @@ dirmngr_client_LDADD = $(libcommon) \
+                        $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV)
+ dirmngr_client_LDFLAGS = $(extra_bin_ldflags)
+ 
+-no-libgcrypt.c : $(top_srcdir)/tools/no-libgcrypt.c
+-	cat $(top_srcdir)/tools/no-libgcrypt.c > no-libgcrypt.c
+-
+ 
+ t_common_src = t-support.h
+ t_common_ldadd = $(libcommon) $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
diff --git a/debian/patches/0036-agent-sm-Set-CTX-after-start_agent.patch b/debian/patches/0036-agent-sm-Set-CTX-after-start_agent.patch
new file mode 100644
index 0000000..93423a8
--- /dev/null
+++ b/debian/patches/0036-agent-sm-Set-CTX-after-start_agent.patch
@@ -0,0 +1,220 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 27 Sep 2016 14:45:21 +0900
+Subject: agent, sm: Set CTX after start_agent.
+
+* g10/call-agent.c (agent_keytocard): Assign parm.ctx after start_agent.
+* sm/call-agent.c (gpgsm_agent_pksign, gpgsm_scd_pksign)
+(gpgsm_agent_readkey, gpgsm_agent_scd_serialno)
+(gpgsm_agent_scd_keypairinfo, gpgsm_agent_marktrusted)
+(gpgsm_agent_passwd, gpgsm_agent_get_confirmation)
+(gpgsm_agent_ask_passphrase, gpgsm_agent_keywrap_key)
+(gpgsm_agent_export_key): Likewise.
+
+--
+
+Reported-by: Rainer Perske
+GnuPG-bug-id: 2699
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ g10/call-agent.c |  2 +-
+ sm/call-agent.c  | 41 ++++++++++++++++++++++++++++++-----------
+ 2 files changed, 31 insertions(+), 12 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index a023654..93c9b56 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -829,7 +829,6 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
+   struct default_inq_parm_s parm;
+ 
+   memset (&parm, 0, sizeof parm);
+-  parm.ctx = agent_ctx;
+ 
+   snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s",
+             force?"--force ": "", hexgrip, serialno, keyno, timestamp);
+@@ -838,6 +837,7 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
+   rc = start_agent (NULL, 1);
+   if (rc)
+     return rc;
++  parm.ctx = agent_ctx;
+ 
+   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
+                         NULL, NULL);
+diff --git a/sm/call-agent.c b/sm/call-agent.c
+index c7facbb..3262650 100644
+--- a/sm/call-agent.c
++++ b/sm/call-agent.c
+@@ -228,12 +228,13 @@ gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
+   char *p, line[ASSUAN_LINELENGTH];
+   membuf_t data;
+   size_t len;
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_buf = NULL;
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctx = agent_ctx;
+ 
+   if (digestlen*2 + 50 > DIM(line))
+     return gpg_error (GPG_ERR_GENERAL);
+@@ -301,7 +302,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
+   const char *hashopt;
+   unsigned char *sigbuf;
+   size_t sigbuflen;
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   (void)desc;
+ 
+@@ -320,6 +321,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctx = agent_ctx;
+ 
+   if (digestlen*2 + 50 > DIM(line))
+     return gpg_error (GPG_ERR_GENERAL);
+@@ -580,12 +582,13 @@ gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
+   size_t len;
+   unsigned char *buf;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_pubkey = NULL;
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctx = agent_ctx;
+ 
+   rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL);
+   if (rc)
+@@ -668,12 +671,14 @@ gpgsm_agent_scd_serialno (ctrl_t ctrl, char **r_serialno)
+ {
+   int rc;
+   char *serialno = NULL;
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_serialno = NULL;
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   rc = assuan_transact (agent_ctx, "SCD SERIALNO",
+                         NULL, NULL,
+@@ -738,12 +743,14 @@ gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
+ {
+   int rc;
+   strlist_t list = NULL;
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_list = NULL;
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
+                         NULL, NULL,
+@@ -836,11 +843,13 @@ gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert)
+   int rc;
+   char *fpr, *dn, *dnfmt;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
+   if (!fpr)
+@@ -1023,11 +1032,13 @@ gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
+ {
+   int rc;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   if (!hexkeygrip || strlen (hexkeygrip) != 40)
+     return gpg_error (GPG_ERR_INV_VALUE);
+@@ -1059,11 +1070,13 @@ gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc)
+ {
+   int rc;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   rc = start_agent (ctrl);
+   if (rc)
+     return rc;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", desc);
+   line[DIM(line)-1] = 0;
+@@ -1170,13 +1183,15 @@ gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg, int repeat,
+   char line[ASSUAN_LINELENGTH];
+   char *arg4 = NULL;
+   membuf_t data;
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_passphrase = NULL;
+ 
+   err = start_agent (ctrl);
+   if (err)
+     return err;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   if (desc_msg && *desc_msg && !(arg4 = percent_plus_escape (desc_msg)))
+     return gpg_error_from_syserror ();
+@@ -1217,12 +1232,14 @@ gpgsm_agent_keywrap_key (ctrl_t ctrl, int forexport,
+   size_t len;
+   unsigned char *buf;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_kek = NULL;
+   err = start_agent (ctrl);
+   if (err)
+     return err;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
+             forexport? "--export":"--import");
+@@ -1306,13 +1323,15 @@ gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip, const char *desc,
+   size_t len;
+   unsigned char *buf;
+   char line[ASSUAN_LINELENGTH];
+-  struct default_inq_parm_s inq_parm = { ctrl, agent_ctx };
++  struct default_inq_parm_s inq_parm;
+ 
+   *r_result = NULL;
+ 
+   err = start_agent (ctrl);
+   if (err)
+     return err;
++  inq_parm.ctrl = ctrl;
++  inq_parm.ctx = agent_ctx;
+ 
+   if (desc)
+     {
diff --git a/debian/patches/0037-common-Correctly-handle-modules-relying-on-npth.patch b/debian/patches/0037-common-Correctly-handle-modules-relying-on-npth.patch
new file mode 100644
index 0000000..05f6977
--- /dev/null
+++ b/debian/patches/0037-common-Correctly-handle-modules-relying-on-npth.patch
@@ -0,0 +1,41 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 27 Sep 2016 15:54:56 +0200
+Subject: common: Correctly handle modules relying on npth.
+
+* common/Makefile.am (common_sources): Drop 'call-gpg.{c,h}'.
+(with_npth_sources): New variable.
+(libcommonpth_a_SOURCES): Use the new variable.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ common/Makefile.am | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/common/Makefile.am b/common/Makefile.am
+index 422fcf6..9f151f2 100644
+--- a/common/Makefile.am
++++ b/common/Makefile.am
+@@ -88,7 +88,6 @@ common_sources = \
+ 	helpfile.c \
+ 	mkdir_p.c mkdir_p.h \
+ 	strlist.c strlist.h \
+-	call-gpg.c call-gpg.h \
+ 	exectool.c exectool.h \
+ 	server-help.c server-help.h \
+ 	name-value.c name-value.h \
+@@ -114,11 +113,14 @@ endif
+ without_npth_sources = \
+         get-passphrase.c get-passphrase.h
+ 
++# Sources only useful with NPTH.
++with_npth_sources = \
++        call-gpg.c call-gpg.h
+ 
+ libcommon_a_SOURCES = $(common_sources) $(without_npth_sources)
+ libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_NPTH=1
+ 
+-libcommonpth_a_SOURCES = $(common_sources)
++libcommonpth_a_SOURCES = $(common_sources) $(with_npth_sources)
+ libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
+ 
+ if !HAVE_W32CE_SYSTEM
diff --git a/debian/patches/0038-build-Do-not-link-gpg-connect-agent-against-npth.patch b/debian/patches/0038-build-Do-not-link-gpg-connect-agent-against-npth.patch
new file mode 100644
index 0000000..90ac0c5
--- /dev/null
+++ b/debian/patches/0038-build-Do-not-link-gpg-connect-agent-against-npth.patch
@@ -0,0 +1,27 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 27 Sep 2016 17:45:52 +0200
+Subject: build: Do not link gpg-connect-agent against npth.
+
+* tools/Makefile.am: Do not link gpg-connect-agent against npth.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ tools/Makefile.am | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tools/Makefile.am b/tools/Makefile.am
+index 12e5815..c9ff2b4 100644
+--- a/tools/Makefile.am
++++ b/tools/Makefile.am
+@@ -119,10 +119,9 @@ watchgnupg_SOURCES = watchgnupg.c
+ watchgnupg_LDADD = $(NETLIBS)
+ 
+ gpg_connect_agent_SOURCES = gpg-connect-agent.c
+-# FIXME: remove NPTH_LIBS (why do we need them at all?)
+ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
+ 	                  $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
+-                          $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
++                          $(GPG_ERROR_LIBS) \
+                           $(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
+                           $(resource_objs)
+ 
diff --git a/debian/patches/0039-gpg-Make-sure-that-internal-key-import-is-done-with-.patch b/debian/patches/0039-gpg-Make-sure-that-internal-key-import-is-done-with-.patch
new file mode 100644
index 0000000..e537a22
--- /dev/null
+++ b/debian/patches/0039-gpg-Make-sure-that-internal-key-import-is-done-with-.patch
@@ -0,0 +1,24 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 28 Sep 2016 13:36:28 +0200
+Subject: gpg: Make sure that internal key import is done with a binary stream.
+
+* g10/import.c (import_keys_internal): Open stream in binary mode.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/import.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index f7cb923..f16c063 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -465,7 +465,7 @@ import_keys_es_stream (ctrl_t ctrl, estream_t fp,
+   int rc;
+   iobuf_t inp;
+ 
+-  inp = iobuf_esopen (fp, "r", 1);
++  inp = iobuf_esopen (fp, "rb", 1);
+   if (!inp)
+     {
+       rc = gpg_error_from_syserror ();
diff --git a/debian/patches/0040-gpg-Make-import-filter-data-object-more-flexible.patch b/debian/patches/0040-gpg-Make-import-filter-data-object-more-flexible.patch
new file mode 100644
index 0000000..653b1e6
--- /dev/null
+++ b/debian/patches/0040-gpg-Make-import-filter-data-object-more-flexible.patch
@@ -0,0 +1,163 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 28 Sep 2016 13:39:09 +0200
+Subject: gpg: Make import filter data object more flexible.
+
+* g10/main.h (import_filter_t): New.
+* g10/import.c (struct import_filter_s): Declare struct.
+(import_keep_uid, import_drop_sig): Replace by ...
+(import_filter): new.  Adjust all users.
+(cleanup_import_globals): Move code to ...
+(release_import_filter): new.
+(save_and_clear_import_filter): New.
+(restore_import_filter): New.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/import.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++-------------
+ g10/main.h   |  6 +++++
+ 2 files changed, 63 insertions(+), 15 deletions(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index f16c063..8ad1bd9 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -76,16 +76,22 @@ struct import_stats_s
+ #define NODE_FLAG_A  8
+ 
+ 
+-/* Global variables to store selector created from
++/* A an object and a global instance to store selectors created from
+  * --import-filter keep-uid=EXPR.
+  * --import-filter drop-sig=EXPR.
+  *
+  * FIXME: We should put this into the CTRL object but that requires a
+- * lot more changes right now.
++ * lot more changes right now.  For now we use save and restore
++ * fucntion to temporary change them.
+  */
+-static recsel_expr_t import_keep_uid;
+-static recsel_expr_t import_drop_sig;
+-
++/* Definition of the import filters.  */
++struct import_filter_s
++{
++  recsel_expr_t keep_uid;
++  recsel_expr_t drop_sig;
++};
++/* The current instance.  */
++struct import_filter_s import_filter;
+ 
+ 
+ static int import (ctrl_t ctrl,
+@@ -120,12 +126,18 @@ static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs);
+ 
+ 

+ static void
++release_import_filter (import_filter_t filt)
++{
++  recsel_release (filt->keep_uid);
++  filt->keep_uid = NULL;
++  recsel_release (filt->drop_sig);
++  filt->drop_sig = NULL;
++}
++
++static void
+ cleanup_import_globals (void)
+ {
+-  recsel_release (import_keep_uid);
+-  import_keep_uid = NULL;
+-  recsel_release (import_drop_sig);
+-  import_drop_sig = NULL;
++  release_import_filter (&import_filter);
+ }
+ 
+ 
+@@ -201,9 +213,9 @@ parse_and_set_import_filter (const char *string)
+   register_mem_cleanup_func (cleanup_import_globals);
+ 
+   if (!strncmp (string, "keep-uid=", 9))
+-    err = recsel_parse_expr (&import_keep_uid, string+9);
++    err = recsel_parse_expr (&import_filter.keep_uid, string+9);
+   else if (!strncmp (string, "drop-sig=", 9))
+-    err = recsel_parse_expr (&import_drop_sig, string+9);
++    err = recsel_parse_expr (&import_filter.drop_sig, string+9);
+   else
+     err = gpg_error (GPG_ERR_INV_NAME);
+ 
+@@ -211,6 +223,36 @@ parse_and_set_import_filter (const char *string)
+ }
+ 
+ 
++/* Save the current import filters, return them, and clear the current
++ * filters.  Returns NULL on error and sets ERRNO.  */
++import_filter_t
++save_and_clear_import_filter (void)
++{
++  import_filter_t filt;
++
++  filt = xtrycalloc (1, sizeof *filt);
++  if (!filt)
++    return NULL;
++  *filt = import_filter;
++  memset (&import_filter, 0, sizeof import_filter);
++
++  return filt;
++}
++
++
++/* Release the current import filters and restore them from NEWFILT.
++ * Ownership of NEWFILT is moved to this function.  */
++void
++restore_import_filter (import_filter_t filt)
++{
++  if (filt)
++    {
++      release_import_filter (&import_filter);
++      import_filter = *filt;
++      xfree (filt);
++    }
++}
++
+ 
+ import_stats_t
+ import_new_stats_handle (void)
+@@ -1380,14 +1422,14 @@ import_one (ctrl_t ctrl,
+   commit_kbnode (&keyblock);
+ 
+   /* Apply import filter.  */
+-  if (import_keep_uid)
++  if (import_filter.keep_uid)
+     {
+-      apply_keep_uid_filter (keyblock, import_keep_uid);
++      apply_keep_uid_filter (keyblock, import_filter.keep_uid);
+       commit_kbnode (&keyblock);
+     }
+-  if (import_drop_sig)
++  if (import_filter.drop_sig)
+     {
+-      apply_drop_sig_filter (keyblock, import_drop_sig);
++      apply_drop_sig_filter (keyblock, import_filter.drop_sig);
+       commit_kbnode (&keyblock);
+     }
+ 
+diff --git a/g10/main.h b/g10/main.h
+index 0956f66..c7ded7c 100644
+--- a/g10/main.h
++++ b/g10/main.h
+@@ -346,10 +346,16 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk,
+ /*-- import.c --*/
+ struct import_stats_s;
+ typedef struct import_stats_s *import_stats_t;
++struct import_filter_s;
++typedef struct import_filter_s *import_filter_t;
+ typedef gpg_error_t (*import_screener_t)(kbnode_t keyblock, void *arg);
+ 
+ int parse_import_options(char *str,unsigned int *options,int noisy);
++
+ gpg_error_t parse_and_set_import_filter (const char *string);
++import_filter_t save_and_clear_import_filter (void);
++void            restore_import_filter (import_filter_t filt);
++
+ gpg_error_t read_key_from_file (ctrl_t ctrl, const char *fname,
+                                 kbnode_t *r_keyblock);
+ void import_keys (ctrl_t ctrl, char **fnames, int nnames,
diff --git a/debian/patches/0041-gpg-Reject-import-if-an-import-filter-removed-all-us.patch b/debian/patches/0041-gpg-Reject-import-if-an-import-filter-removed-all-us.patch
new file mode 100644
index 0000000..159f754
--- /dev/null
+++ b/debian/patches/0041-gpg-Reject-import-if-an-import-filter-removed-all-us.patch
@@ -0,0 +1,78 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 28 Sep 2016 15:32:04 +0200
+Subject: gpg: Reject import if an import filter removed all user ids.
+
+* g10/import.c (any_uid_left): New.
+(import_one): Check that a UID is left.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/import.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/g10/import.c b/g10/import.c
+index 8ad1bd9..2e8c941 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -115,6 +115,7 @@ static int import_revoke_cert (kbnode_t node, struct import_stats_s *stats);
+ static int chk_self_sigs (kbnode_t keyblock, u32 *keyid, int *non_self);
+ static int delete_inv_parts (kbnode_t keyblock,
+                              u32 *keyid, unsigned int options);
++static int any_uid_left (kbnode_t keyblock);
+ static int merge_blocks (kbnode_t keyblock_orig,
+ 			 kbnode_t keyblock, u32 *keyid,
+ 			 int *n_uids, int *n_sigs, int *n_subk );
+@@ -1315,6 +1316,7 @@ import_one (ctrl_t ctrl,
+   size_t an;
+   char pkstrbuf[PUBKEY_STRING_SIZE];
+   int merge_keys_done = 0;
++  int any_filter = 0;
+ 
+   /* Get the key and print some info about it. */
+   node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
+@@ -1426,13 +1428,25 @@ import_one (ctrl_t ctrl,
+     {
+       apply_keep_uid_filter (keyblock, import_filter.keep_uid);
+       commit_kbnode (&keyblock);
++      any_filter = 1;
+     }
+   if (import_filter.drop_sig)
+     {
+       apply_drop_sig_filter (keyblock, import_filter.drop_sig);
+       commit_kbnode (&keyblock);
++      any_filter = 1;
+     }
+ 
++  /* If we ran any filter we need to check that at least one user id
++   * is left in the keyring.  Note that we do not use log_error in
++   * this case. */
++  if (any_filter && !any_uid_left (keyblock))
++    {
++      if (!opt.quiet )
++        log_info ( _("key %s: no valid user IDs\n"), keystr_from_pk (pk));
++      stats->no_user_id++;
++      return 0;
++    }
+ 
+   /* Show the key in the form it is merged or inserted.  We skip this
+    * if "import-export" is also active without --armor or the output
+@@ -2714,6 +2728,19 @@ delete_inv_parts (kbnode_t keyblock, u32 *keyid, unsigned int options)
+   return nvalid;
+ }
+ 
++/* This function returns true if any UID is left in the keyring.  */
++static int
++any_uid_left (kbnode_t keyblock)
++{
++  kbnode_t node;
++
++  for (node=keyblock->next; node; node = node->next)
++    if (node->pkt->pkttype == PKT_USER_ID)
++      return 1;
++  return 0;
++}
++
++
+ 
+ /****************
+  * It may happen that the imported keyblock has duplicated user IDs.
diff --git a/debian/patches/0042-dirmngr-Fix-STARTTLS-on-LDAP-connections.patch b/debian/patches/0042-dirmngr-Fix-STARTTLS-on-LDAP-connections.patch
new file mode 100644
index 0000000..3a4970a
--- /dev/null
+++ b/debian/patches/0042-dirmngr-Fix-STARTTLS-on-LDAP-connections.patch
@@ -0,0 +1,26 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 29 Sep 2016 14:17:24 +0200
+Subject: dirmngr: Fix STARTTLS on LDAP connections.
+
+* dirmngr/ks-engine-ldap.c (my_ldap_connect): Fix unfortunate typo.
+--
+Courtesy of pkgsrc contributor fhajny.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ dirmngr/ks-engine-ldap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c
+index ad2110e..9b9efc7 100644
+--- a/dirmngr/ks-engine-ldap.c
++++ b/dirmngr/ks-engine-ldap.c
+@@ -513,7 +513,7 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
+ #endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
+ #endif
+ 
+-#ifndef HAVE_LDAP_START_TLS_S
++#ifdef HAVE_LDAP_START_TLS_S
+   if (uri->use_tls)
+     {
+       /* XXX: We need an option to determine whether to abort if the
diff --git a/debian/patches/0043-tools-Give-mime-parser-callbacks-access-to-the-rfc82.patch b/debian/patches/0043-tools-Give-mime-parser-callbacks-access-to-the-rfc82.patch
new file mode 100644
index 0000000..51b787a
--- /dev/null
+++ b/debian/patches/0043-tools-Give-mime-parser-callbacks-access-to-the-rfc82.patch
@@ -0,0 +1,81 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 29 Sep 2016 08:11:32 +0200
+Subject: tools: Give mime parser callbacks access to the rfc822 parser.
+
+* tools/mime-parser.c (mime_parser_context_s): Add field MSG.
+(parse_message_cb): Set it.
+(mime_parser_rfc822parser): New.
+* tools/mime-parser.h: Declare rfc822parse_t for the new prototype.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ tools/mime-parser.c | 17 +++++++++++++++++
+ tools/mime-parser.h |  7 +++++++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/tools/mime-parser.c b/tools/mime-parser.c
+index 5f3659e..87f11d0 100644
+--- a/tools/mime-parser.c
++++ b/tools/mime-parser.c
+@@ -64,6 +64,9 @@ struct mime_parser_context_s
+   /* The callback to collect a signature.  */
+   gpg_error_t (*collect_signature) (void *cookie, const char *data);
+ 
++  /* The RFC822 parser context is stored here during callbacks.  */
++  rfc822parse_t msg;
++
+   /* Helper to convey error codes from user callbacks.  */
+   gpg_error_t err;
+ 
+@@ -189,6 +192,9 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
+   const char *s;
+   int rc = 0;
+ 
++  /* Make the RFC822 parser context availabale for callbacks.  */
++  ctx->msg = msg;
++
+   if (ctx->debug)
+     show_message_parser_event (event);
+ 
+@@ -475,6 +481,8 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
+         }
+     }
+ 
++  ctx->msg = NULL;
++
+   return rc;
+ }
+ 
+@@ -599,6 +607,15 @@ mime_parser_set_collect_signature (mime_parser_t ctx,
+ }
+ 
+ 
++/* Return the RFC888 parser context.  This is only available inside a
++ * callback.  */
++rfc822parse_t
++mime_parser_rfc822parser (mime_parser_t ctx)
++{
++  return ctx->msg;
++}
++
++
+ /* Read and parse a message from FP and call the appropriate
+  * callbacks.  */
+ gpg_error_t
+diff --git a/tools/mime-parser.h b/tools/mime-parser.h
+index ab0d792..b217a2c 100644
+--- a/tools/mime-parser.h
++++ b/tools/mime-parser.h
+@@ -48,5 +48,12 @@ void mime_parser_set_collect_signature (mime_parser_t ctx,
+ gpg_error_t mime_parser_parse (mime_parser_t ctx, estream_t fp);
+ 
+ 
++/* Duplicated declaration of the RFC822 parser context. */
++struct rfc822parse_context;
++typedef struct rfc822parse_context *rfc822parse_t;
++
++rfc822parse_t mime_parser_rfc822parser (mime_parser_t ctx);
++
++
+ 
+ #endif /*GNUPG_MIME_PARSER_H*/
diff --git a/debian/patches/0044-agent-Enable-restricted-browser-and-ssh-socket-by-de.patch b/debian/patches/0044-agent-Enable-restricted-browser-and-ssh-socket-by-de.patch
new file mode 100644
index 0000000..628db05
--- /dev/null
+++ b/debian/patches/0044-agent-Enable-restricted-browser-and-ssh-socket-by-de.patch
@@ -0,0 +1,114 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 15 Sep 2016 14:47:00 +0200
+Subject: agent: Enable restricted, browser, and ssh socket by default.
+
+* agent/gpg-agent.c (main): Provide defaults for 'extra-socket' and
+'browser-socket', enable ssh socket by default, but do not emit the
+'SSH_AUTH_SOCK' variable unless it has been explicitly requested.
+* configure.ac (GPG_AGENT_{EXTRA,BROWSER}_SOCK_NAME): New definitions.
+* doc/gpg-agent.texi: Update documentation.
+--
+
+This change enables the restricted, browser, and ssh socket by
+default.  Note that in all cases, the user has to do some additional
+configuration to her setup to make use of these features.  Therefore,
+this should not break any existing setups, but makes it simpler to
+discover and use these features.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ agent/gpg-agent.c  | 26 +++++++++++++++++---------
+ configure.ac       |  4 ++++
+ doc/gpg-agent.texi |  6 +++++-
+ 3 files changed, 26 insertions(+), 10 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 07e75c0..4aeb241 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1053,6 +1053,18 @@ main (int argc, char **argv )
+       agent_exit (0);
+     }
+ 
++  if (! opt.extra_socket)
++    {
++      opt.extra_socket = 1;  /* (1 = points into r/o section)  */
++      socket_name_extra = GPG_AGENT_EXTRA_SOCK_NAME;
++    }
++
++  if (! opt.browser_socket)
++    {
++      opt.browser_socket = 1;  /* (1 = points into r/o section)  */
++      socket_name_browser = GPG_AGENT_BROWSER_SOCK_NAME;
++    }
++
+   set_debug ();
+ 
+   if (atexit (cleanup))
+@@ -1249,13 +1261,10 @@ main (int argc, char **argv )
+                                              &socket_nonce_browser);
+         }
+ 
+-      if (ssh_support)
+-        {
+-          socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
+-          fd_ssh = create_server_socket (socket_name_ssh, 0, 1,
+-                                         &redir_socket_name_ssh,
+-                                         &socket_nonce_ssh);
+-        }
++      socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
++      fd_ssh = create_server_socket (socket_name_ssh, 0, 1,
++                                     &redir_socket_name_ssh,
++                                     &socket_nonce_ssh);
+ 
+       /* If we are going to exec a program in the parent, we record
+          the PID, so that the child may check whether the program is
+@@ -1321,8 +1330,7 @@ main (int argc, char **argv )
+ 	    *socket_name_extra = 0;
+ 	  if (opt.browser_socket)
+ 	    *socket_name_browser = 0;
+-	  if (ssh_support)
+-	    *socket_name_ssh = 0;
++          *socket_name_ssh = 0;
+ 
+           if (argc)
+             { /* Run the program given on the commandline.  */
+diff --git a/configure.ac b/configure.ac
+index d452021..acfd8c2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1747,6 +1747,10 @@ AC_DEFINE_UNQUOTED(GPGTAR_NAME, "gpgtar", [The name of the gpgtar tool])
+ 
+ AC_DEFINE_UNQUOTED(GPG_AGENT_SOCK_NAME, "S.gpg-agent",
+                    [The name of the agent socket])
++AC_DEFINE_UNQUOTED(GPG_AGENT_EXTRA_SOCK_NAME, "S.gpg-agent.rstrd",
++                   [The name of the agent socket for remote access])
++AC_DEFINE_UNQUOTED(GPG_AGENT_BROWSER_SOCK_NAME, "S.gpg-agent.brwsr",
++                   [The name of the agent socket for browsers])
+ AC_DEFINE_UNQUOTED(GPG_AGENT_SSH_SOCK_NAME, "S.gpg-agent.ssh",
+                    [The name of the agent socket for ssh])
+ AC_DEFINE_UNQUOTED(DIRMNGR_INFO_NAME, "DIRMNGR_INFO",
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index b481dd6..079022d 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -536,6 +536,9 @@ pinentry to pop up at the @code{tty} or display you started the agent.
+ @anchor{option --extra-socket}
+ @item --extra-socket @var{name}
+ @opindex extra-socket
++The extra socket is always created, you may use this option to change
++the name of the socket.
++
+ Also listen on native gpg-agent connections on the given socket.  The
+ intended use for this extra socket is to setup a Unix domain socket
+ forwarding from a remote machine to this socket on the local machine.
+@@ -551,7 +554,8 @@ remote machine.
+ @opindex enable-ssh-support
+ @opindex enable-putty-support
+ 
+-Enable the OpenSSH Agent protocol.
++The OpenSSH Agent protocol is always enabled, but @command{gpg-agent}
++will only set the @code{SSH_AUTH_SOCK} variable if this flag is given.
+ 
+ In this mode of operation, the agent does not only implement the
+ gpg-agent protocol, but also the agent protocol used by OpenSSH
diff --git a/debian/patches/0045-build-Fix-build-against-libiconv.patch b/debian/patches/0045-build-Fix-build-against-libiconv.patch
new file mode 100644
index 0000000..7ef1b1e
--- /dev/null
+++ b/debian/patches/0045-build-Fix-build-against-libiconv.patch
@@ -0,0 +1,94 @@
+From: Justus Winter <justus at g10code.com>
+Date: Fri, 30 Sep 2016 12:34:31 +0200
+Subject: build: Fix build against libiconv.
+
+* agent/Makefile.am: Add INCICONV and LIBICONV.
+* common/Makefile.am: Likewise.
+* tools/Makefile.am: Likewise.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ agent/Makefile.am  |  6 ++++--
+ common/Makefile.am |  2 +-
+ tools/Makefile.am  | 15 +++++++++------
+ 3 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/agent/Makefile.am b/agent/Makefile.am
+index 1970088..ed0ed44 100644
+--- a/agent/Makefile.am
++++ b/agent/Makefile.am
+@@ -64,7 +64,8 @@ pwquery_libs = ../common/libsimple-pwquery.a
+ endif
+ 
+ 
+-gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
++gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) \
++		$(INCICONV)
+ gpg_agent_LDADD = $(commonpth_libs) \
+                 $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
+ 	        $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
+@@ -76,7 +77,8 @@ gpg_protect_tool_SOURCES = \
+ 	protect-tool.c \
+ 	protect.c cvt-openpgp.c
+ 
+-gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
++gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) \
++	$(INCICONV)
+ gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \
+          $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV)
+ 
+diff --git a/common/Makefile.am b/common/Makefile.am
+index 9f151f2..960d1dc 100644
+--- a/common/Makefile.am
++++ b/common/Makefile.am
+@@ -177,7 +177,7 @@ endif
+ t_extra_src = t-support.h
+ 
+ t_common_cflags = $(KSBA_CFLAGS) $(LIBGCRYPT_CFLAGS) \
+-                  $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
++                  $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
+ t_common_ldadd = libcommon.a \
+                  $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+ 	         $(LIBINTL) $(LIBICONV)
+diff --git a/tools/Makefile.am b/tools/Makefile.am
+index c9ff2b4..54486a3 100644
+--- a/tools/Makefile.am
++++ b/tools/Makefile.am
+@@ -128,9 +128,10 @@ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
+ 
+ if !DISABLE_REGEX
+ gpg_check_pattern_SOURCES = gpg-check-pattern.c
+-gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
++gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
+ gpg_check_pattern_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
+-                          $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS)
++			  $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) \
++			  $(LIBICONV)
+ endif
+ 
+ gpgtar_SOURCES = \
+@@ -152,8 +153,9 @@ gpg_wks_server_SOURCES = \
+ 	mime-maker.c  mime-maker.h  \
+ 	send-mail.c   send-mail.h
+ 
+-gpg_wks_server_CFLAGS = $(GPG_ERROR_CFLAGS)
+-gpg_wks_server_LDADD = $(libcommon) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS)
++gpg_wks_server_CFLAGS = $(GPG_ERROR_CFLAGS) $(INCICONV)
++gpg_wks_server_LDADD = $(libcommon) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
++		       $(LIBICONV)
+ 
+ gpg_wks_client_SOURCES = \
+ 	gpg-wks-client.c \
+@@ -166,9 +168,10 @@ gpg_wks_client_SOURCES = \
+ 	send-mail.c   send-mail.h   \
+ 	call-dirmngr.c call-dirmngr.h
+ 
+-gpg_wks_client_CFLAGS = $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
++gpg_wks_client_CFLAGS = $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
+ gpg_wks_client_LDADD = $(libcommon) \
+-	               $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS)
++		       $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
++		       $(LIBICONV)
+ 
+ 
+ # Make sure that all libs are build before we use them.  This is
diff --git a/debian/patches/0046-agent-Kludge-to-allow-disabling-of-the-extra-sockets.patch b/debian/patches/0046-agent-Kludge-to-allow-disabling-of-the-extra-sockets.patch
new file mode 100644
index 0000000..4cc1a3f
--- /dev/null
+++ b/debian/patches/0046-agent-Kludge-to-allow-disabling-of-the-extra-sockets.patch
@@ -0,0 +1,61 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 30 Sep 2016 18:49:16 +0200
+Subject: agent: Kludge to allow disabling of the extra sockets.
+
+* agent/gpg-agent.c (main): Check for special socket names.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c  | 16 ++++++++++++++++
+ doc/gpg-agent.texi |  5 +++--
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 4aeb241..29e0a40 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1058,12 +1058,28 @@ main (int argc, char **argv )
+       opt.extra_socket = 1;  /* (1 = points into r/o section)  */
+       socket_name_extra = GPG_AGENT_EXTRA_SOCK_NAME;
+     }
++  else if (socket_name_extra
++           && (!strcmp (socket_name_extra, "none")
++               || !strcmp (socket_name_extra, "/dev/null")))
++    {
++      /* User requested not to create this socket.  */
++      opt.extra_socket = 0;
++      socket_name_extra = NULL;
++    }
+ 
+   if (! opt.browser_socket)
+     {
+       opt.browser_socket = 1;  /* (1 = points into r/o section)  */
+       socket_name_browser = GPG_AGENT_BROWSER_SOCK_NAME;
+     }
++  else if (socket_name_browser
++           && (!strcmp (socket_name_browser, "none")
++               || !strcmp (socket_name_browser, "/dev/null")))
++    {
++      /* User requested not to create this socket.  */
++      opt.browser_socket = 0;
++      socket_name_browser = NULL;
++    }
+ 
+   set_debug ();
+ 
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index 079022d..c096b61 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -536,8 +536,9 @@ pinentry to pop up at the @code{tty} or display you started the agent.
+ @anchor{option --extra-socket}
+ @item --extra-socket @var{name}
+ @opindex extra-socket
+-The extra socket is always created, you may use this option to change
+-the name of the socket.
++The extra socket is created by default, you may use this option to
++change the name of the socket.  To disable the creation of the socket
++use ``none'' or ``/dev/null'' for @var{name}.
+ 
+ Also listen on native gpg-agent connections on the given socket.  The
+ intended use for this extra socket is to setup a Unix domain socket
diff --git a/debian/patches/0047-agent-Create-the-extra-sockets-in-the-standard-socke.patch b/debian/patches/0047-agent-Create-the-extra-sockets-in-the-standard-socke.patch
new file mode 100644
index 0000000..10e1a05
--- /dev/null
+++ b/debian/patches/0047-agent-Create-the-extra-sockets-in-the-standard-socke.patch
@@ -0,0 +1,78 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 30 Sep 2016 19:21:51 +0200
+Subject: agent: Create the extra sockets in the standard socket dir.
+
+* agent/gpg-agent.c (main): Take the socketdir in account for the
+default sockets.
+* tools/gpgconf.c (list_dirs): Add "agent-extra-socket" and
+"agent-browser-socket".
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c | 18 ++++++++++++------
+ tools/gpgconf.c   |  2 ++
+ 2 files changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 29e0a40..aaebce3 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1055,8 +1055,7 @@ main (int argc, char **argv )
+ 
+   if (! opt.extra_socket)
+     {
+-      opt.extra_socket = 1;  /* (1 = points into r/o section)  */
+-      socket_name_extra = GPG_AGENT_EXTRA_SOCK_NAME;
++      opt.extra_socket = 1;
+     }
+   else if (socket_name_extra
+            && (!strcmp (socket_name_extra, "none")
+@@ -1069,8 +1068,7 @@ main (int argc, char **argv )
+ 
+   if (! opt.browser_socket)
+     {
+-      opt.browser_socket = 1;  /* (1 = points into r/o section)  */
+-      socket_name_browser = GPG_AGENT_BROWSER_SOCK_NAME;
++      opt.browser_socket = 1;
+     }
+   else if (socket_name_browser
+            && (!strcmp (socket_name_browser, "none")
+@@ -1261,7 +1259,11 @@ main (int argc, char **argv )
+ 
+       if (opt.extra_socket)
+         {
+-          socket_name_extra = create_socket_name (socket_name_extra, 0);
++          if (socket_name_extra)
++            socket_name_extra = create_socket_name (socket_name_extra, 0);
++          else
++            socket_name_extra = create_socket_name
++              /**/                (GPG_AGENT_EXTRA_SOCK_NAME, 1);
+           opt.extra_socket = 2; /* Indicate that it has been malloced.  */
+           fd_extra = create_server_socket (socket_name_extra, 0, 0,
+                                            &redir_socket_name_extra,
+@@ -1270,7 +1272,11 @@ main (int argc, char **argv )
+ 
+       if (opt.browser_socket)
+         {
+-          socket_name_browser = create_socket_name (socket_name_browser, 0);
++          if (socket_name_browser)
++            socket_name_browser = create_socket_name (socket_name_browser, 0);
++          else
++            socket_name_browser= create_socket_name
++              /**/                 (GPG_AGENT_BROWSER_SOCK_NAME, 1);
+           opt.browser_socket = 2; /* Indicate that it has been malloced.  */
+           fd_browser = create_server_socket (socket_name_browser, 0, 0,
+                                              &redir_socket_name_browser,
+diff --git a/tools/gpgconf.c b/tools/gpgconf.c
+index 221e3e2..263d726 100644
+--- a/tools/gpgconf.c
++++ b/tools/gpgconf.c
+@@ -165,6 +165,8 @@ list_dirs (estream_t fp, char **names)
+     { "localedir",          gnupg_localedir,  NULL },
+     { "dirmngr-socket",     dirmngr_socket_name, NULL,},
+     { "agent-ssh-socket",   gnupg_socketdir,  GPG_AGENT_SSH_SOCK_NAME },
++    { "agent-extra-socket", gnupg_socketdir,  GPG_AGENT_EXTRA_SOCK_NAME },
++    { "agent-browser-socket",gnupg_socketdir, GPG_AGENT_BROWSER_SOCK_NAME },
+     { "agent-socket",       gnupg_socketdir,  GPG_AGENT_SOCK_NAME },
+     { "homedir",            gnupg_homedir,    NULL }
+   };
diff --git a/debian/patches/0048-agent-Remove-the-warning-for-the-GKR-hijacking.patch b/debian/patches/0048-agent-Remove-the-warning-for-the-GKR-hijacking.patch
new file mode 100644
index 0000000..221d6f1
--- /dev/null
+++ b/debian/patches/0048-agent-Remove-the-warning-for-the-GKR-hijacking.patch
@@ -0,0 +1,95 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 30 Sep 2016 19:38:03 +0200
+Subject: agent: Remove the warning for the GKR hijacking.
+
+* g10/call-agent.c (check_hijacking): Remove.
+(start_agent): Remove call.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ g10/call-agent.c | 65 --------------------------------------------------------
+ 1 file changed, 65 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 93c9b56..0fb392c 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -189,69 +189,6 @@ default_inq_cb (void *opaque, const char *line)
+ }
+ 
+ 
+-/* Check whether gnome-keyring hijacked the gpg-agent.  */
+-static void
+-check_hijacking (assuan_context_t ctx)
+-{
+-  membuf_t mb;
+-  char *string;
+-
+-  init_membuf (&mb, 64);
+-
+-  /* AGENT_ID is a command implemented by gnome-keyring-daemon.  It
+-     does not return any data but an OK line with a remark.  */
+-  if (assuan_transact (ctx, "AGENT_ID",
+-                       put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
+-    {
+-      xfree (get_membuf (&mb, NULL));
+-      return; /* Error - Probably not hijacked.  */
+-    }
+-  put_membuf (&mb, "", 1);
+-  string = get_membuf (&mb, NULL);
+-  if (!string || !*string)
+-    {
+-      /* Definitely hijacked - show a warning prompt.  */
+-      static int shown;
+-      const char warn1[] =
+-        "The GNOME keyring manager hijacked the GnuPG agent.";
+-      const char warn2[] =
+-        "GnuPG will not work properly - please configure that "
+-        "tool to not interfere with the GnuPG system!";
+-      log_info ("WARNING: %s\n", warn1);
+-      log_info ("WARNING: %s\n", warn2);
+-      /*                 (GPG_ERR_SOURCRE_GPG, GPG_ERR_NO_AGENT) */
+-      write_status_text (STATUS_ERROR, "check_hijacking 33554509");
+-      xfree (string);
+-      string = strconcat (warn1, "\n\n", warn2, NULL);
+-      if (string && !shown && !opt.batch)
+-        {
+-          /* NB: The Pinentry based prompt will only work if a
+-             gnome-keyring manager passes invalid commands on to the
+-             original gpg-agent.  */
+-          char *cmd, *cmdargs;
+-
+-          cmdargs = percent_plus_escape (string);
+-          cmd = strconcat ("GET_CONFIRMATION ", cmdargs, NULL);
+-          xfree (cmdargs);
+-          if (cmd)
+-            {
+-              struct default_inq_parm_s dfltparm;
+-
+-              memset (&dfltparm, 0, sizeof dfltparm);
+-              dfltparm.ctx = ctx;
+-              assuan_transact (ctx, cmd, NULL, NULL,
+-                               default_inq_cb, &dfltparm,
+-                               NULL, NULL);
+-              xfree (cmd);
+-              shown = 1;
+-            }
+-        }
+-    }
+-  xfree (string);
+-}
+-
+-
+-
+ /* Print a warning if the server's version number is less than our
+    version number.  Returns an error code on a connection problem.  */
+ static gpg_error_t
+@@ -346,8 +283,6 @@ start_agent (ctrl_t ctrl, int for_card)
+                   write_status_error ("set_pinentry_mode", rc);
+                 }
+             }
+-
+-          check_hijacking (agent_ctx);
+         }
+     }
+ 
diff --git a/debian/patches/0049-agent-dirmngr-scd-npth_init-must-be-after-fork.patch b/debian/patches/0049-agent-dirmngr-scd-npth_init-must-be-after-fork.patch
new file mode 100644
index 0000000..f83eaa8
--- /dev/null
+++ b/debian/patches/0049-agent-dirmngr-scd-npth_init-must-be-after-fork.patch
@@ -0,0 +1,225 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 4 Oct 2016 09:01:13 +0900
+Subject: agent, dirmngr, scd: npth_init must be after fork.
+
+* agent/gpg-agent.c (thread_init_once, initialize_modules): New.
+(main): Make sure no daemonizing-fork call after npth_init, and no npth
+calls before npth_init, with care of npth calls by assuan hooks.
+* dirmngr/dirmngr.c (thread_init): New.
+(main): Make sure npth_init must not be called before daemonizing fork.
+* scd/scdaemon.c (main): Likewise.
+
+--
+
+It is simply the best for nPth not to allow the daemonizing fork after
+npth_init, because semantics and implementations of forked child process
+in a threaded application is a difficult corner case.
+
+GnuPG-bug-id: 1779
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ agent/gpg-agent.c | 36 ++++++++++++++++++++++++++++--------
+ dirmngr/dirmngr.c | 31 ++++++++++++++++++++-----------
+ scd/scdaemon.c    |  6 ++++--
+ 3 files changed, 52 insertions(+), 21 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index aaebce3..c1be1d7 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -721,6 +721,29 @@ finalize_rereadable_options (void)
+ }
+ 
+ 
++static void
++thread_init_once (void)
++{
++  static int npth_initialized = 0;
++
++  if (!npth_initialized)
++    {
++      npth_initialized++;
++      npth_init ();
++    }
++}
++
++static void
++initialize_modules (void)
++{
++  thread_init_once ();
++  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
++  initialize_module_cache ();
++  initialize_module_call_pinentry ();
++  initialize_module_call_scd ();
++  initialize_module_trustlist ();
++}
++
+ 
+ /* The main entry point.  */
+ int
+@@ -773,14 +796,11 @@ main (int argc, char **argv )
+   i18n_init ();
+   init_common_subsystems (&argc, &argv);
+ 
+-  npth_init ();
+-
+   malloc_hooks.malloc = gcry_malloc;
+   malloc_hooks.realloc = gcry_realloc;
+   malloc_hooks.free = gcry_free;
+   assuan_set_malloc_hooks (&malloc_hooks);
+   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+-  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
+   assuan_sock_init ();
+   setup_libassuan_logging (&opt.debug);
+ 
+@@ -1088,16 +1108,12 @@ main (int argc, char **argv )
+       exit (1);
+     }
+ 
+-  initialize_module_cache ();
+-  initialize_module_call_pinentry ();
+-  initialize_module_call_scd ();
+-  initialize_module_trustlist ();
+-
+   /* Try to create missing directories. */
+   create_directories ();
+ 
+   if (debug_wait && pipe_server)
+     {
++      thread_init_once ();
+       log_debug ("waiting for debugger - my pid is %u .....\n",
+                  (unsigned int)getpid());
+       gnupg_sleep (debug_wait);
+@@ -1204,6 +1220,8 @@ main (int argc, char **argv )
+       /* This is the simple pipe based server */
+       ctrl_t ctrl;
+ 
++      initialize_modules ();
++
+       ctrl = xtrycalloc (1, sizeof *ctrl);
+       if (!ctrl)
+         {
+@@ -1411,6 +1429,8 @@ main (int argc, char **argv )
+          This is the child
+        */
+ 
++      initialize_modules ();
++
+       /* Detach from tty and put process into a new session */
+       if (!nodetach )
+         {
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 7be18cc..67f8490 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -647,6 +647,22 @@ pid_suffix_callback (unsigned long *r_suffix)
+ #endif /*!HAVE_W32_SYSTEM*/
+ 
+ 
++static void
++thread_init (void)
++{
++  npth_init ();
++
++  /* Now with NPth running we can set the logging callback.  Our
++     windows implementation does not yet feature the NPth TLS
++     functions.  */
++#ifndef HAVE_W32_SYSTEM
++  if (npth_key_create (&my_tlskey_current_fd, NULL) == 0)
++    if (npth_setspecific (my_tlskey_current_fd, NULL) == 0)
++      log_set_pid_suffix_cb (pid_suffix_callback);
++#endif /*!HAVE_W32_SYSTEM*/
++}
++
++
+ int
+ main (int argc, char **argv)
+ {
+@@ -680,8 +696,6 @@ main (int argc, char **argv)
+   i18n_init ();
+   init_common_subsystems (&argc, &argv);
+ 
+-  npth_init ();
+-
+   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ 
+  /* Check that the libraries are suitable.  Do it here because
+@@ -722,15 +736,6 @@ main (int argc, char **argv)
+   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
+     csh_style = 1;
+ 
+-    /* Now with NPth running we can set the logging callback.  Our
+-     windows implementation does not yet feature the NPth TLS
+-     functions.  */
+-#ifndef HAVE_W32_SYSTEM
+-  if (npth_key_create (&my_tlskey_current_fd, NULL) == 0)
+-    if (npth_setspecific (my_tlskey_current_fd, NULL) == 0)
+-      log_set_pid_suffix_cb (pid_suffix_callback);
+-#endif /*!HAVE_W32_SYSTEM*/
+-
+   /* Reset rereadable options to default values. */
+   parse_rereadable_options (NULL, 0);
+ 
+@@ -981,6 +986,7 @@ main (int argc, char **argv)
+       ldap_wrapper_launch_thread ();
+ #endif /*USE_LDAP*/
+ 
++      thread_init ();
+       cert_cache_init ();
+       crl_cache_init ();
+       start_command_handler (ASSUAN_INVALID_FD);
+@@ -1179,6 +1185,7 @@ main (int argc, char **argv)
+       ldap_wrapper_launch_thread ();
+ #endif /*USE_LDAP*/
+ 
++      thread_init ();
+       cert_cache_init ();
+       crl_cache_init ();
+       handle_connections (fd);
+@@ -1206,6 +1213,7 @@ main (int argc, char **argv)
+ #if USE_LDAP
+       ldap_wrapper_launch_thread ();
+ #endif /*USE_LDAP*/
++      thread_init ();
+       cert_cache_init ();
+       crl_cache_init ();
+       if (!argc)
+@@ -1231,6 +1239,7 @@ main (int argc, char **argv)
+ #if USE_LDAP
+       ldap_wrapper_launch_thread ();
+ #endif /*USE_LDAP*/
++      thread_init ();
+       cert_cache_init ();
+       crl_cache_init ();
+       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index 514e3c2..f0e704b 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -422,8 +422,6 @@ main (int argc, char **argv )
+   i18n_init ();
+   init_common_subsystems (&argc, &argv);
+ 
+-  npth_init ();
+-
+   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
+ 
+   malloc_hooks.malloc = gcry_malloc;
+@@ -724,6 +722,8 @@ main (int argc, char **argv )
+       }
+ #endif
+ 
++      npth_init ();
++
+       /* If --debug-allow-core-dump has been given we also need to
+          switch the working directory to a place where we can actually
+          write. */
+@@ -861,6 +861,8 @@ main (int argc, char **argv )
+ 
+       /* This is the child. */
+ 
++      npth_init ();
++
+       /* Detach from tty and put process into a new session. */
+       if (!nodetach )
+         {
diff --git a/debian/patches/0050-tools-Ignore-existing-directories-in-gpgtar.patch b/debian/patches/0050-tools-Ignore-existing-directories-in-gpgtar.patch
new file mode 100644
index 0000000..954b42a
--- /dev/null
+++ b/debian/patches/0050-tools-Ignore-existing-directories-in-gpgtar.patch
@@ -0,0 +1,34 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 4 Oct 2016 12:44:14 +0200
+Subject: tools: Ignore existing directories in gpgtar.
+
+* tools/gpgtar-extract.c (extract_directory): Ignore existing
+directories now that we have '--directory'.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ tools/gpgtar-extract.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
+index cee609c..8641126 100644
+--- a/tools/gpgtar-extract.c
++++ b/tools/gpgtar-extract.c
+@@ -122,11 +122,15 @@ extract_directory (const char *dirname, tar_header_t hdr)
+   if (fname[strlen (fname)-1] == '/')
+     fname[strlen (fname)-1] = 0;
+ 
+- /* Note that we don't need to care about EEXIST because we always
+-     extract into a new hierarchy.  */
+   if (! opt.dry_run && gnupg_mkdir (fname, "-rwx------"))
+     {
+       err = gpg_error_from_syserror ();
++      if (gpg_err_code (err) == GPG_ERR_EEXIST)
++        {
++          /* Ignore existing directories while extracting.  */
++          err = 0;
++        }
++
+       if (gpg_err_code (err) == GPG_ERR_ENOENT)
+         {
+           /* Try to create the directory with parents but keep the
diff --git a/debian/patches/0051-agent-Implement-supervised-command-for-systemd-etc.patch b/debian/patches/0051-agent-Implement-supervised-command-for-systemd-etc.patch
new file mode 100644
index 0000000..1d06575
--- /dev/null
+++ b/debian/patches/0051-agent-Implement-supervised-command-for-systemd-etc.patch
@@ -0,0 +1,358 @@
+From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
+Date: Fri, 12 Aug 2016 01:37:59 -0400
+Subject: agent: Implement --supervised command (for systemd, etc).
+
+* agent/gpg-agent.c (get_socket_path): New function for POSIX systems
+to return the path for a provided unix-domain socket.
+(map_supervised_sockets): New function to inspect $LISTEN_FDS and
+$LISTEN_FDNAMES and map them to the specific functionality offered by
+the agent.
+(main): Add --supervised command.  When used, listen on already-open
+file descriptors instead of opening our own.
+* doc/gpg-agent.texi: Document --supervised option.
+
+--
+
+"gpg-agent --supervised" is a way to invoke gpg-agent such that a
+system supervisor like systemd can provide socket-activated startup,
+log management, and scheduled shutdown.
+
+When running in this mode, gpg-agent:
+
+ * Does not open its own listening socket; rather, it expects to be
+   given a listening socket on incoming file descriptors.
+
+ * Does not detach from the invoking process, staying in the
+   foreground instead.  Unless otherwise specified, logs are sent to
+   stderr.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
+---
+ agent/gpg-agent.c  | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ doc/gpg-agent.texi |  12 +++
+ 2 files changed, 243 insertions(+), 2 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index c1be1d7..6f301fe 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -93,6 +93,7 @@ enum cmd_and_opt_values
+   oLogFile,
+   oServer,
+   oDaemon,
++  oSupervised,
+   oBatch,
+ 
+   oPinentryProgram,
+@@ -155,6 +156,7 @@ static ARGPARSE_OPTS opts[] = {
+ 
+   ARGPARSE_s_n (oDaemon,  "daemon", N_("run in daemon mode (background)")),
+   ARGPARSE_s_n (oServer,  "server", N_("run in server mode (foreground)")),
++  ARGPARSE_s_n (oSupervised,  "supervised", N_("run supervised (e.g., systemd)")),
+   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
+   ARGPARSE_s_n (oQuiet,	  "quiet",     N_("be somewhat more quiet")),
+   ARGPARSE_s_n (oSh,	  "sh",        N_("sh-style command output")),
+@@ -733,6 +735,7 @@ thread_init_once (void)
+     }
+ }
+ 
++
+ static void
+ initialize_modules (void)
+ {
+@@ -745,6 +748,180 @@ initialize_modules (void)
+ }
+ 
+ 
++/* return a malloc'ed string that is the path to the passed unix-domain socket
++   (or return NULL if this is not a valid unix-domain socket) */
++static char *
++get_socket_path (gnupg_fd_t fd)
++{
++#ifdef HAVE_W32_SYSTEM
++  return NULL;
++#else
++  struct sockaddr_un un;
++  socklen_t len = sizeof(un);
++  char *ret = NULL;
++
++  if (fd == GNUPG_INVALID_FD)
++    return NULL;
++
++  if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
++    log_error ("could not getsockname(%d) -- error %d (%s)\n", fd,
++               errno, strerror(errno));
++  else if (un.sun_family != AF_UNIX)
++    log_error ("file descriptor %d is not a unix-domain socket\n", fd);
++  else if (len <= offsetof (struct sockaddr_un, sun_path))
++    log_error ("socket path not present for file descriptor %d\n", fd);
++  else if (len > sizeof(un))
++    log_error ("socket path for file descriptor %d was truncated "
++               "(passed %lu bytes, wanted %u)\n", fd, sizeof(un), len);
++  else
++    {
++      log_debug ("file descriptor %d has path %s (%lu octets)\n", fd,
++                 un.sun_path, len - offsetof (struct sockaddr_un, sun_path));
++      ret = malloc(len - offsetof (struct sockaddr_un, sun_path));
++      if (ret == NULL)
++        log_error ("failed to allocate memory for path to file "
++                   "descriptor %d\n", fd);
++      else
++        memcpy (ret, un.sun_path, len);
++    }
++  return ret;
++#endif /* HAVE_W32_SYSTEM */
++}
++
++
++/* Discover which inherited file descriptors correspond to which
++   services/sockets offered by gpg-agent, using the LISTEN_FDS and
++   LISTEN_FDNAMES convention.  The understood labels are "ssh",
++   "extra", and "browser".  Any other label will be interpreted as the
++   standard socket.
++
++   This function is designed to log errors when the expected file
++   descriptors don't make sense, but to do its best to continue to
++   work even in the face of minor misconfigurations.
++
++   For more information on the LISTEN_FDS convention, see
++   sd_listen_fds(3).
++ */
++static void
++map_supervised_sockets (gnupg_fd_t *fd,
++                        gnupg_fd_t *fd_extra,
++                        gnupg_fd_t *fd_browser,
++                        gnupg_fd_t *fd_ssh)
++{
++  const char *listen_pid = NULL;
++  const char *listen_fds = NULL;
++  const char *listen_fdnames = NULL;
++  int listen_fd_count = -1;
++  int listen_fdnames_colons = 0;
++  const char *fdnamep = NULL;
++
++  listen_pid = getenv ("LISTEN_PID");
++  listen_fds = getenv ("LISTEN_FDS");
++  listen_fdnames = getenv ("LISTEN_FDNAMES");
++
++  if (!listen_pid)
++    log_error ("no $LISTEN_PID environment variable found in "
++               "--supervised mode (ignoring).\n");
++  else if (atoi (listen_pid) != getpid ())
++    log_error ("$LISTEN_PID (%d) does not match process ID (%d) "
++               "in --supervised mode (ignoring).\n",
++               atoi (listen_pid), getpid ());
++  else
++    log_debug ("$LISTEN_PID matches process ID (%d)\n",
++               getpid());
++
++  if (listen_fdnames)
++    for (fdnamep = listen_fdnames; *fdnamep; fdnamep++)
++      if (*fdnamep == ':')
++        listen_fdnames_colons++;
++  log_debug ("%d colon(s) in $LISTEN_FDNAMES: (%s)\n", listen_fdnames_colons, listen_fdnames);
++
++  if (!listen_fds)
++    {
++      if (!listen_fdnames)
++        {
++          log_error ("no LISTEN_FDS or LISTEN_FDNAMES environment variables "
++                     "found in --supervised mode (assuming 1 active descriptor).\n");
++          listen_fd_count = 1;
++        }
++      else
++        {
++          log_error ("no LISTEN_FDS environment variable found in --supervised "
++                     " mode (relying on colons in LISTEN_FDNAMES instead)\n");
++          listen_fd_count = listen_fdnames_colons + 1;
++        }
++    }
++  else
++    listen_fd_count = atoi (listen_fds);
++
++  if (listen_fd_count < 1)
++    {
++      log_error ("--supervised mode expects at least one file descriptor (was told %d) "
++                 "(carrying on as though it were 1)\n", listen_fd_count);
++      listen_fd_count = 1;
++    }
++
++  if (!listen_fdnames)
++    {
++      if (listen_fd_count != 1)
++        log_error ("no LISTEN_FDNAMES and LISTEN_FDS (%d) != 1 in --supervised mode. "
++                   "(ignoring all sockets but the first one)\n", listen_fd_count);
++      *fd = 3;
++    }
++  else
++    {
++      int i;
++      if (listen_fd_count != listen_fdnames_colons + 1)
++        {
++          log_fatal ("number of items in LISTEN_FDNAMES (%d) does not match "
++                     "LISTEN_FDS (%d) in --supervised mode\n",
++                     listen_fdnames_colons + 1, listen_fd_count);
++          exit (1);
++        }
++
++      for (i = 3; i < 3 + listen_fd_count; i++)
++        {
++          int found = 0;
++          char *next = strchrnul(listen_fdnames, ':');
++          *next = '\0';
++#define match_socket(var) if (!found && strcmp (listen_fdnames, #var) == 0) \
++            {                                                           \
++              found = 1;                                                \
++              if (*fd_ ## var == GNUPG_INVALID_FD)                      \
++                {                                                       \
++                  *fd_ ## var = i;                                      \
++                  log_info (#var " socket on fd %d\n", i);              \
++                }                                                       \
++              else                                                      \
++                {                                                       \
++                  log_error ("cannot listen on more than one " #var " socket. (closing fd %d)\n", i); \
++                  close (i);                                            \
++                }                                                       \
++            }
++          match_socket(ssh);
++          match_socket(browser);
++          match_socket(extra);
++#undef match_socket
++          if (!found)
++            {
++              if (*fd == GNUPG_INVALID_FD)
++                {
++                  *fd = i;
++                  log_info ("standard socket (\"%s\") on fd %d\n",
++                            listen_fdnames, i);
++                }
++              else
++                {
++                  log_error ("cannot listen on more than one standard socket. (closing fd %d)\n", i);
++                  close (i);
++                }
++            }
++          listen_fdnames = next + 1;
++        }
++    }
++}
++
++
+ /* The main entry point.  */
+ int
+ main (int argc, char **argv )
+@@ -760,6 +937,7 @@ main (int argc, char **argv )
+   int default_config =1;
+   int pipe_server = 0;
+   int is_daemon = 0;
++  int is_supervised = 0;
+   int nodetach = 0;
+   int csh_style = 0;
+   char *logfile = NULL;
+@@ -962,6 +1140,7 @@ main (int argc, char **argv )
+         case oSh: csh_style = 0; break;
+         case oServer: pipe_server = 1; break;
+         case oDaemon: is_daemon = 1; break;
++        case oSupervised: is_supervised = 1; break;
+ 
+         case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
+         case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
+@@ -1061,9 +1240,9 @@ main (int argc, char **argv )
+     bind_textdomain_codeset (PACKAGE_GT, "UTF-8");
+ #endif
+ 
+-  if (!pipe_server && !is_daemon && !gpgconf_list)
++  if (!pipe_server && !is_daemon && !gpgconf_list && !is_supervised)
+     {
+-     /* We have been called without any options and thus we merely
++     /* We have been called without any command and thus we merely
+         check whether an agent is already running.  We do this right
+         here so that we don't clobber a logfile with this check but
+         print the status directly to stderr. */
+@@ -1242,6 +1421,54 @@ main (int argc, char **argv )
+       agent_deinit_default_ctrl (ctrl);
+       xfree (ctrl);
+     }
++  else if (is_supervised)
++    {
++      gnupg_fd_t fd = GNUPG_INVALID_FD;
++      gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
++      gnupg_fd_t fd_browser = GNUPG_INVALID_FD;
++      gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
++
++      /* when supervised and sending logs to stderr, the process
++         supervisor should handle log entry metadata (pid, name,
++         timestamp) */
++      if (!logfile)
++        log_set_prefix (NULL, 0);
++
++      log_info ("%s %s starting in supervised mode.\n",
++                strusage(11), strusage(13) );
++
++      map_supervised_sockets (&fd, &fd_extra, &fd_browser, &fd_ssh);
++      if (fd == GNUPG_INVALID_FD)
++        {
++          log_fatal ("no standard socket provided\n");
++          exit (1);
++        }
++      /* record socket names where possible: */
++      socket_name = get_socket_path (fd);
++      socket_name_extra = get_socket_path (fd_extra);
++      if (socket_name_extra)
++        opt.extra_socket = 2;
++      socket_name_browser = get_socket_path (fd_browser);
++      if (socket_name_browser)
++        opt.browser_socket = 2;
++      socket_name_ssh = get_socket_path (fd_ssh);
++
++#ifdef HAVE_SIGPROCMASK
++      if (startup_signal_mask_valid)
++        {
++          if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
++            log_error ("error restoring signal mask: %s\n",
++                       strerror (errno));
++        }
++      else
++        log_info ("no saved signal mask\n");
++#endif /*HAVE_SIGPROCMASK*/
++
++      log_debug ("FDs: std: %d extra: %d browser: %d ssh: %d\n",
++                 fd, fd_extra, fd_browser, fd_ssh);
++      handle_connections (fd, fd_extra, fd_browser, fd_ssh);
++      assuan_sock_close (fd);
++    }
+   else if (!is_daemon)
+     ; /* NOTREACHED */
+   else
+@@ -1254,6 +1481,8 @@ main (int argc, char **argv )
+       pid_t pid;
+ #endif
+ 
++      initialize_modules ();
++
+       /* Remove the DISPLAY variable so that a pinentry does not
+          default to a specific display.  There is still a default
+          display when gpg-agent was started using --display or a
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index c096b61..d40f981 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -158,6 +158,18 @@ As an alternative you may create a new process as a child of
+ gpg-agent: @code{gpg-agent --daemon /bin/sh}.  This way you get a new
+ shell with the environment setup properly; after you exit from this
+ shell, gpg-agent terminates within a few seconds.
++
++ at item --supervised
++ at opindex supervised
++Run in the foreground, sending logs by default to stderr, and
++listening on provided file descriptors, which must already be bound to
++listening sockets.  This command is useful when running under systemd
++or other similar process supervision schemes.
++
++In --supervised mode, different file descriptors can be provided for
++use as different socket types (e.g. ssh, extra) as long as they are
++identified in the environment variable $LISTEN_FDNAMES (see
++sd_listen_fds(3) for more information on this convention).
+ @end table
+ 
+ @mansect options
diff --git a/debian/patches/0052-agent-Adjust-supervised-mode-for-the-new-default-soc.patch b/debian/patches/0052-agent-Adjust-supervised-mode-for-the-new-default-soc.patch
new file mode 100644
index 0000000..0dd129f
--- /dev/null
+++ b/debian/patches/0052-agent-Adjust-supervised-mode-for-the-new-default-soc.patch
@@ -0,0 +1,80 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 4 Oct 2016 11:23:18 +0200
+Subject: agent: Adjust supervised mode for the new default socket names.
+
+* agent/gpg-agent.c (main): In supervised mode do not provide default
+socket names.  Unset DISPLAY and INSIDE_EMACS.  Use log_error and
+agent_exit.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c | 32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 6f301fe..13b6c6a 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1252,10 +1252,10 @@ main (int argc, char **argv )
+       agent_exit (0);
+     }
+ 
+-  if (! opt.extra_socket)
+-    {
+-      opt.extra_socket = 1;
+-    }
++  if (is_supervised)
++    ;
++  else if (!opt.extra_socket)
++    opt.extra_socket = 1;
+   else if (socket_name_extra
+            && (!strcmp (socket_name_extra, "none")
+                || !strcmp (socket_name_extra, "/dev/null")))
+@@ -1265,10 +1265,10 @@ main (int argc, char **argv )
+       socket_name_extra = NULL;
+     }
+ 
+-  if (! opt.browser_socket)
+-    {
+-      opt.browser_socket = 1;
+-    }
++  if (is_supervised)
++    ;
++  else if (!opt.browser_socket)
++    opt.browser_socket = 1;
+   else if (socket_name_browser
+            && (!strcmp (socket_name_browser, "none")
+                || !strcmp (socket_name_browser, "/dev/null")))
+@@ -1437,11 +1437,19 @@ main (int argc, char **argv )
+       log_info ("%s %s starting in supervised mode.\n",
+                 strusage(11), strusage(13) );
+ 
++      /* See below on why we remove certain envvars.  */
++#ifndef HAVE_W32_SYSTEM
++      if (!opt.keep_display)
++        gnupg_unsetenv ("DISPLAY");
++#endif
++      gnupg_unsetenv ("INSIDE_EMACS");
++
++      /* Virtually create the sockets.  */
+       map_supervised_sockets (&fd, &fd_extra, &fd_browser, &fd_ssh);
+       if (fd == GNUPG_INVALID_FD)
+         {
+-          log_fatal ("no standard socket provided\n");
+-          exit (1);
++          log_error ("no standard socket provided\n");
++          agent_exit (1);
+         }
+       /* record socket names where possible: */
+       socket_name = get_socket_path (fd);
+@@ -1464,8 +1472,8 @@ main (int argc, char **argv )
+         log_info ("no saved signal mask\n");
+ #endif /*HAVE_SIGPROCMASK*/
+ 
+-      log_debug ("FDs: std: %d extra: %d browser: %d ssh: %d\n",
+-                 fd, fd_extra, fd_browser, fd_ssh);
++      log_info ("listening on: std=%d extra=%d browser=%d ssh=%d\n",
++                fd, fd_extra, fd_browser, fd_ssh);
+       handle_connections (fd, fd_extra, fd_browser, fd_ssh);
+       assuan_sock_close (fd);
+     }
diff --git a/debian/patches/0053-agent-Adjust-cleanup-for-supervised-mode.-Fix-for-W3.patch b/debian/patches/0053-agent-Adjust-cleanup-for-supervised-mode.-Fix-for-W3.patch
new file mode 100644
index 0000000..1855df4
--- /dev/null
+++ b/debian/patches/0053-agent-Adjust-cleanup-for-supervised-mode.-Fix-for-W3.patch
@@ -0,0 +1,88 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 4 Oct 2016 16:57:55 +0200
+Subject: agent: Adjust cleanup for supervised mode. Fix for W32.
+
+* agent/gpg-agent.c (opts) [W32]: Remove option --supervised.
+(is_supervised): Move from main() to global.
+(inhibit_socket_removal): New.
+(cleanup): Take care of supervise mode and INHIBIT_SOCKET_REMOVAL.
+(check_own_socket_thread): Set INHIBIT_SOCKET_REMOVAL instead of
+seting the socket names to empty.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c | 33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 13b6c6a..719e747 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -156,7 +156,9 @@ static ARGPARSE_OPTS opts[] = {
+ 
+   ARGPARSE_s_n (oDaemon,  "daemon", N_("run in daemon mode (background)")),
+   ARGPARSE_s_n (oServer,  "server", N_("run in server mode (foreground)")),
+-  ARGPARSE_s_n (oSupervised,  "supervised", N_("run supervised (e.g., systemd)")),
++#ifndef HAVE_W32_SYSTEM
++  ARGPARSE_s_n (oSupervised,  "supervised", N_("run in supervised mode")),
++#endif
+   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
+   ARGPARSE_s_n (oQuiet,	  "quiet",     N_("be somewhat more quiet")),
+   ARGPARSE_s_n (oSh,	  "sh",        N_("sh-style command output")),
+@@ -326,6 +328,12 @@ static int check_own_socket_running;
+ /* Flags to indicate that check_own_socket shall not be called.  */
+ static int disable_check_own_socket;
+ 
++/* Flag indicating that we are in supervised mode.  */
++static int is_supervised;
++
++/* Flag to inhibit socket removal in cleanup.  */
++static int inhibit_socket_removal;
++
+ /* It is possible that we are currently running under setuid permissions */
+ static int maybe_setuid = 1;
+ 
+@@ -582,12 +590,15 @@ cleanup (void)
+     return;
+   done = 1;
+   deinitialize_module_cache ();
+-  remove_socket (socket_name, redir_socket_name);
+-  if (opt.extra_socket > 1)
+-    remove_socket (socket_name_extra, redir_socket_name_extra);
+-  if (opt.browser_socket > 1)
+-    remove_socket (socket_name_browser, redir_socket_name_browser);
+-  remove_socket (socket_name_ssh, redir_socket_name_ssh);
++  if (!is_supervised && !inhibit_socket_removal)
++    {
++      remove_socket (socket_name, redir_socket_name);
++      if (opt.extra_socket > 1)
++        remove_socket (socket_name_extra, redir_socket_name_extra);
++      if (opt.browser_socket > 1)
++        remove_socket (socket_name_browser, redir_socket_name_browser);
++      remove_socket (socket_name_ssh, redir_socket_name_ssh);
++    }
+ }
+ 
+ 
+@@ -937,7 +948,6 @@ main (int argc, char **argv )
+   int default_config =1;
+   int pipe_server = 0;
+   int is_daemon = 0;
+-  int is_supervised = 0;
+   int nodetach = 0;
+   int csh_style = 0;
+   char *logfile = NULL;
+@@ -3062,11 +3072,8 @@ check_own_socket_thread (void *arg)
+   if (rc)
+     {
+       /* We may not remove the socket as it is now in use by another
+-         server.  Setting the name to empty does this.  */
+-      if (socket_name)
+-        *socket_name = 0;
+-      if (socket_name_ssh)
+-        *socket_name_ssh = 0;
++         server. */
++      inhibit_socket_removal = 1;
+       shutdown_pending = 2;
+       log_info ("this process is useless - shutting down\n");
+     }
diff --git a/debian/patches/0054-agent-Streamline-the-supervised-mode-code.patch b/debian/patches/0054-agent-Streamline-the-supervised-mode-code.patch
new file mode 100644
index 0000000..ad7ca2e
--- /dev/null
+++ b/debian/patches/0054-agent-Streamline-the-supervised-mode-code.patch
@@ -0,0 +1,491 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 4 Oct 2016 17:02:49 +0200
+Subject: agent: Streamline the supervised mode code.
+
+* agent/gpg-agent.c (get_socket_path): Rename to ...
+(get_socket_name): this.  This is to comply with the GNU coding guide.
+Use xtrymalloc instead of malloc.  Do not build for W32.
+(map_supervised_sockets): Use strtokenize and set the the socket names
+here.
+(main): Adjust for above change.  Do not close the socket.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c  | 408 +++++++++++++++++++++++++++--------------------------
+ doc/gpg-agent.texi |   8 +-
+ 2 files changed, 216 insertions(+), 200 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 719e747..ea23159 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -579,6 +579,208 @@ remove_socket (char *name, char *redir_name)
+ }
+ 
+ 
++/* Return a malloc'ed string that is the path to the passed
++ * unix-domain socket (or return NULL if this is not a valid
++ * unix-domain socket).  We use a plain int here because it is only
++ * used on Linux.
++ *
++ * FIXME: This function needs to be moved to libassuan.  */
++#ifndef HAVE_W32_SYSTEM
++static char *
++get_socket_name (int fd)
++{
++  struct sockaddr_un un;
++  socklen_t len = sizeof(un);
++  char *name = NULL;
++
++  if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
++    log_error ("could not getsockname(%d): %s\n", fd,
++               gpg_strerror (gpg_error_from_syserror ()));
++  else if (un.sun_family != AF_UNIX)
++    log_error ("file descriptor %d is not a unix-domain socket\n", fd);
++  else if (len <= offsetof (struct sockaddr_un, sun_path))
++    log_error ("socket name not present for file descriptor %d\n", fd);
++  else if (len > sizeof(un))
++    log_error ("socket name for file descriptor %d was truncated "
++               "(passed %lu bytes, wanted %u)\n", fd, sizeof(un), len);
++  else
++    {
++      log_debug ("file descriptor %d has path %s (%lu octets)\n", fd,
++                 un.sun_path, len - offsetof (struct sockaddr_un, sun_path));
++      name = xtrymalloc (len - offsetof (struct sockaddr_un, sun_path) + 1);
++      if (!name)
++        log_error ("failed to allocate memory for name of fd %d: %s\n",
++                   fd, gpg_strerror (gpg_error_from_syserror ()));
++      else
++        {
++          memcpy (name, un.sun_path, len);
++          name[len] = 0;
++        }
++    }
++
++  return name;
++}
++#endif /*!HAVE_W32_SYSTEM*/
++
++
++/* Discover which inherited file descriptors correspond to which
++ * services/sockets offered by gpg-agent, using the LISTEN_FDS and
++ * LISTEN_FDNAMES convention.  The understood labels are "ssh",
++ * "extra", and "browser".  "std" or other labels will be interpreted
++ * as the standard socket.
++ *
++ * This function is designed to log errors when the expected file
++ * descriptors don't make sense, but to do its best to continue to
++ * work even in the face of minor misconfigurations.
++ *
++ * For more information on the LISTEN_FDS convention, see
++ * sd_listen_fds(3) on certain Linux distributions.
++ */
++#ifndef HAVE_W32_SYSTEM
++static void
++map_supervised_sockets (gnupg_fd_t *r_fd,
++                        gnupg_fd_t *r_fd_extra,
++                        gnupg_fd_t *r_fd_browser,
++                        gnupg_fd_t *r_fd_ssh)
++{
++  struct {
++    const char *label;
++    int **fdaddr;
++    char **nameaddr;
++  } tbl[] = {
++    { "ssh",     &r_fd_ssh,     &socket_name_ssh },
++    { "browser", &r_fd_browser, &socket_name_browser },
++    { "extra",   &r_fd_extra,   &socket_name_extra },
++    { "std",     &r_fd,         &socket_name }  /* (Must be the last item.)  */
++  };
++  const char *envvar;
++  char **fdnames;
++  int nfdnames;
++  int fd_count;
++
++  *r_fd = *r_fd_extra = *r_fd_browser = *r_fd_ssh = -1;
++
++  /* Print a warning if LISTEN_PID does not match outr pid.  */
++  envvar = getenv ("LISTEN_PID");
++  if (!envvar)
++    log_error ("no LISTEN_PID environment variable found in "
++               "--supervised mode (ignoring)\n");
++  else if (strtoul (envvar, NULL, 10) != (unsigned long)getpid ())
++    log_error ("environment variable LISTEN_PID (%lu) does not match"
++               " our pid (%lu) in --supervised mode (ignoring)\n",
++               (unsigned long)strtoul (envvar, NULL, 10),
++               (unsigned long)getpid ());
++
++  /* Parse LISTEN_FDNAMES into the array FDNAMES.  */
++  envvar = getenv ("LISTEN_FDNAMES");
++  if (envvar)
++    {
++      fdnames = strtokenize (envvar, ":");
++      if (!fdnames)
++        {
++          log_error ("strtokenize failed: %s\n",
++                     gpg_strerror (gpg_error_from_syserror ()));
++          agent_exit (1);
++        }
++      for (nfdnames=0; fdnames[nfdnames]; nfdnames++)
++        ;
++    }
++  else
++    {
++      fdnames = NULL;
++      nfdnames = 0;
++    }
++
++  /* Parse LISTEN_FDS into fd_count or provide a replacement.  */
++  envvar = getenv ("LISTEN_FDS");
++  if (envvar)
++    fd_count = atoi (envvar);
++  else if (fdnames)
++    {
++      log_error ("no LISTEN_FDS environment variable found in --supervised"
++                 " mode (relying on LISTEN_FDNAMES instead)\n");
++      fd_count = nfdnames;
++    }
++  else
++    {
++      log_error ("no LISTEN_FDS or LISTEN_FDNAMES environment variables "
++                "found in --supervised mode"
++                " (assuming 1 active descriptor)\n");
++      fd_count = 1;
++    }
++
++  if (fd_count < 1)
++    {
++      log_error ("--supervised mode expects at least one file descriptor"
++                 " (was told %d, carrying on as though it were 1)\n",
++                 fd_count);
++      fd_count = 1;
++    }
++
++  /* Assign the descriptors to the return values.  */
++  if (!fdnames)
++    {
++      if (fd_count != 1)
++        log_error ("no LISTEN_FDNAMES and LISTEN_FDS (%d) != 1"
++                   " in --supervised mode."
++                   " (ignoring all sockets but the first one)\n",
++                   fd_count);
++      *r_fd = 3;
++    }
++  else if (fd_count != nfdnames)
++    {
++      log_fatal ("number of items in LISTEN_FDNAMES (%d) does not match "
++                 "LISTEN_FDS (%d) in --supervised mode\n",
++                 nfdnames, fd_count);
++    }
++  else
++    {
++      int i, j, fd;
++      char *name;
++
++      for (i = 0; i < nfdnames; i++)
++        {
++          for (j = 0; j < DIM (tbl); j++)
++            {
++              log_debug ("i=%d j=%d fdname=%s check=%s\n", i, j,
++                         fdnames[i], tbl[j].label);
++              if (!strcmp (fdnames[i], tbl[j].label) || j == DIM(tbl)-1)
++                {
++                  if (**tbl[j].fdaddr == -1)
++                    {
++                      fd = 3 + i;
++                      name = get_socket_name (fd);
++                      if (name)
++                        {
++                          **tbl[j].fdaddr = fd;
++                          *tbl[j].nameaddr = name;
++                          log_info ("using fd %d for %s socket (%s)\n",
++                                    fd, tbl[j].label, name);
++                        }
++                      else
++                        {
++                          log_error ("cannot listen on fd %d for %s socket\n",
++                                     fd, tbl[j].label);
++                          close (i);
++                        }
++                    }
++                  else
++                    {
++                      log_error ("cannot listen on more than one %s socket\n",
++                                 tbl[j].label);
++                      close (i);
++                    }
++                  break;
++                }
++            }
++        }
++    }
++
++  xfree (fdnames);
++}
++#endif /*!HAVE_W32_SYSTEM*/
++
++
+ /* Cleanup code for this program.  This is either called has an atexit
+    handler or directly.  */
+ static void
+@@ -759,180 +961,6 @@ initialize_modules (void)
+ }
+ 
+ 
+-/* return a malloc'ed string that is the path to the passed unix-domain socket
+-   (or return NULL if this is not a valid unix-domain socket) */
+-static char *
+-get_socket_path (gnupg_fd_t fd)
+-{
+-#ifdef HAVE_W32_SYSTEM
+-  return NULL;
+-#else
+-  struct sockaddr_un un;
+-  socklen_t len = sizeof(un);
+-  char *ret = NULL;
+-
+-  if (fd == GNUPG_INVALID_FD)
+-    return NULL;
+-
+-  if (getsockname (fd, (struct sockaddr*)&un, &len) != 0)
+-    log_error ("could not getsockname(%d) -- error %d (%s)\n", fd,
+-               errno, strerror(errno));
+-  else if (un.sun_family != AF_UNIX)
+-    log_error ("file descriptor %d is not a unix-domain socket\n", fd);
+-  else if (len <= offsetof (struct sockaddr_un, sun_path))
+-    log_error ("socket path not present for file descriptor %d\n", fd);
+-  else if (len > sizeof(un))
+-    log_error ("socket path for file descriptor %d was truncated "
+-               "(passed %lu bytes, wanted %u)\n", fd, sizeof(un), len);
+-  else
+-    {
+-      log_debug ("file descriptor %d has path %s (%lu octets)\n", fd,
+-                 un.sun_path, len - offsetof (struct sockaddr_un, sun_path));
+-      ret = malloc(len - offsetof (struct sockaddr_un, sun_path));
+-      if (ret == NULL)
+-        log_error ("failed to allocate memory for path to file "
+-                   "descriptor %d\n", fd);
+-      else
+-        memcpy (ret, un.sun_path, len);
+-    }
+-  return ret;
+-#endif /* HAVE_W32_SYSTEM */
+-}
+-
+-
+-/* Discover which inherited file descriptors correspond to which
+-   services/sockets offered by gpg-agent, using the LISTEN_FDS and
+-   LISTEN_FDNAMES convention.  The understood labels are "ssh",
+-   "extra", and "browser".  Any other label will be interpreted as the
+-   standard socket.
+-
+-   This function is designed to log errors when the expected file
+-   descriptors don't make sense, but to do its best to continue to
+-   work even in the face of minor misconfigurations.
+-
+-   For more information on the LISTEN_FDS convention, see
+-   sd_listen_fds(3).
+- */
+-static void
+-map_supervised_sockets (gnupg_fd_t *fd,
+-                        gnupg_fd_t *fd_extra,
+-                        gnupg_fd_t *fd_browser,
+-                        gnupg_fd_t *fd_ssh)
+-{
+-  const char *listen_pid = NULL;
+-  const char *listen_fds = NULL;
+-  const char *listen_fdnames = NULL;
+-  int listen_fd_count = -1;
+-  int listen_fdnames_colons = 0;
+-  const char *fdnamep = NULL;
+-
+-  listen_pid = getenv ("LISTEN_PID");
+-  listen_fds = getenv ("LISTEN_FDS");
+-  listen_fdnames = getenv ("LISTEN_FDNAMES");
+-
+-  if (!listen_pid)
+-    log_error ("no $LISTEN_PID environment variable found in "
+-               "--supervised mode (ignoring).\n");
+-  else if (atoi (listen_pid) != getpid ())
+-    log_error ("$LISTEN_PID (%d) does not match process ID (%d) "
+-               "in --supervised mode (ignoring).\n",
+-               atoi (listen_pid), getpid ());
+-  else
+-    log_debug ("$LISTEN_PID matches process ID (%d)\n",
+-               getpid());
+-
+-  if (listen_fdnames)
+-    for (fdnamep = listen_fdnames; *fdnamep; fdnamep++)
+-      if (*fdnamep == ':')
+-        listen_fdnames_colons++;
+-  log_debug ("%d colon(s) in $LISTEN_FDNAMES: (%s)\n", listen_fdnames_colons, listen_fdnames);
+-
+-  if (!listen_fds)
+-    {
+-      if (!listen_fdnames)
+-        {
+-          log_error ("no LISTEN_FDS or LISTEN_FDNAMES environment variables "
+-                     "found in --supervised mode (assuming 1 active descriptor).\n");
+-          listen_fd_count = 1;
+-        }
+-      else
+-        {
+-          log_error ("no LISTEN_FDS environment variable found in --supervised "
+-                     " mode (relying on colons in LISTEN_FDNAMES instead)\n");
+-          listen_fd_count = listen_fdnames_colons + 1;
+-        }
+-    }
+-  else
+-    listen_fd_count = atoi (listen_fds);
+-
+-  if (listen_fd_count < 1)
+-    {
+-      log_error ("--supervised mode expects at least one file descriptor (was told %d) "
+-                 "(carrying on as though it were 1)\n", listen_fd_count);
+-      listen_fd_count = 1;
+-    }
+-
+-  if (!listen_fdnames)
+-    {
+-      if (listen_fd_count != 1)
+-        log_error ("no LISTEN_FDNAMES and LISTEN_FDS (%d) != 1 in --supervised mode. "
+-                   "(ignoring all sockets but the first one)\n", listen_fd_count);
+-      *fd = 3;
+-    }
+-  else
+-    {
+-      int i;
+-      if (listen_fd_count != listen_fdnames_colons + 1)
+-        {
+-          log_fatal ("number of items in LISTEN_FDNAMES (%d) does not match "
+-                     "LISTEN_FDS (%d) in --supervised mode\n",
+-                     listen_fdnames_colons + 1, listen_fd_count);
+-          exit (1);
+-        }
+-
+-      for (i = 3; i < 3 + listen_fd_count; i++)
+-        {
+-          int found = 0;
+-          char *next = strchrnul(listen_fdnames, ':');
+-          *next = '\0';
+-#define match_socket(var) if (!found && strcmp (listen_fdnames, #var) == 0) \
+-            {                                                           \
+-              found = 1;                                                \
+-              if (*fd_ ## var == GNUPG_INVALID_FD)                      \
+-                {                                                       \
+-                  *fd_ ## var = i;                                      \
+-                  log_info (#var " socket on fd %d\n", i);              \
+-                }                                                       \
+-              else                                                      \
+-                {                                                       \
+-                  log_error ("cannot listen on more than one " #var " socket. (closing fd %d)\n", i); \
+-                  close (i);                                            \
+-                }                                                       \
+-            }
+-          match_socket(ssh);
+-          match_socket(browser);
+-          match_socket(extra);
+-#undef match_socket
+-          if (!found)
+-            {
+-              if (*fd == GNUPG_INVALID_FD)
+-                {
+-                  *fd = i;
+-                  log_info ("standard socket (\"%s\") on fd %d\n",
+-                            listen_fdnames, i);
+-                }
+-              else
+-                {
+-                  log_error ("cannot listen on more than one standard socket. (closing fd %d)\n", i);
+-                  close (i);
+-                }
+-            }
+-          listen_fdnames = next + 1;
+-        }
+-    }
+-}
+-
+-
+ /* The main entry point.  */
+ int
+ main (int argc, char **argv )
+@@ -1433,10 +1461,8 @@ main (int argc, char **argv )
+     }
+   else if (is_supervised)
+     {
+-      gnupg_fd_t fd = GNUPG_INVALID_FD;
+-      gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
+-      gnupg_fd_t fd_browser = GNUPG_INVALID_FD;
+-      gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
++#ifndef HAVE_W32_SYSTEM
++      gnupg_fd_t fd, fd_extra, fd_browser, fd_ssh;
+ 
+       /* when supervised and sending logs to stderr, the process
+          supervisor should handle log entry metadata (pid, name,
+@@ -1447,29 +1473,17 @@ main (int argc, char **argv )
+       log_info ("%s %s starting in supervised mode.\n",
+                 strusage(11), strusage(13) );
+ 
+-      /* See below on why we remove certain envvars.  */
+-#ifndef HAVE_W32_SYSTEM
++      /* See below in "regular server mode" on why we remove certain
++       * envvars.  */
+       if (!opt.keep_display)
+         gnupg_unsetenv ("DISPLAY");
+-#endif
+       gnupg_unsetenv ("INSIDE_EMACS");
+ 
+-      /* Virtually create the sockets.  */
++      /* Virtually create the sockets.  Note that we use -1 here
++       * because the whole thing works only on Unix. */
+       map_supervised_sockets (&fd, &fd_extra, &fd_browser, &fd_ssh);
+-      if (fd == GNUPG_INVALID_FD)
+-        {
+-          log_error ("no standard socket provided\n");
+-          agent_exit (1);
+-        }
+-      /* record socket names where possible: */
+-      socket_name = get_socket_path (fd);
+-      socket_name_extra = get_socket_path (fd_extra);
+-      if (socket_name_extra)
+-        opt.extra_socket = 2;
+-      socket_name_browser = get_socket_path (fd_browser);
+-      if (socket_name_browser)
+-        opt.browser_socket = 2;
+-      socket_name_ssh = get_socket_path (fd_ssh);
++      if (fd == -1)
++        log_fatal ("no standard socket provided\n");
+ 
+ #ifdef HAVE_SIGPROCMASK
+       if (startup_signal_mask_valid)
+@@ -1485,7 +1499,7 @@ main (int argc, char **argv )
+       log_info ("listening on: std=%d extra=%d browser=%d ssh=%d\n",
+                 fd, fd_extra, fd_browser, fd_ssh);
+       handle_connections (fd, fd_extra, fd_browser, fd_ssh);
+-      assuan_sock_close (fd);
++#endif /*!HAVE_W32_SYSTEM*/
+     }
+   else if (!is_daemon)
+     ; /* NOTREACHED */
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index d40f981..232e060 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -164,12 +164,14 @@ shell, gpg-agent terminates within a few seconds.
+ Run in the foreground, sending logs by default to stderr, and
+ listening on provided file descriptors, which must already be bound to
+ listening sockets.  This command is useful when running under systemd
+-or other similar process supervision schemes.
++or other similar process supervision schemes.  This option is not
++supported on Windows.
+ 
+ In --supervised mode, different file descriptors can be provided for
+ use as different socket types (e.g. ssh, extra) as long as they are
+-identified in the environment variable $LISTEN_FDNAMES (see
+-sd_listen_fds(3) for more information on this convention).
++identified in the environment variable @code{LISTEN_FDNAMES} (see
++sd_listen_fds(3) on some Linux distributions for more information on
++this convention).
+ @end table
+ 
+ @mansect options
diff --git a/debian/patches/0055-agent-Fix-error-handling-in-map_supervised_sockets.patch b/debian/patches/0055-agent-Fix-error-handling-in-map_supervised_sockets.patch
new file mode 100644
index 0000000..0b07c0a
--- /dev/null
+++ b/debian/patches/0055-agent-Fix-error-handling-in-map_supervised_sockets.patch
@@ -0,0 +1,33 @@
+From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
+Date: Wed, 5 Oct 2016 00:23:11 -0400
+Subject: agent: Fix error handling in map_supervised_sockets
+
+* agent/gpg-agent.c (map_supervised_sockets): the file descriptor to
+  close on error is fd, not i.
+
+Signed-off-by: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
+---
+ agent/gpg-agent.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index ea23159..26994bd 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -761,14 +761,14 @@ map_supervised_sockets (gnupg_fd_t *r_fd,
+                         {
+                           log_error ("cannot listen on fd %d for %s socket\n",
+                                      fd, tbl[j].label);
+-                          close (i);
++                          close (fd);
+                         }
+                     }
+                   else
+                     {
+                       log_error ("cannot listen on more than one %s socket\n",
+                                  tbl[j].label);
+-                      close (i);
++                      close (fd);
+                     }
+                   break;
+                 }
diff --git a/debian/patches/0056-agent-Fix-npth-supervised-mode-problem.patch b/debian/patches/0056-agent-Fix-npth-supervised-mode-problem.patch
new file mode 100644
index 0000000..d5edaa0
--- /dev/null
+++ b/debian/patches/0056-agent-Fix-npth-supervised-mode-problem.patch
@@ -0,0 +1,29 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 5 Oct 2016 09:13:27 +0200
+Subject: agent: Fix npth + supervised mode problem.
+
+* agent/gpg-agent.c (main): Initialize modules in supervised mode.
+--
+
+It was probably my fault.  I had to rebase my patches to take in the
+npth patches but for some reason my addition of initialize_modules got
+lost.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 26994bd..054e845 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1464,6 +1464,8 @@ main (int argc, char **argv )
+ #ifndef HAVE_W32_SYSTEM
+       gnupg_fd_t fd, fd_extra, fd_browser, fd_ssh;
+ 
++      initialize_modules ();
++
+       /* when supervised and sending logs to stderr, the process
+          supervisor should handle log entry metadata (pid, name,
+          timestamp) */
diff --git a/debian/patches/0057-agent-Another-minor-fix-to-map_supervised_sockets.patch b/debian/patches/0057-agent-Another-minor-fix-to-map_supervised_sockets.patch
new file mode 100644
index 0000000..24f2a2e
--- /dev/null
+++ b/debian/patches/0057-agent-Another-minor-fix-to-map_supervised_sockets.patch
@@ -0,0 +1,31 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 5 Oct 2016 11:48:59 +0200
+Subject: agent: Another minor fix to map_supervised_sockets.
+
+* agent/gpg-agent.c (map_supervised_sockets): Remove debug message.
+Provide correct fd in the second error case.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+---
+ agent/gpg-agent.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 054e845..c236180 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -742,13 +742,11 @@ map_supervised_sockets (gnupg_fd_t *r_fd,
+         {
+           for (j = 0; j < DIM (tbl); j++)
+             {
+-              log_debug ("i=%d j=%d fdname=%s check=%s\n", i, j,
+-                         fdnames[i], tbl[j].label);
+               if (!strcmp (fdnames[i], tbl[j].label) || j == DIM(tbl)-1)
+                 {
++                  fd = 3 + i;
+                   if (**tbl[j].fdaddr == -1)
+                     {
+-                      fd = 3 + i;
+                       name = get_socket_name (fd);
+                       if (name)
+                         {
diff --git a/debian/patches/0058-g10-Don-t-add-user-attributes-to-the-TOFU-DB.patch b/debian/patches/0058-g10-Don-t-add-user-attributes-to-the-TOFU-DB.patch
new file mode 100644
index 0000000..56bf69f
--- /dev/null
+++ b/debian/patches/0058-g10-Don-t-add-user-attributes-to-the-TOFU-DB.patch
@@ -0,0 +1,31 @@
+From: "Neal H. Walfield" <neal at g10code.com>
+Date: Mon, 5 Sep 2016 16:44:09 +0200
+Subject: g10: Don't add user attributes to the TOFU DB.
+
+* g10/trustdb.c (tdb_get_validity_core): Skip user attributes.
+
+--
+Signed-off-by: Neal H. Walfield <neal at g10code.com>
+---
+ g10/trustdb.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/g10/trustdb.c b/g10/trustdb.c
+index dd74d18..7097be2 100644
+--- a/g10/trustdb.c
++++ b/g10/trustdb.c
+@@ -1043,6 +1043,14 @@ tdb_get_validity_core (ctrl_t ctrl,
+ 	  else
+ 	    user_id = n->pkt->pkt.user_id;
+ 
++          if (user_id->attrib_data)
++            {
++              /* Skip user attributes.  */
++              if (uid)
++                break;
++              continue;
++            }
++
+           /* If the user id is revoked or expired, then skip it.  */
+ 	  if (user_id->is_revoked || user_id->is_expired)
+ 	    {
diff --git a/debian/patches/0059-g10-Fix-testing-for-debug-flag.patch b/debian/patches/0059-g10-Fix-testing-for-debug-flag.patch
new file mode 100644
index 0000000..0755fba
--- /dev/null
+++ b/debian/patches/0059-g10-Fix-testing-for-debug-flag.patch
@@ -0,0 +1,25 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 6 Oct 2016 14:17:55 +0200
+Subject: g10: Fix testing for debug flag.
+
+* g10/parse-packet.c (set_packet_list_mode): Fix testing for debug
+flag.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ g10/parse-packet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/parse-packet.c b/g10/parse-packet.c
+index 9a733b5..86c2be4 100644
+--- a/g10/parse-packet.c
++++ b/g10/parse-packet.c
+@@ -220,7 +220,7 @@ set_packet_list_mode (int mode)
+       else
+         listfp = es_stderr;
+ 
+-      if (opt.debug && DBG_MPI_VALUE)
++      if (opt.debug & DBG_MPI_VALUE)
+         mpi_print_mode = 1;
+     }
+   return old;
diff --git a/debian/patches/0060-sm-Remove-statement-without-effect.patch b/debian/patches/0060-sm-Remove-statement-without-effect.patch
new file mode 100644
index 0000000..aba162b
--- /dev/null
+++ b/debian/patches/0060-sm-Remove-statement-without-effect.patch
@@ -0,0 +1,24 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 6 Oct 2016 14:30:56 +0200
+Subject: sm: Remove statement without effect.
+
+* sm/call-dirmngr.c (gpgsm_dirmngr_isvalid): Remove statement without
+effect.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+---
+ sm/call-dirmngr.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
+index 7e26c3a..6987121 100644
+--- a/sm/call-dirmngr.c
++++ b/sm/call-dirmngr.c
+@@ -559,7 +559,6 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
+                         isvalid_status_cb, &stparm);
+   if (opt.verbose > 1)
+     log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
+-  rc = rc;
+ 
+   if (!rc && stparm.seen)
+     {
diff --git a/debian/patches/0061-common-Avoid-pointer-arithmetic-on-string-literals.patch b/debian/patches/0061-common-Avoid-pointer-arithmetic-on-string-literals.patch
new file mode 100644
index 0000000..cce801b
--- /dev/null
+++ b/debian/patches/0061-common-Avoid-pointer-arithmetic-on-string-literals.patch
@@ -0,0 +1,42 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 6 Oct 2016 14:48:52 +0200
+Subject: common: Avoid pointer arithmetic on string literals.
+
+* common/gettime.c (rfctimestamp): Use indexing instead.
+* common/signal.c (got_fatal_signal): Likewise.
+---
+ common/gettime.c | 6 +++---
+ common/signal.c  | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/common/gettime.c b/common/gettime.c
+index dd9c196..2103d5f 100644
+--- a/common/gettime.c
++++ b/common/gettime.c
+@@ -746,10 +746,10 @@ rfctimestamp (u32 stamp)
+   if (!tp)
+     return NULL;
+   return xtryasprintf ("%.3s, %02d %.3s %04d %02d:%02d:%02d +0000",
+-                       ("SunMonTueWedThuFriSat" + (tp->tm_wday%7)*3),
++                       &"SunMonTueWedThuFriSat"[(tp->tm_wday%7)*3],
+                        tp->tm_mday,
+-                       ("JanFebMarAprMayJunJulAugSepOctNovDec"
+-                        + (tp->tm_mon%12)*3),
++                       &"JanFebMarAprMayJunJulAugSepOctNovDec"
++                       [(tp->tm_mon%12)*3],
+                        tp->tm_year + 1900,
+                        tp->tm_hour,
+                        tp->tm_min,
+diff --git a/common/signal.c b/common/signal.c
+index b202f0f..9064adc 100644
+--- a/common/signal.c
++++ b/common/signal.c
+@@ -134,7 +134,7 @@ got_fatal_signal (int sig)
+             {
+               if (value >= i || ((any || i==1) && !(value/i)))
+                 {
+-                  (void)write (2, "0123456789"+(value/i), 1);
++                  (void)write (2, &"0123456789"[value/i], 1);
+                   if ((value/i))
+                     any = 1;
+                   value %= i;
diff --git a/debian/patches/0062-agent-dirmngr-scd-Fix-init_common_subsystems.patch b/debian/patches/0062-agent-dirmngr-scd-Fix-init_common_subsystems.patch
new file mode 100644
index 0000000..8074607
--- /dev/null
+++ b/debian/patches/0062-agent-dirmngr-scd-Fix-init_common_subsystems.patch
@@ -0,0 +1,98 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Fri, 7 Oct 2016 10:45:22 +0900
+Subject: agent, dirmngr, scd: Fix init_common_subsystems.
+
+* common/init.c (_init_common_subsystems): Don't call
+gpgrt_set_syscall_clamp in this function.
+* agent/gpg-agent.c, dirmngr/dirmngr.c, scd/scdaemon.c: Call
+gpgrt_set_syscall_clamp after npth_init.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ agent/gpg-agent.c |  1 +
+ common/init.c     | 11 -----------
+ dirmngr/dirmngr.c |  1 +
+ scd/scdaemon.c    |  2 ++
+ 4 files changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index c236180..6b97a3c 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -944,6 +944,7 @@ thread_init_once (void)
+       npth_initialized++;
+       npth_init ();
+     }
++  gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+ }
+ 
+ 
+diff --git a/common/init.c b/common/init.c
+index 591c854..f71c1be 100644
+--- a/common/init.c
++++ b/common/init.c
+@@ -29,20 +29,12 @@
+ 
+ #include <config.h>
+ 
+-#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+-#undef HAVE_NPTH
+-#undef USE_NPTH
+-#endif
+-
+ #ifdef HAVE_W32_SYSTEM
+ # ifdef HAVE_WINSOCK2_H
+ #  include <winsock2.h>
+ # endif
+ # include <windows.h>
+ #endif
+-#ifdef HAVE_NPTH
+-# include <npth.h>
+-#endif
+ #ifdef HAVE_W32CE_SYSTEM
+ # include <assuan.h> /* For _assuan_w32ce_finish_pipe. */
+ #endif
+@@ -197,9 +189,6 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
+   /* Initialize the Estream library. */
+   gpgrt_init ();
+   gpgrt_set_alloc_func (gcry_realloc);
+-#ifdef USE_NPTH
+-  gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+-#endif
+ 
+   /* Special hack for Windows CE: We extract some options from arg
+      to setup the standard handles.  */
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 67f8490..2bbc0ed 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -651,6 +651,7 @@ static void
+ thread_init (void)
+ {
+   npth_init ();
++  gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+ 
+   /* Now with NPth running we can set the logging callback.  Our
+      windows implementation does not yet feature the NPth TLS
+diff --git a/scd/scdaemon.c b/scd/scdaemon.c
+index f0e704b..33a822e 100644
+--- a/scd/scdaemon.c
++++ b/scd/scdaemon.c
+@@ -723,6 +723,7 @@ main (int argc, char **argv )
+ #endif
+ 
+       npth_init ();
++      gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+ 
+       /* If --debug-allow-core-dump has been given we also need to
+          switch the working directory to a place where we can actually
+@@ -862,6 +863,7 @@ main (int argc, char **argv )
+       /* This is the child. */
+ 
+       npth_init ();
++      gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
+ 
+       /* Detach from tty and put process into a new session. */
+       if (!nodetach )
diff --git a/debian/patches/0063-agent-Fix-get_socket_name.patch b/debian/patches/0063-agent-Fix-get_socket_name.patch
new file mode 100644
index 0000000..bba2512
--- /dev/null
+++ b/debian/patches/0063-agent-Fix-get_socket_name.patch
@@ -0,0 +1,45 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Fri, 7 Oct 2016 19:00:10 +0900
+Subject: agent: Fix get_socket_name.
+
+* agent/gpg-agent.c (get_socket_name): Fix the size of copying.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+---
+ agent/gpg-agent.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 6b97a3c..44a6bbb 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -602,19 +602,21 @@ get_socket_name (int fd)
+     log_error ("socket name not present for file descriptor %d\n", fd);
+   else if (len > sizeof(un))
+     log_error ("socket name for file descriptor %d was truncated "
+-               "(passed %lu bytes, wanted %u)\n", fd, sizeof(un), len);
++               "(passed %zu bytes, wanted %u)\n", fd, sizeof(un), len);
+   else
+     {
+-      log_debug ("file descriptor %d has path %s (%lu octets)\n", fd,
+-                 un.sun_path, len - offsetof (struct sockaddr_un, sun_path));
+-      name = xtrymalloc (len - offsetof (struct sockaddr_un, sun_path) + 1);
++      size_t namelen = len - offsetof (struct sockaddr_un, sun_path);
++
++      log_debug ("file descriptor %d has path %s (%zu octets)\n", fd,
++                 un.sun_path, namelen);
++      name = xtrymalloc (namelen + 1);
+       if (!name)
+         log_error ("failed to allocate memory for name of fd %d: %s\n",
+                    fd, gpg_strerror (gpg_error_from_syserror ()));
+       else
+         {
+-          memcpy (name, un.sun_path, len);
+-          name[len] = 0;
++          memcpy (name, un.sun_path, namelen);
++          name[namelen] = 0;
+         }
+     }
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 49fff0e..0de45be 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -19,3 +19,45 @@
 0019-gpg-Remove-option-yes-from-gpgv.patch
 0020-gpg-print-fingerprint-regardless-of-keyid-format.patch
 0021-spelling-conenction-should-be-connection.patch
+0022-gpg-Improve-usability-of-quick-gen-key.patch
+0023-gpg-Allow-use-of-default-algo-for-quick-addkey.patch
+0024-gpg-Emit-a-new-error-status-line-in-quick-adduid.patch
+0025-tests-gpgscm-Fix-use-of-pointer.patch
+0026-scd-Add-support-of-ECC-pubkey-attribute.patch
+0027-gpg-Avoid-malloc-failure-due-to-no-key-signatures.patch
+0028-gpgscm-Fix-gcrypt-version-check.patch
+0029-dirmngr-Silence-diagnostics-about-starting-housekeep.patch
+0030-gpg-Fix-regression-in-fingerprint-printing.patch
+0031-dirmngr-Open-file-CRL-s-in-binary-mode.patch
+0032-dirmngr-Fix-type.patch
+0033-g10-When-adding-a-user-id-make-sure-the-keyblock-has.patch
+0034-agent-Allow-only-specific-digest-size-for-ECDSA.patch
+0035-dirmngr-Removal-of-no-libgcrypt.o.patch
+0036-agent-sm-Set-CTX-after-start_agent.patch
+0037-common-Correctly-handle-modules-relying-on-npth.patch
+0038-build-Do-not-link-gpg-connect-agent-against-npth.patch
+0039-gpg-Make-sure-that-internal-key-import-is-done-with-.patch
+0040-gpg-Make-import-filter-data-object-more-flexible.patch
+0041-gpg-Reject-import-if-an-import-filter-removed-all-us.patch
+0042-dirmngr-Fix-STARTTLS-on-LDAP-connections.patch
+0043-tools-Give-mime-parser-callbacks-access-to-the-rfc82.patch
+0044-agent-Enable-restricted-browser-and-ssh-socket-by-de.patch
+0045-build-Fix-build-against-libiconv.patch
+0046-agent-Kludge-to-allow-disabling-of-the-extra-sockets.patch
+0047-agent-Create-the-extra-sockets-in-the-standard-socke.patch
+0048-agent-Remove-the-warning-for-the-GKR-hijacking.patch
+0049-agent-dirmngr-scd-npth_init-must-be-after-fork.patch
+0050-tools-Ignore-existing-directories-in-gpgtar.patch
+0051-agent-Implement-supervised-command-for-systemd-etc.patch
+0052-agent-Adjust-supervised-mode-for-the-new-default-soc.patch
+0053-agent-Adjust-cleanup-for-supervised-mode.-Fix-for-W3.patch
+0054-agent-Streamline-the-supervised-mode-code.patch
+0055-agent-Fix-error-handling-in-map_supervised_sockets.patch
+0056-agent-Fix-npth-supervised-mode-problem.patch
+0057-agent-Another-minor-fix-to-map_supervised_sockets.patch
+0058-g10-Don-t-add-user-attributes-to-the-TOFU-DB.patch
+0059-g10-Fix-testing-for-debug-flag.patch
+0060-sm-Remove-statement-without-effect.patch
+0061-common-Avoid-pointer-arithmetic-on-string-literals.patch
+0062-agent-dirmngr-scd-Fix-init_common_subsystems.patch
+0063-agent-Fix-get_socket_name.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list