[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