[Pkg-gnupg-commit] [gnupg2] 02/05: more upstream fixes (Closes: #854829)
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed Apr 26 07:11:12 UTC 2017
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit 1c52c8223324c8b8aad61c2dd1756392bd4d6629
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date: Wed Apr 26 01:17:35 2017 -0400
more upstream fixes (Closes: #854829)
---
...mon-Make-sure-that-all-fd-given-are-valid.patch | 12 +-
debian/patches/0040-gpgv-w32-Fix-status-fd.patch | 27 +++
...Make-trust-model-configurable-via-gpgconf.patch | 42 ++++
...ake-auto-key-retrieve-configurable-via-gp.patch | 40 ++++
...w-creating-keys-using-an-existing-ECC-key.patch | 204 +++++++++++++++++
...port-options-work-with-export-secret-keys.patch | 156 +++++++++++++
...s-Always-escape-newlines-when-escaping-da.patch | 63 ++++++
...an-error-when-trying-to-revoke-non-exista.patch | 53 +++++
...sible-segv-when-attribute-packets-are-fil.patch | 58 +++++
...x-attempt-to-double-free-an-UID-structure.patch | 59 +++++
...-doc-Add-a-note-to-the-trust-model-direct.patch | 75 +++++++
...tdout-before-printing-stats-with-check-si.patch | 37 ++++
...ore-warning-alerts-in-the-GNUTLS-handshak.patch | 44 ++++
...re-the-conflict-set-includes-the-current-.patch | 72 ++++++
...3-dirmngr-Load-the-hosts-file-into-libdns.patch | 60 +++++
.../patches/0054-dirmngr-Fix-error-handling.patch | 26 +++
...-Implicitly-do-a-gpgconf-create-socketdir.patch | 65 ++++++
.../0056-common-Fix-connecting-to-the-agent.patch | 34 +++
debian/patches/0057-g10-Fix-memory-leak.patch | 33 +++
.../0058-common-Avoid-undefined-behavior.patch | 26 +++
...dle-critical-marked-Reason-for-Revocation.patch | 31 +++
...rmngr-Do-not-assume-that-etc-hosts-exists.patch | 61 ++++++
...ays-print-a-warning-for-a-missing-etc-hos.patch | 49 +++++
...dle-EIO-which-is-sometimes-returned-by-co.patch | 26 +++
.../0063-dirmngr-New-option-disable-ipv6.patch | 241 +++++++++++++++++++++
...gent-Serialize-access-to-passphrase-cache.patch | 220 +++++++++++++++++++
...-gpg-Fix-printing-of-offline-taken-subkey.patch | 27 +++
.../0066-doc-Explain-the-in-a-key-listing.patch | 34 +++
.../0067-dirmngr-Fix-possible-null-reference.patch | 28 +++
...tools-Fix-condition-for-gpg-connect-agent.patch | 30 +++
.../0069-dirmngr-Fix-alignment-of-ADDR.patch | 155 +++++++++++++
...0-dirmngr-Fix-http.c-for-sockaddr_storage.patch | 70 ++++++
...0-Fix-import-export-filter-property-match.patch | 25 +++
debian/patches/0072-g10-Minor-fixes.patch | 66 ++++++
...0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch | 52 +++++
...4-g10-invalidate-the-fd-cache-for-keyring.patch | 41 ++++
...075-dirmngr-Fix-aliasing-problem-in-dns.c.patch | 89 ++++++++
debian/patches/series | 36 +++
38 files changed, 2462 insertions(+), 5 deletions(-)
diff --git a/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch b/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
index 400d51b..bf9691b 100644
--- a/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
+++ b/debian/patches/0032-gpg-common-Make-sure-that-all-fd-given-are-valid.patch
@@ -52,9 +52,9 @@ Signed-off-by: Justus Winter <justus at g10code.com>
g10/gpg.c | 5 +++++
g10/keylist.c | 3 +++
g10/passphrase.c | 3 +++
- tests/openpgp/Makefile.am | 2 +-
+ tests/openpgp/Makefile.am | 4 ++--
tests/openpgp/issue2941.scm | 34 ++++++++++++++++++++++++++++++++++
- 9 files changed, 64 insertions(+), 1 deletion(-)
+ 9 files changed, 65 insertions(+), 2 deletions(-)
create mode 100755 tests/openpgp/issue2941.scm
diff --git a/common/logging.c b/common/logging.c
@@ -168,13 +168,15 @@ index fb4ec4c..37abc0f 100644
{ /* Not used but we have to do a dummy read, so that it won't end
up at the begin of the message if the quite usual trick to
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
-index 05341fb..d9a2e34 100644
+index 05341fb..377a2ed 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
-@@ -96,11 +96,11 @@ XTESTS = \
+@@ -95,12 +95,12 @@ XTESTS = \
+ issue2015.scm \
issue2346.scm \
issue2417.scm \
- issue2419.scm
+- issue2419.scm
++ issue2419.scm \
+ issue2941.scm
# Fixme: gpgconf.scm does not yet work with make distcheck.
diff --git a/debian/patches/0040-gpgv-w32-Fix-status-fd.patch b/debian/patches/0040-gpgv-w32-Fix-status-fd.patch
new file mode 100644
index 0000000..555af36
--- /dev/null
+++ b/debian/patches/0040-gpgv-w32-Fix-status-fd.patch
@@ -0,0 +1,27 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 28 Feb 2017 09:35:41 +0100
+Subject: gpgv,w32: Fix --status-fd.
+
+* g10/gpgv.c (main): Use translate_sys2libc_fd_int for --status-fd.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 8a67dc4c4324b617b5a3fea51c59c674488544d6)
+---
+ g10/gpgv.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/g10/gpgv.c b/g10/gpgv.c
+index bd16b39..ca8fca4 100644
+--- a/g10/gpgv.c
++++ b/g10/gpgv.c
+@@ -194,7 +194,9 @@ main( int argc, char **argv )
+ break;
+ case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
+ case oOutput: opt.outfile = pargs.r.ret_str; break;
+- case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
++ case oStatusFD:
++ set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
++ break;
+ case oLoggerFD:
+ log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
+ break;
diff --git a/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch b/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
new file mode 100644
index 0000000..ae0cff9
--- /dev/null
+++ b/debian/patches/0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
@@ -0,0 +1,42 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 28 Feb 2017 13:15:42 +0100
+Subject: gpg,tools: Make trust-model configurable via gpgconf.
+
+* g10/gpg.c (gpgconf_list): Add 'trust-model'.
+* tools/gpgconf-comp.c (gc_options_gpg): Likewise.
+
+GnuPG-bug-id: 2381
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit ebeccd73eb85f9027f0985d77dfe901266c6ddef)
+---
+ g10/gpg.c | 1 +
+ tools/gpgconf-comp.c | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 0c5a167..09bdf66 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -1845,6 +1845,7 @@ gpgconf_list (const char *configfile)
+ es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+ es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
++ es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE);
+
+ /* The next one is an info only item and should match the macros at
+ the top of keygen.c */
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index a0d9659..cdd2586 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -716,6 +716,10 @@ static gc_option_t gc_options_gpg[] =
+ (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
+ NULL, NULL,
+ GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
++ { "trust-model",
++ GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
++ NULL, NULL,
++ GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+
+
+ { "Debug",
diff --git a/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch b/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
new file mode 100644
index 0000000..60d29b7
--- /dev/null
+++ b/debian/patches/0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
@@ -0,0 +1,40 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 28 Feb 2017 14:59:11 +0100
+Subject: gpg,tools: Make auto-key-retrieve configurable via gpgconf.
+
+* g10/gpg.c (gpgconf_list): Add 'auto-key-retrieve'.
+* tools/gpgconf-comp.c (gc_options_gpg): Likewise.
+
+GnuPG-bug-id: 2381
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit d379a0174cca595204b32da9a66c513a1304e6d0)
+---
+ g10/gpg.c | 1 +
+ tools/gpgconf-comp.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 09bdf66..2a4a0ad 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -1840,6 +1840,7 @@ gpgconf_list (const char *configfile)
+ es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
++ es_printf ("auto-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+ es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+ es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index cdd2586..530c128 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -747,6 +747,8 @@ static gc_option_t gc_options_gpg[] =
+ { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
+ "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
+ GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
++ { "auto-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
++ NULL, NULL, GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
+
+
+ GC_OPTION_NULL
diff --git a/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch b/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
new file mode 100644
index 0000000..9d6fe6e
--- /dev/null
+++ b/debian/patches/0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
@@ -0,0 +1,204 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 1 Mar 2017 13:36:01 +0100
+Subject: gpg: Allow creating keys using an existing ECC key.
+
+* common/sexputil.c (get_pk_algo_from_canon_sexp): Remove arg R_ALGO.
+Change to return the algo id. Reimplement using get_pk_algo_from_key.
+* g10/keygen.c (check_keygrip): Adjust for change.
+* sm/certreqgen-ui.c (check_keygrip): Ditto.
+--
+
+GnuPG-bug-id: 2976
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 2bbdeb8ee87a6c7ec211be16391a11b7c6030bed)
+---
+ common/sexputil.c | 65 +++++++++++++++---------------------------------------
+ common/util.h | 6 ++---
+ g10/keygen.c | 22 +++---------------
+ sm/certreqgen-ui.c | 24 +++++++++-----------
+ 4 files changed, 34 insertions(+), 83 deletions(-)
+
+diff --git a/common/sexputil.c b/common/sexputil.c
+index 0c5c730..a8dc1a5 100644
+--- a/common/sexputil.c
++++ b/common/sexputil.c
+@@ -512,53 +512,6 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
+ }
+
+
+-/* Return the algo of a public RSA expressed as an canonical encoded
+- S-expression. The return value is a statically allocated
+- string. On error that string is set to NULL. */
+-gpg_error_t
+-get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
+- const char **r_algo)
+-{
+- gpg_error_t err;
+- const unsigned char *buf, *tok;
+- size_t buflen, toklen;
+- int depth;
+-
+- *r_algo = NULL;
+-
+- buf = keydata;
+- buflen = keydatalen;
+- depth = 0;
+- if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+- return err;
+- if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+- return err;
+- if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
+- return gpg_error (GPG_ERR_BAD_PUBKEY);
+- if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+- return err;
+- if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
+- return err;
+- if (!tok)
+- return gpg_error (GPG_ERR_BAD_PUBKEY);
+-
+- if (toklen == 3 && !memcmp ("rsa", tok, toklen))
+- *r_algo = "rsa";
+- else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
+- *r_algo = "dsa";
+- else if (toklen == 3 && !memcmp ("elg", tok, toklen))
+- *r_algo = "elg";
+- else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
+- *r_algo = "ecdsa";
+- else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
+- *r_algo = "eddsa";
+- else
+- return gpg_error (GPG_ERR_PUBKEY_ALGO);
+-
+- return 0;
+-}
+-
+-
+ /* Return the algo of a public KEY of SEXP. */
+ int
+ get_pk_algo_from_key (gcry_sexp_t key)
+@@ -606,3 +559,21 @@ get_pk_algo_from_key (gcry_sexp_t key)
+
+ return algo;
+ }
++
++
++/* This is a variant of get_pk_algo_from_key but takes an canonical
++ * encoded S-expression as input. Returns a GCRYPT public key
++ * identiier or 0 on error. */
++int
++get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen)
++{
++ gcry_sexp_t sexp;
++ int algo;
++
++ if (gcry_sexp_sscan (&sexp, NULL, keydata, keydatalen))
++ return 0;
++
++ algo = get_pk_algo_from_key (sexp);
++ gcry_sexp_release (sexp);
++ return algo;
++}
+diff --git a/common/util.h b/common/util.h
+index f7a53e1..b6d7156 100644
+--- a/common/util.h
++++ b/common/util.h
+@@ -195,10 +195,10 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
+ size_t *r_nlen,
+ unsigned char const **r_e,
+ size_t *r_elen);
+-gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
+- size_t keydatalen,
+- const char **r_algo);
++
+ int get_pk_algo_from_key (gcry_sexp_t key);
++int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
++ size_t keydatalen);
+
+ /*-- convert.c --*/
+ int hex2bin (const char *string, void *buffer, size_t length);
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 98ef29e..0180581 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -1838,7 +1838,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+ gpg_error_t err;
+ unsigned char *public;
+ size_t publiclen;
+- const char *algostr;
++ int algo;
+
+ if (hexgrip[0] == '&')
+ hexgrip++;
+@@ -1848,26 +1848,10 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+ return 0;
+ publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
+
+- get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
++ algo = get_pk_algo_from_canon_sexp (public, publiclen);
+ xfree (public);
+
+- /* FIXME: Mapping of ECC algorithms is probably not correct. */
+- if (!algostr)
+- return 0;
+- else if (!strcmp (algostr, "rsa"))
+- return PUBKEY_ALGO_RSA;
+- else if (!strcmp (algostr, "dsa"))
+- return PUBKEY_ALGO_DSA;
+- else if (!strcmp (algostr, "elg"))
+- return PUBKEY_ALGO_ELGAMAL_E;
+- else if (!strcmp (algostr, "ecc"))
+- return PUBKEY_ALGO_ECDH;
+- else if (!strcmp (algostr, "ecdsa"))
+- return PUBKEY_ALGO_ECDSA;
+- else if (!strcmp (algostr, "eddsa"))
+- return PUBKEY_ALGO_EDDSA;
+- else
+- return 0;
++ return map_pk_gcry_to_openpgp (algo);
+ }
+
+
+diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c
+index ece8668..b50d338 100644
+--- a/sm/certreqgen-ui.c
++++ b/sm/certreqgen-ui.c
+@@ -95,7 +95,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+ gpg_error_t err;
+ ksba_sexp_t public;
+ size_t publiclen;
+- const char *algostr;
++ int algo;
+
+ if (hexgrip[0] == '&')
+ hexgrip++;
+@@ -105,21 +105,17 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
+ return NULL;
+ publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
+
+- get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
++ algo = get_pk_algo_from_canon_sexp (public, publiclen);
+ xfree (public);
+
+- if (!algostr)
+- return NULL;
+- else if (!strcmp (algostr, "rsa"))
+- return "RSA";
+- else if (!strcmp (algostr, "dsa"))
+- return "DSA";
+- else if (!strcmp (algostr, "elg"))
+- return "ELG";
+- else if (!strcmp (algostr, "ecdsa"))
+- return "ECDSA";
+- else
+- return NULL;
++ switch (algo)
++ {
++ case GCRY_PK_RSA: return "RSA";
++ case GCRY_PK_DSA: return "DSA";
++ case GCRY_PK_ELG: return "ELG";
++ case GCRY_PK_EDDSA: return "ECDSA";
++ default: return NULL;
++ }
+ }
+
+
diff --git a/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch b/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch
new file mode 100644
index 0000000..7dc7666
--- /dev/null
+++ b/debian/patches/0044-gpg-Make-export-options-work-with-export-secret-keys.patch
@@ -0,0 +1,156 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 1 Mar 2017 14:41:47 +0100
+Subject: gpg: Make --export-options work with --export-secret-keys.
+
+* g10/export.c (export_seckeys): Add arg OPTIONS and pass it to
+do_export.
+(export_secsubkeys): Ditto.
+* g10/gpg.c (main): Pass opt.export_options to export_seckeys and
+export_secsubkeys
+--
+
+Back in the old days we did not used the export options for secret
+keys export because of a lot of duplicated code and that the old
+secring.gpg was anyway smaller that the pubring.gpg. With 2.1 it was
+pretty easy to enable it.
+
+Reported-by: Peter Lebbing
+GnuPG-bug-id: 2973
+(cherry picked from commit 891ab23411b7f20ef37d8bde81d9857b083235df)
+---
+ doc/gpg.texi | 7 ++++---
+ g10/export.c | 31 ++++++++++++++++---------------
+ g10/gpg.c | 4 ++--
+ g10/main.h | 6 ++++--
+ 4 files changed, 26 insertions(+), 22 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index b79b783..3b82b44 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -1824,7 +1824,8 @@ are available for all keyserver types, some common options are:
+ used with HKP keyservers.
+
+ @item auto-key-retrieve
+- This is the same as the option @option{auto-key-retrieve}.
++ This is an obsolete alias for the option @option{auto-key-retrieve}.
++ Please do not use it; it will be removed in future versions..
+
+ @item honor-keyserver-url
+ When using @option{--refresh-keys}, if the key in question has a preferred
+@@ -2371,8 +2372,8 @@ The available properties are:
+ @item --export-options @code{parameters}
+ @opindex export-options
+ This is a space or comma delimited string that gives options for
+-exporting keys. Options can be prepended with a `no-' to give the
+-opposite meaning. The options are:
++exporting keys. Options can be prepended with a `no-' to give the
++opposite meaning. The options are:
+
+ @table @asis
+
+diff --git a/g10/export.c b/g10/export.c
+index 8668126..207f994 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -247,16 +247,17 @@ export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
+ /*
+ * Export secret keys (to stdout or to --output FILE).
+ *
+- * Depending on opt.armor the output is armored. If USERS is NULL,
+- * all secret keys will be exported. STATS is either an export stats
+- * object for update or NULL.
++ * Depending on opt.armor the output is armored. OPTIONS are defined
++ * in main.h. If USERS is NULL, all secret keys will be exported.
++ * STATS is either an export stats object for update or NULL.
+ *
+ * This function is the core of "gpg --export-secret-keys".
+ */
+ int
+-export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
++export_seckeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++ export_stats_t stats)
+ {
+- return do_export (ctrl, users, 1, 0, stats);
++ return do_export (ctrl, users, 1, options, stats);
+ }
+
+
+@@ -264,16 +265,18 @@ export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
+ * Export secret sub keys (to stdout or to --output FILE).
+ *
+ * This is the same as export_seckeys but replaces the primary key by
+- * a stub key. Depending on opt.armor the output is armored. If
+- * USERS is NULL, all secret subkeys will be exported. STATS is
+- * either an export stats object for update or NULL.
++ * a stub key. Depending on opt.armor the output is armored. OPTIONS
++ * are defined in main.h. If USERS is NULL, all secret subkeys will
++ * be exported. STATS is either an export stats object for update or
++ * NULL.
+ *
+ * This function is the core of "gpg --export-secret-subkeys".
+ */
+ int
+-export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
++export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++ export_stats_t stats)
+ {
+- return do_export (ctrl, users, 2, 0, stats);
++ return do_export (ctrl, users, 2, options, stats);
+ }
+
+
+@@ -1969,11 +1972,9 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
+ }
+
+ /* Always do the cleaning on the public key part if requested.
+- Note that we don't yet set this option if we are exporting
+- secret keys. Note that both export-clean and export-minimal
+- only apply to UID sigs (0x10, 0x11, 0x12, and 0x13). A
+- designated revocation is never stripped, even with
+- export-minimal set. */
++ * Note that both export-clean and export-minimal only apply to
++ * UID sigs (0x10, 0x11, 0x12, and 0x13). A designated
++ * revocation is never stripped, even with export-minimal set. */
+ if ((options & EXPORT_CLEAN))
+ clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
+
+diff --git a/g10/gpg.c b/g10/gpg.c
+index 2a4a0ad..5a880fd 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -4546,7 +4546,7 @@ main (int argc, char **argv)
+ add_to_strlist2( &sl, *argv, utf8_strings );
+ {
+ export_stats_t stats = export_new_stats ();
+- export_seckeys (ctrl, sl, stats);
++ export_seckeys (ctrl, sl, opt.export_options, stats);
+ export_print_stats (stats);
+ export_release_stats (stats);
+ }
+@@ -4559,7 +4559,7 @@ main (int argc, char **argv)
+ add_to_strlist2( &sl, *argv, utf8_strings );
+ {
+ export_stats_t stats = export_new_stats ();
+- export_secsubkeys (ctrl, sl, stats);
++ export_secsubkeys (ctrl, sl, opt.export_options, stats);
+ export_print_stats (stats);
+ export_release_stats (stats);
+ }
+diff --git a/g10/main.h b/g10/main.h
+index 5ed501b..6837e98 100644
+--- a/g10/main.h
++++ b/g10/main.h
+@@ -397,8 +397,10 @@ gpg_error_t parse_and_set_export_filter (const char *string);
+
+ int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
+ export_stats_t stats);
+-int export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
+-int export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
++int export_seckeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++ export_stats_t stats);
++int export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
++ export_stats_t stats);
+
+ gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec,
+ unsigned int options,
diff --git a/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch b/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch
new file mode 100644
index 0000000..8b3e32b
--- /dev/null
+++ b/debian/patches/0045-common-tools-Always-escape-newlines-when-escaping-da.patch
@@ -0,0 +1,63 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 1 Mar 2017 17:47:47 +0100
+Subject: common,tools: Always escape newlines when escaping data.
+
+* common/stringhelp.c (do_percent_escape): Always escape newlines.
+* tools/gpgconf-comp.c (gc_percent_escape): Likewise.
+--
+Newlines always pose a problem for a line-based communication format.
+
+GnuPG-bug-id: 2387
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit e064c75b08a523f738108428fe0c417a46e66238)
+---
+ common/stringhelp.c | 10 +++++++++-
+ tools/gpgconf-comp.c | 7 +++++++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/common/stringhelp.c b/common/stringhelp.c
+index dea2212..0abfa3d 100644
+--- a/common/stringhelp.c
++++ b/common/stringhelp.c
+@@ -1052,7 +1052,8 @@ do_percent_escape (const char *str, const char *extra, int die)
+ return NULL;
+
+ for (i=j=0; str[i]; i++)
+- if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
++ if (str[i] == ':' || str[i] == '%' || str[i] == '\n'
++ || (extra && strchr (extra, str[i])))
+ j++;
+ if (die)
+ ptr = xmalloc (i + 2 * j + 1);
+@@ -1077,6 +1078,13 @@ do_percent_escape (const char *str, const char *extra, int die)
+ ptr[i++] = '2';
+ ptr[i++] = '5';
+ }
++ else if (*str == '\n')
++ {
++ /* The newline is problematic in a line-based format. */
++ ptr[i++] = '%';
++ ptr[i++] = '0';
++ ptr[i++] = 'a';
++ }
+ else if (extra && strchr (extra, *str))
+ {
+ ptr[i++] = '%';
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 530c128..9358e2e 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -1490,6 +1490,13 @@ gc_percent_escape (const char *src)
+ *(dst++) = '2';
+ *(dst++) = 'c';
+ }
++ else if (*src == '\n')
++ {
++ /* The newline is problematic in a line-based format. */
++ *(dst++) = '%';
++ *(dst++) = '0';
++ *(dst++) = 'a';
++ }
+ else
+ *(dst++) = *(src);
+ src++;
diff --git a/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch b/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
new file mode 100644
index 0000000..14480bf
--- /dev/null
+++ b/debian/patches/0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
@@ -0,0 +1,53 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 2 Mar 2017 11:39:00 +0100
+Subject: g10: Signal an error when trying to revoke non-existant UID.
+
+* g10/keyedit.c (keyedit_quick_revuid): Signal an error when trying to
+revoke non-existant UID.
+* tests/openpgp/quick-key-manipulation.scm: Test that.
+
+GnuPG-bug-id: 2962
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 62d21a4ab4029b32ea129f1cf3a0e1f22e2fb7b0)
+---
+ g10/keyedit.c | 2 ++
+ tests/openpgp/quick-key-manipulation.scm | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 1456d28..a477e92 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -3053,6 +3053,8 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
+ }
+ }
+
++ log_error (_("User ID revocation failed: %s\n"), gpg_strerror (GPG_ERR_NOT_FOUND));
++
+ leave:
+ release_kbnode (keyblock);
+ keydb_release (kdbhd);
+diff --git a/tests/openpgp/quick-key-manipulation.scm b/tests/openpgp/quick-key-manipulation.scm
+index d43f7b5..ae1d0b9 100755
+--- a/tests/openpgp/quick-key-manipulation.scm
++++ b/tests/openpgp/quick-key-manipulation.scm
+@@ -36,6 +36,7 @@
+
+ (define alpha "Alpha <alpha at invalid.example.net>")
+ (define bravo "Bravo <bravo at invalid.example.net>")
++(define charlie "Charlie <charlie at invalid.example.net>")
+
+ (define (key-data key)
+ (filter (lambda (x) (or (string=? (car x) "pub")
+@@ -78,6 +79,11 @@
+ (info "Checking that we can revoke a user ID...")
+ (call-check `(, at GPG --quick-revoke-uid ,(exact bravo) ,alpha))
+
++(info "Checking that we get an error revoking a non-existant user ID.")
++(catch '()
++ (call-check `(, at GPG --quick-revoke-uid ,(exact bravo) ,charlie))
++ (error "Expected an error, but get none."))
++
+ (assert (= 1 (count-uids-of-secret-key bravo)))
+
+ (info "Checking that we can change the expiration time.")
diff --git a/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch b/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
new file mode 100644
index 0000000..3b232db
--- /dev/null
+++ b/debian/patches/0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
@@ -0,0 +1,58 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 3 Mar 2017 09:50:40 +0100
+Subject: gpg: Fix possible segv when attribute packets are filtered.
+
+* g10/import.c (impex_filter_getval): Handle PKT_ATTRIBUTE the same as
+PKT_USER_ID
+(apply_drop_sig_filter): Ditto.
+--
+
+The old code was plainly wrong in that it considered PKT_ATTRIBUTE to
+use a PKT_signature object.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 5f6f3f5cae8a95ed469129f9677782c17951dab3)
+---
+ g10/import.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index b6c04dc..4e6f692 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1173,7 +1173,8 @@ impex_filter_getval (void *cookie, const char *propname)
+ static char numbuf[20];
+ const char *result;
+
+- if (node->pkt->pkttype == PKT_USER_ID)
++ if (node->pkt->pkttype == PKT_USER_ID
++ || node->pkt->pkttype == PKT_ATTRIBUTE)
+ {
+ if (!strcmp (propname, "uid"))
+ result = node->pkt->pkt.user_id->name;
+@@ -1191,8 +1192,7 @@ impex_filter_getval (void *cookie, const char *propname)
+ else
+ result = NULL;
+ }
+- else if (node->pkt->pkttype == PKT_SIGNATURE
+- || node->pkt->pkttype == PKT_ATTRIBUTE)
++ else if (node->pkt->pkttype == PKT_SIGNATURE)
+ {
+ PKT_signature *sig = node->pkt->pkt.signature;
+
+@@ -1313,12 +1313,12 @@ apply_drop_sig_filter (kbnode_t keyblock, recsel_expr_t selector)
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+ break; /* ready. */
+- if (node->pkt->pkttype == PKT_USER_ID)
++ if (node->pkt->pkttype == PKT_USER_ID
++ || node->pkt->pkttype == PKT_ATTRIBUTE)
+ active = 1;
+ if (!active)
+ continue;
+- if (node->pkt->pkttype != PKT_SIGNATURE
+- && node->pkt->pkttype != PKT_ATTRIBUTE)
++ if (node->pkt->pkttype != PKT_SIGNATURE)
+ continue;
+
+ sig = node->pkt->pkt.signature;
diff --git a/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch b/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
new file mode 100644
index 0000000..9de4ed1
--- /dev/null
+++ b/debian/patches/0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
@@ -0,0 +1,59 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Sun, 5 Mar 2017 23:24:15 +0100
+Subject: gpg: Fix attempt to double free an UID structure.
+
+* g10/getkey.c (get_best_pubkey_byname): Set released .UID to NULL.
+--
+
+Phil Pennock reported an assertion failure when doing
+
+ % gpg --auto-key-locate dane --locate-keys someone
+ gpg: Ohhhh jeeee: Assertion "uid->ref > 0" in \
+ free_user_id failed (free-packet.c:310)
+
+on his keyring. This patch is not tested but a good guess.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 4a130bbc2c2f4be6e8c6357512a943f435ade28f)
+---
+ g10/getkey.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/g10/getkey.c b/g10/getkey.c
+index e39de28..21dcf08 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -1592,8 +1592,10 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+ if (is_valid_mailbox (name) && ctx)
+ {
+ /* Rank results and return only the most relevant key. */
+- struct pubkey_cmp_cookie best = { 0 }, new;
+- KBNODE new_keyblock;
++ struct pubkey_cmp_cookie best = { 0 };
++ struct pubkey_cmp_cookie new;
++ kbnode_t new_keyblock;
++
+ while (getkey_next (ctx, &new.key, &new_keyblock) == 0)
+ {
+ int diff = pubkey_cmp (ctrl, name, &best, &new, new_keyblock);
+@@ -1610,17 +1612,20 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+ /* Old key is better. */
+ release_public_key_parts (&new.key);
+ free_user_id (new.uid);
++ new.uid = NULL;
+ }
+ else
+ {
+ /* A tie. Keep the old key. */
+ release_public_key_parts (&new.key);
+ free_user_id (new.uid);
++ new.uid = NULL;
+ }
+ }
+ getkey_end (ctx);
+ ctx = NULL;
+ free_user_id (best.uid);
++ best.uid = NULL;
+
+ if (best.valid)
+ {
diff --git a/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch b/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch
new file mode 100644
index 0000000..de1f75d
--- /dev/null
+++ b/debian/patches/0049-doc-Add-a-note-to-the-trust-model-direct.patch
@@ -0,0 +1,75 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Wed, 8 Mar 2017 10:46:09 +0100
+Subject: doc: Add a note to the trust model direct.
+
+* doc/gpg.texi (GPG Configuration Options): Add note. Chnage Index
+from trust-mode:foo to trust-model:foo.
+
+(cherry picked from commit f0257b4a86b73f5b956028e68590b6d2a23ea4da)
+---
+ doc/gpg.texi | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index 3b82b44..d658737 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -1600,17 +1600,17 @@ Set what trust model GnuPG should follow. The models are:
+ @table @asis
+
+ @item pgp
+- @opindex trust-mode:pgp
++ @opindex trust-model:pgp
+ This is the Web of Trust combined with trust signatures as used in PGP
+ 5.x and later. This is the default trust model when creating a new
+ trust database.
+
+ @item classic
+- @opindex trust-mode:classic
++ @opindex trust-model:classic
+ This is the standard Web of Trust as introduced by PGP 2.
+
+ @item tofu
+- @opindex trust-mode:tofu
++ @opindex trust-model:tofu
+ @anchor{trust-model-tofu}
+ TOFU stands for Trust On First Use. In this trust model, the first
+ time a key is seen, it is memorized. If later another key is seen
+@@ -1656,7 +1656,7 @@ Set what trust model GnuPG should follow. The models are:
+ @code{undefined} trust level is returned.
+
+ @item tofu+pgp
+- @opindex trust-mode:tofu+pgp
++ @opindex trust-model:tofu+pgp
+ This trust model combines TOFU with the Web of Trust. This is done
+ by computing the trust level for each model and then taking the
+ maximum trust level where the trust levels are ordered as follows:
+@@ -1669,12 +1669,16 @@ Set what trust model GnuPG should follow. The models are:
+ which some security-conscious users don't like.
+
+ @item direct
+- @opindex trust-mode:direct
++ @opindex trust-model:direct
+ Key validity is set directly by the user and not calculated via the
+- Web of Trust.
++ Web of Trust. This model is soley based on the key and does
++ not distinguish user IDs. Note that when changing to another trust
++ model the trust values assigned to a key are transformed into
++ ownertrust values, which also indicate how you trust the owner of
++ the key to sign other keys.
+
+ @item always
+- @opindex trust-mode:always
++ @opindex trust-model:always
+ Skip key validation and assume that used keys are always fully
+ valid. You generally won't use this unless you are using some
+ external validation scheme. This option also suppresses the
+@@ -1684,7 +1688,7 @@ Set what trust model GnuPG should follow. The models are:
+ disabled keys.
+
+ @item auto
+- @opindex trust-mode:auto
++ @opindex trust-model:auto
+ Select the trust model depending on whatever the internal trust
+ database says. This is the default model if such a database already
+ exists.
diff --git a/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch b/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
new file mode 100644
index 0000000..62cbee9
--- /dev/null
+++ b/debian/patches/0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
@@ -0,0 +1,37 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 13 Mar 2017 17:42:08 +0100
+Subject: gpg: Flush stdout before printing stats with --check-sigs.
+
+* g10/keylist.c (print_signature_stats): Flush stdout.
+(list_keyblock_colon): Use es_flush instead of fflush.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 9a77b3b6e41f97b1209ad61c04b3dd33242ecae8)
+---
+ g10/keylist.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index abdcb9f..4078053 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -465,6 +465,10 @@ print_signature_stats (struct keylist_context *s)
+ if (!s->check_sigs)
+ return; /* Signature checking was not requested. */
+
++ /* Better flush stdout so that the stats are always printed after
++ * the output. */
++ es_fflush (es_stdout);
++
+ if (s->good_sigs)
+ log_info (ngettext("%d good signature\n",
+ "%d good signatures\n", s->good_sigs), s->good_sigs);
+@@ -1447,7 +1451,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
+ {
+ PKT_public_key *signer_pk = NULL;
+
+- fflush (stdout);
++ es_fflush (es_stdout);
+ if (opt.no_sig_cache)
+ signer_pk = xmalloc_clear (sizeof (PKT_public_key));
+
diff --git a/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch b/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
new file mode 100644
index 0000000..c30365b
--- /dev/null
+++ b/debian/patches/0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
@@ -0,0 +1,44 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 17 Mar 2017 12:46:09 +0100
+Subject: dirmngr: Ignore warning alerts in the GNUTLS handshake.
+
+* dirmngr/http.c (send_request) [GNUTLS]: Don't bail out on warning
+alerts.
+--
+
+GnuPG-bug-id: 2833
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 69c521df422a6c9a6b0a93e45c9373a8b6ceb28e)
+---
+ dirmngr/http.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index fe9c3c7..c9c16df 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -1847,6 +1847,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
+ gnutls_transport_set_push_function (hd->session->tls_session,
+ my_gnutls_write);
+
++ handshake_again:
+ do
+ {
+ rc = gnutls_handshake (hd->session->tls_session);
+@@ -1862,10 +1863,15 @@ send_request (http_t hd, const char *httphost, const char *auth,
+
+ alertno = gnutls_alert_get (hd->session->tls_session);
+ alertstr = gnutls_alert_get_name (alertno);
+- log_info ("TLS handshake failed: %s (alert %d)\n",
++ log_info ("TLS handshake %s: %s (alert %d)\n",
++ rc == GNUTLS_E_WARNING_ALERT_RECEIVED
++ ? "warning" : "failed",
+ alertstr, (int)alertno);
+ if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
+ log_info (" (sent server name '%s')\n", server);
++
++ if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
++ goto handshake_again;
+ }
+ else
+ log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
diff --git a/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch b/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
new file mode 100644
index 0000000..0a11a8e
--- /dev/null
+++ b/debian/patches/0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
@@ -0,0 +1,72 @@
+From: "Neal H. Walfield" <neal at g10code.com>
+Date: Fri, 17 Mar 2017 13:36:51 +0100
+Subject: gpg: Make sure the conflict set includes the current key.
+
+* g10/tofu.c (get_trust): Sanity check CONFLICT_SET after calling
+get_policy. If POLICY is 'auto' and the default policy is 'ask', make
+sure CONFLICT_SET includes the current key.
+
+--
+Signed-off-by: Neal H. Walfield <neal at g10code.com>
+GnuPG-bug-id: 2959
+Debian-bug-id: 854829
+
+Signed-off-by: Neal H. Walfield <neal at g10code.com>
+(cherry picked from commit b1106b4d640325c60a7212a4a44e4f67c0e3312d)
+---
+ g10/tofu.c | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 449e921..39457a5 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -2304,9 +2304,14 @@ build_conflict_set (tofu_dbs_t dbs,
+
+
+ /* Return the effective policy for the binding <FINGERPRINT, EMAIL>
+- * (email has already been normalized) and any conflict information in
+- * *CONFLICT_SETP, if CONFLICT_SETP is not NULL. Returns
+- * _tofu_GET_POLICY_ERROR if an error occurs.
++ * (email has already been normalized). Returns
++ * _tofu_GET_POLICY_ERROR if an error occurs. Returns any conflict
++ * information in *CONFLICT_SETP if CONFLICT_SETP is not NULL and the
++ * returned policy is TOFU_POLICY_ASK (consequently, if there is a
++ * conflict, but the user set the policy to good *CONFLICT_SETP will
++ * empty). Note: as per build_conflict_set, which is used to build
++ * the conflict information, the conflict information includes the
++ * current user id as the first element of the linked list.
+ *
+ * This function registers the binding in the bindings table if it has
+ * not yet been registered.
+@@ -2689,6 +2694,15 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+ policy = get_policy (dbs, pk, fingerprint, user_id, email,
+ &conflict_set, now);
+
++ if (policy == TOFU_POLICY_ASK)
++ /* The conflict set should always contain at least one element:
++ * the current key. */
++ log_assert (conflict_set);
++ else
++ /* If the policy is not TOFU_POLICY_ASK, then conflict_set will be
++ * NULL. */
++ log_assert (! conflict_set);
++
+ /* If the key is ultimately trusted, there is nothing to do. */
+ {
+ u32 kid[2];
+@@ -2710,6 +2724,14 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk,
+ " auto (default: %s).\n",
+ fingerprint, email,
+ tofu_policy_str (opt.tofu_default_policy));
++
++ if (policy == TOFU_POLICY_ASK)
++ /* The default policy is ASK, but there is no conflict (policy
++ * was 'auto'). In this case, we need to make sure the
++ * conflict set includes at least the current user id. */
++ {
++ add_to_strlist (&conflict_set, fingerprint);
++ }
+ }
+ switch (policy)
+ {
diff --git a/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch b/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch
new file mode 100644
index 0000000..aae341c
--- /dev/null
+++ b/debian/patches/0053-dirmngr-Load-the-hosts-file-into-libdns.patch
@@ -0,0 +1,60 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 21 Mar 2017 14:18:25 +0100
+Subject: dirmngr: Load the hosts file into libdns.
+
+* dirmngr/dns-stuff.c (libdns_init): Actually load the hosts file into
+libdns.
+--
+
+Previously, connecting to key servers specified in /etc/hosts was not
+possible because libdns' hosts structure was initialized, but not
+filled with the content of the hosts file.
+
+GnuPG-bug-id: 2977
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 88f1505f0613894d5544290a170119eb538921e5)
+---
+ dirmngr/dns-stuff.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index bc2e071..35e6c82 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -533,11 +533,35 @@ libdns_init (void)
+ ld.hosts = dns_hosts_open (&derr);
+ if (!ld.hosts)
+ {
+- log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+ err = libdns_error_to_gpg_error (derr);
++ log_error ("failed to initialize hosts file: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
++
++ {
++#if HAVE_W32_SYSTEM
++ char *hosts_path = xtryasprintf ("%s\System32\drivers\etc\hosts",
++ getenv ("SystemRoot"));
++ if (! hosts_path)
++ {
++ err = gpg_error_from_syserror ();
++ goto leave;
++ }
++
++ derr = dns_hosts_loadpath (ld.hosts, hosts_path);
++ xfree (hosts_path);
++#else
++ derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
++#endif
++ if (derr)
++ {
++ err = libdns_error_to_gpg_error (derr);
++ log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
++ goto leave;
++ }
++ }
++
+ /* dns_hints_local for stub mode, dns_hints_root for recursive. */
+ ld.hints = (recursive_resolver
+ ? dns_hints_root (ld.resolv_conf, &derr)
diff --git a/debian/patches/0054-dirmngr-Fix-error-handling.patch b/debian/patches/0054-dirmngr-Fix-error-handling.patch
new file mode 100644
index 0000000..5b1d359
--- /dev/null
+++ b/debian/patches/0054-dirmngr-Fix-error-handling.patch
@@ -0,0 +1,26 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 21 Mar 2017 14:22:13 +0100
+Subject: dirmngr: Fix error handling.
+
+* dirmngr/dns-stuff.c (libdns_init): Convert error before printing it.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 483c1288a8f86dc6bf93d0d3f2865ecc246aecba)
+---
+ dirmngr/dns-stuff.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 35e6c82..c79a9c7 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -568,8 +568,8 @@ libdns_init (void)
+ : dns_hints_local (ld.resolv_conf, &derr));
+ if (!ld.hints)
+ {
+- log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
+ err = libdns_error_to_gpg_error (derr);
++ log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
diff --git a/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch b/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
new file mode 100644
index 0000000..f7d7608
--- /dev/null
+++ b/debian/patches/0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
@@ -0,0 +1,65 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 23 Mar 2017 09:38:19 +0100
+Subject: common: Implicitly do a gpgconf --create-socketdir.
+
+* common/homedir.c (_gnupg_socketdir_internal): Create the
+sub-directory.
+--
+
+Although there is no auto cleanup (yet) this should be helpful. Let's
+see whether possibly leaving stale directories around is better than
+running into trouble when --create-socketdir was not used.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 26086b362ff47d21b1abefaf674a6464bf0a8921)
+---
+ common/homedir.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/common/homedir.c b/common/homedir.c
+index 6b40bb6..c41cbdc 100644
+--- a/common/homedir.c
++++ b/common/homedir.c
+@@ -542,7 +542,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+
+ /* If a non default homedir is used, we check whether an
+ * corresponding sub directory below the socket dir is available
+- * and use that. We has the non default homedir to keep the new
++ * and use that. We hash the non default homedir to keep the new
+ * subdir short enough. */
+ if (non_default_homedir)
+ {
+@@ -566,16 +566,27 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+ goto leave;
+ }
+
+- /* Stat that directory and check constraints. Note that we
+- * do not auto create such a directory because we would not
+- * have a way to remove it. Thus the directory needs to be
+- * pre-created. The command
+- * gpgconf --create-socketdir
+- * can be used tocreate that directory. */
++ /* Stat that directory and check constraints.
++ * The command
++ * gpgconf --remove-socketdir
++ * can be used to remove that directory. */
+ if (stat (name, &sb))
+ {
+ if (errno != ENOENT)
+ *r_info |= 1; /* stat failed. */
++ else if (!skip_checks)
++ {
++ /* Try to create the directory and check again. */
++ if (gnupg_mkdir (name, "-rwx"))
++ *r_info |= 16; /* mkdir failed. */
++ else if (stat (prefix, &sb))
++ {
++ if (errno != ENOENT)
++ *r_info |= 1; /* stat failed. */
++ else
++ *r_info |= 64; /* Subdir does not exist. */
++ }
++ }
+ else
+ *r_info |= 64; /* Subdir does not exist. */
+ if (!skip_checks)
diff --git a/debian/patches/0056-common-Fix-connecting-to-the-agent.patch b/debian/patches/0056-common-Fix-connecting-to-the-agent.patch
new file mode 100644
index 0000000..4923afb
--- /dev/null
+++ b/debian/patches/0056-common-Fix-connecting-to-the-agent.patch
@@ -0,0 +1,34 @@
+From: Justus Winter <justus at g10code.com>
+Date: Mon, 27 Mar 2017 16:14:20 +0200
+Subject: common: Fix connecting to the agent.
+
+* common/homedir.c (_gnupg_socketdir_internal): Fix error handling.
+--
+
+Prior to 26086b36 the non-existance of the socket directory was
+considered an error if a non-default home directory is used. Since
+26086b36 we now create the directory on demand, but the function still
+returned the fallback path. This made the agent bind the socket in
+the socket directory, and the client trying to connect to the socket
+in the home directory.
+
+Fixes-commit: 26086b362ff47d21b1abefaf674a6464bf0a8921
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit caf00915532e6e8e509738962964edcd14fb0654)
+---
+ common/homedir.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/common/homedir.c b/common/homedir.c
+index c41cbdc..4571aac 100644
+--- a/common/homedir.c
++++ b/common/homedir.c
+@@ -586,6 +586,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
+ else
+ *r_info |= 64; /* Subdir does not exist. */
+ }
++ else
++ goto leave; /* Success! */
+ }
+ else
+ *r_info |= 64; /* Subdir does not exist. */
diff --git a/debian/patches/0057-g10-Fix-memory-leak.patch b/debian/patches/0057-g10-Fix-memory-leak.patch
new file mode 100644
index 0000000..d6e074f
--- /dev/null
+++ b/debian/patches/0057-g10-Fix-memory-leak.patch
@@ -0,0 +1,33 @@
+From: Justus Winter <justus at g10code.com>
+Date: Tue, 28 Mar 2017 12:10:28 +0200
+Subject: g10: Fix memory leak.
+
+* g10/decrypt-data.c (decrypt_data): Free 'filename'.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 6d3edfd972c1114f43f6b35773dc25e0256f48f4)
+---
+ g10/decrypt-data.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
+index 585b150..f5843d6 100644
+--- a/g10/decrypt-data.c
++++ b/g10/decrypt-data.c
+@@ -222,7 +222,7 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+
+ if (opt.unwrap_encryption)
+ {
+- char *filename;
++ char *filename = NULL;
+ estream_t fp;
+ rc = get_output_file ("", 0, ed->buf, &filename, &fp);
+ if (! rc)
+@@ -248,6 +248,7 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
+ if (afx)
+ release_armor_context (afx);
+ }
++ xfree (filename);
+ }
+ else
+ proc_packets (ctrl, procctx, ed->buf );
diff --git a/debian/patches/0058-common-Avoid-undefined-behavior.patch b/debian/patches/0058-common-Avoid-undefined-behavior.patch
new file mode 100644
index 0000000..ad46b22
--- /dev/null
+++ b/debian/patches/0058-common-Avoid-undefined-behavior.patch
@@ -0,0 +1,26 @@
+From: Justus Winter <justus at g10code.com>
+Date: Thu, 30 Mar 2017 15:44:35 +0200
+Subject: common: Avoid undefined behavior.
+
+* common/iobuf.c (iobuf_read_line): Do not consider 'length' if
+'buffer' is NULL.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 214fa9012296d796b78f1a3106d656639cf50aef)
+---
+ common/iobuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/common/iobuf.c b/common/iobuf.c
+index d346027..b8baf7f 100644
+--- a/common/iobuf.c
++++ b/common/iobuf.c
+@@ -2552,7 +2552,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
+ NUL character in the buffer. This requires at least 2 bytes. We
+ don't complicate the code by handling the stupid corner case, but
+ simply assert that it can't happen. */
+- assert (length >= 2 || maxlen >= 2);
++ assert (!buffer || length >= 2 || maxlen >= 2);
+
+ if (!buffer || length <= 1)
+ /* must allocate a new buffer */
diff --git a/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch b/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
new file mode 100644
index 0000000..8d958d5
--- /dev/null
+++ b/debian/patches/0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
@@ -0,0 +1,31 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 3 Apr 2017 08:51:52 +0200
+Subject: gpg: Handle critical marked 'Reason for Revocation'.
+
+* g10/parse-packet.c (can_handle_critical): Add
+SIGSUBPKT_REVOC_REASON.
+--
+
+Some software seems to mark that subpacket as criticial. Although gpg
+has no special treatment for a revocation reasons (except for
+--list-packets) we can accept a criticial marked anyway. There are no
+mandatary rules specified on how to handle a revocation reason.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 3f6d949011f485613bb4bd3e06a2643be79cce40)
+---
+ g10/parse-packet.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/g10/parse-packet.c b/g10/parse-packet.c
+index 7f44ce5..bbb784a 100644
+--- a/g10/parse-packet.c
++++ b/g10/parse-packet.c
+@@ -1572,6 +1572,7 @@ can_handle_critical (const byte * buffer, size_t n, int type)
+ /* Is it enough to show the policy or keyserver? */
+ case SIGSUBPKT_POLICY:
+ case SIGSUBPKT_PREF_KS:
++ case SIGSUBPKT_REVOC_REASON: /* At least we know about it. */
+ return 1;
+
+ default:
diff --git a/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch b/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
new file mode 100644
index 0000000..7cec8ae
--- /dev/null
+++ b/debian/patches/0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
@@ -0,0 +1,61 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 3 Apr 2017 19:10:50 +0200
+Subject: dirmngr: Do not assume that /etc/hosts exists.
+
+* dirmngr/dns-stuff.c (libdns_init): Do not bail out.
+--
+
+A standard Windows installation does not have a hosts file and thus we
+can't bail out here. We should also not bail out on a Unix system
+because /etc/hosts is just one method in nsswitch.conf.
+
+Fixes-commit: 88f1505f0613894d5544290a170119eb538921e5
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 5d873f288e86edfb684f4dd57ac36466b06494a4)
+---
+ dirmngr/dns-stuff.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index c79a9c7..c2d5488 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -538,10 +538,9 @@ libdns_init (void)
+ goto leave;
+ }
+
+-
+ {
+ #if HAVE_W32_SYSTEM
+- char *hosts_path = xtryasprintf ("%s\System32\drivers\etc\hosts",
++ char *hosts_path = xtryasprintf ("%s\\System32\\drivers\\etc\\hosts",
+ getenv ("SystemRoot"));
+ if (! hosts_path)
+ {
+@@ -551,15 +550,24 @@ libdns_init (void)
+
+ derr = dns_hosts_loadpath (ld.hosts, hosts_path);
+ xfree (hosts_path);
++ if (derr)
++ {
++ err = libdns_error_to_gpg_error (derr);
++ /* Most Windows systems don't have a hosts files. So do not
++ * report in this case. */
++ if (gpg_err_code (err) != GPG_ERR_ENOENT)
++ log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
++ err = 0; /* Do not bail out. */
++ }
+ #else
+ derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
+-#endif
+ if (derr)
+ {
+ err = libdns_error_to_gpg_error (derr);
+ log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+- goto leave;
++ err = 0; /* Do not bail out - having no /etc/hosts is legal. */
+ }
++#endif
+ }
+
+ /* dns_hints_local for stub mode, dns_hints_root for recursive. */
diff --git a/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch b/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
new file mode 100644
index 0000000..ecf484e
--- /dev/null
+++ b/debian/patches/0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
@@ -0,0 +1,49 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 3 Apr 2017 20:20:27 +0200
+Subject: dirmngr: Always print a warning for a missing /etc/hosts.
+
+* dirmngr/dns-stuff.c (libdns_init): No Windows specific handling of a
+missing /etc/hosts.
+--
+
+My last comment on this was flawed. Windows seems to always have its
+version of /etc/hosts. Only the en passant fixed bad escaping led me
+assume that this was the case. Thanks to Andre for complaining about
+my comment remark.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 35c843c815306f36d1efbc52f5e2f6bac3f67aec)
+---
+ dirmngr/dns-stuff.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index c2d5488..150237e 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -550,24 +550,15 @@ libdns_init (void)
+
+ derr = dns_hosts_loadpath (ld.hosts, hosts_path);
+ xfree (hosts_path);
+- if (derr)
+- {
+- err = libdns_error_to_gpg_error (derr);
+- /* Most Windows systems don't have a hosts files. So do not
+- * report in this case. */
+- if (gpg_err_code (err) != GPG_ERR_ENOENT)
+- log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+- err = 0; /* Do not bail out. */
+- }
+ #else
+ derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
++#endif
+ if (derr)
+ {
+ err = libdns_error_to_gpg_error (derr);
+ log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
+ err = 0; /* Do not bail out - having no /etc/hosts is legal. */
+ }
+-#endif
+ }
+
+ /* dns_hints_local for stub mode, dns_hints_root for recursive. */
diff --git a/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch b/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
new file mode 100644
index 0000000..9a53665
--- /dev/null
+++ b/debian/patches/0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
@@ -0,0 +1,26 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 3 Apr 2017 20:23:18 +0200
+Subject: dirmngr: Handle EIO which is sometimes returned by cookie functions.
+
+* dirmngr/ks-engine-hkp.c (handle_send_request_error): Handle EIO.
+--
+
+Suggested-by: Andre Heinecke
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit cc32ddbcba8c53d3e2cad952d72f62dc73911042)
+---
+ dirmngr/ks-engine-hkp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 32db4bc..66350a7 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -1245,6 +1245,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
+ case GPG_ERR_ENETDOWN:
+ case GPG_ERR_UNKNOWN_HOST:
+ case GPG_ERR_NETWORK:
++ case GPG_ERR_EIO: /* Sometimes used by estream cookie functions. */
+ if (mark_host_dead (request) && *tries_left)
+ retry = 1;
+ break;
diff --git a/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch b/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch
new file mode 100644
index 0000000..6a8ea61
--- /dev/null
+++ b/debian/patches/0063-dirmngr-New-option-disable-ipv6.patch
@@ -0,0 +1,241 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 3 Apr 2017 20:56:12 +0200
+Subject: dirmngr: New option --disable-ipv6
+
+* dirmngr/dirmngr.h (struct opt): Add field 'disable_ipv6'.
+* dirmngr/dirmngr.c (oDisableIPv6): New const.
+(opts): New option --disable-ipv6.
+(parse_rereadable_options): Set that option.
+* dirmngr/dns-stuff.c (opt_disable_ipv6): New var.
+(set_dns_disable_ipv6): New.
+(resolve_name_standard): Make use of it.
+* dirmngr/ks-engine-finger.c (ks_finger_fetch): Take care of
+OPT.DISABLE_IPV6.
+* dirmngr/ks-engine-hkp.c (map_host): Ditto.
+(send_request): Ditto.
+* dirmngr/ks-engine-http.c (ks_http_fetch): Ditto.
+* dirmngr/ocsp.c (do_ocsp_request): Ditto.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 3533b854408fa93734742b2ee12b62aa0d55ff28)
+---
+ dirmngr/crlfetch.c | 1 +
+ dirmngr/dirmngr.c | 4 ++++
+ dirmngr/dirmngr.h | 3 ++-
+ dirmngr/dns-stuff.c | 15 +++++++++++++++
+ dirmngr/dns-stuff.h | 4 ++++
+ dirmngr/ks-engine-finger.c | 3 ++-
+ dirmngr/ks-engine-hkp.c | 7 +++++--
+ dirmngr/ks-engine-http.c | 3 ++-
+ dirmngr/ocsp.c | 3 ++-
+ doc/dirmngr.texi | 5 +++--
+ 10 files changed, 40 insertions(+), 8 deletions(-)
+
+diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
+index 337fe6e..2700cf9 100644
+--- a/dirmngr/crlfetch.c
++++ b/dirmngr/crlfetch.c
+@@ -200,6 +200,7 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+ |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0)
+ |(dirmngr_use_tor()? HTTP_FLAG_FORCE_TOR:0)
+ |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0)
++ |(opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6:0)
+ ),
+ ctrl->http_proxy, NULL, NULL, NULL);
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 43e9cbd..31d3ca2 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -112,6 +112,7 @@ enum cmd_and_opt_values {
+ oDisableHTTP,
+ oDisableLDAP,
+ oDisableIPv4,
++ oDisableIPv6,
+ oIgnoreLDAPDP,
+ oIgnoreHTTPDP,
+ oIgnoreOCSPSvcUrl,
+@@ -228,6 +229,7 @@ static ARGPARSE_OPTS opts[] = {
+ ARGPARSE_s_n (oNoUseTor, "no-use-tor", "@"),
+
+ ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
++ ARGPARSE_s_n (oDisableIPv6, "disable-ipv6", "@"),
+
+ ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */
+
+@@ -624,6 +626,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+ case oDisableHTTP: opt.disable_http = 1; break;
+ case oDisableLDAP: opt.disable_ldap = 1; break;
+ case oDisableIPv4: opt.disable_ipv4 = 1; break;
++ case oDisableIPv6: opt.disable_ipv6 = 1; break;
+ case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
+ case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
+ case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
+@@ -690,6 +693,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+ set_dns_verbose (opt.verbose, !!DBG_DNS);
+ http_set_verbose (opt.verbose, !!DBG_NETWORK);
+ set_dns_disable_ipv4 (opt.disable_ipv4);
++ set_dns_disable_ipv6 (opt.disable_ipv6);
+
+ return 1; /* Handled. */
+ }
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index 6a4fd00..4cc2be0 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -97,7 +97,8 @@ struct
+
+ int disable_http; /* Do not use HTTP at all. */
+ int disable_ldap; /* Do not use LDAP at all. */
+- int disable_ipv4; /* Do not use leagacy IP addresses. */
++ int disable_ipv4; /* Do not use legacy IP addresses. */
++ int disable_ipv6; /* Do not use standard IP addresses. */
+ int honor_http_proxy; /* Honor the http_proxy env variable. */
+ const char *http_proxy; /* The default HTTP proxy. */
+ const char *ldap_proxy; /* Use given LDAP proxy. */
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 150237e..ed77742 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -123,6 +123,10 @@ static int opt_timeout;
+ * returned A records. */
+ static int opt_disable_ipv4;
+
++/* The flag to disable IPv6 access - right now this only skips
++ * returned AAAA records. */
++static int opt_disable_ipv6;
++
+ /* If set force the use of the standard resolver. */
+ static int standard_resolver;
+
+@@ -248,6 +252,15 @@ set_dns_disable_ipv4 (int yes)
+ }
+
+
++/* Set the Disable-IPv6 flag so that the name resolver does not return
++ * AAAA addresses. */
++void
++set_dns_disable_ipv6 (int yes)
++{
++ opt_disable_ipv6 = !!yes;
++}
++
++
+ /* Set the timeout for libdns requests to SECONDS. A value of 0 sets
+ * the default timeout and values are capped at 10 minutes. */
+ void
+@@ -934,6 +947,8 @@ resolve_name_standard (const char *name, unsigned short port,
+ continue;
+ if (opt_disable_ipv4 && ai->ai_family == AF_INET)
+ continue;
++ if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
++ continue;
+
+ dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
+ dai->family = ai->ai_family;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index 9b8303c..71605b7 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -99,6 +99,10 @@ void set_dns_verbose (int verbose, int debug);
+ * A addresses. */
+ void set_dns_disable_ipv4 (int yes);
+
++/* Set the Disable-IPv6 flag so that the name resolver does not return
++ * AAAA addresses. */
++void set_dns_disable_ipv6 (int yes);
++
+ /* Set the timeout for libdns requests to SECONDS. */
+ void set_dns_timeout (int seconds);
+
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index 811b72d..8a21c9f 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -84,7 +84,8 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+
+ err = http_raw_connect (&http, server, 79,
+ ((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0)
+- | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++ | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+ NULL);
+ if (err)
+ {
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 66350a7..7c91b6a 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -568,6 +568,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+ continue;
+ if (opt.disable_ipv4 && ai->family == AF_INET)
+ continue;
++ if (opt.disable_ipv6 && ai->family == AF_INET6)
++ continue;
+ dirmngr_tick (ctrl);
+
+ add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
+@@ -649,7 +651,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+ {
+ for (ai = aibuf; ai; ai = ai->next)
+ {
+- if (ai->family == AF_INET6
++ if ((!opt.disable_ipv6 && ai->family == AF_INET6)
+ || (!opt.disable_ipv4 && ai->family == AF_INET))
+ {
+ err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+@@ -1102,7 +1104,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+ (httpflags
+ |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+ |(dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+- |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++ |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++ |(opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+ ctrl->http_proxy,
+ session,
+ NULL,
+diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
+index 69642ff..6de0616 100644
+--- a/dirmngr/ks-engine-http.c
++++ b/dirmngr/ks-engine-http.c
+@@ -89,7 +89,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+ /* fixme: AUTH */ NULL,
+ ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+ | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+- | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++ | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+ ctrl->http_proxy,
+ session,
+ NULL,
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index aff8e32..22391c3 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -175,7 +175,8 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+ err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+ ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+ | (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
+- | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
++ | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
+ ctrl->http_proxy, NULL, NULL, NULL);
+ if (err)
+ {
+diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
+index b00c2d3..9a7238f 100644
+--- a/doc/dirmngr.texi
++++ b/doc/dirmngr.texi
+@@ -313,9 +313,10 @@ a numerical IP address must be given (IPv6 or IPv4) and that no error
+ checking is done for @var{ipaddr}.
+
+ @item --disable-ipv4
++ at item --disable-ipv6
+ @opindex disable-ipv4
+-Disable the use of all IPv4 addresses. This option is mainly useful
+-for debugging.
++ at opindex disable-ipv6
++Disable the use of all IPv4 or IPv6 addresses.
+
+ @item --disable-ldap
+ @opindex disable-ldap
diff --git a/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch b/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch
new file mode 100644
index 0000000..8231848
--- /dev/null
+++ b/debian/patches/0064-agent-Serialize-access-to-passphrase-cache.patch
@@ -0,0 +1,220 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Fri, 7 Apr 2017 08:39:26 +0900
+Subject: agent: Serialize access to passphrase cache.
+
+* agent/cache.c (encryption_lock): Remove.
+(cache_lock): New. Now, we have coarse grain lock to serialize
+entire cache access.
+(initialize_module_cache): Use CACHE_LOCK.
+(init_encryption, new_data): Remove ENCRYPTION_LOCK.
+(agent_flush_cache, agent_put_cache, agent_get_cache): Lock the cache.
+
+--
+
+GnuPG-bug-id: 3027
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit ebe12be034f052cdec871f0d8ad1bfab85d7b943)
+---
+ agent/cache.c | 73 ++++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 37 insertions(+), 36 deletions(-)
+
+diff --git a/agent/cache.c b/agent/cache.c
+index 2483682..fead737 100644
+--- a/agent/cache.c
++++ b/agent/cache.c
+@@ -31,9 +31,8 @@
+ /* The size of the encryption key in bytes. */
+ #define ENCRYPTION_KEYSIZE (128/8)
+
+-/* A mutex used to protect the encryption. This is required because
+- we use one context to do all encryption and decryption. */
+-static npth_mutex_t encryption_lock;
++/* A mutex used to serialize access to the cache. */
++static npth_mutex_t cache_lock;
+ /* The encryption context. This is the only place where the
+ encryption key for all cached entries is available. It would be nice
+ to keep this (or just the key) in some hardware device, for example
+@@ -76,7 +75,7 @@ initialize_module_cache (void)
+ {
+ int err;
+
+- err = npth_mutex_init (&encryption_lock, NULL);
++ err = npth_mutex_init (&cache_lock, NULL);
+
+ if (err)
+ log_fatal ("error initializing cache module: %s\n", strerror (err));
+@@ -102,15 +101,10 @@ init_encryption (void)
+ {
+ gpg_error_t err;
+ void *key;
+- int res;
+
+ if (encryption_handle)
+ return 0; /* Shortcut - Already initialized. */
+
+- res = npth_mutex_lock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res));
+-
+ err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
+ GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
+ if (!err)
+@@ -133,10 +127,6 @@ init_encryption (void)
+ log_error ("error initializing cache encryption context: %s\n",
+ gpg_strerror (err));
+
+- res = npth_mutex_unlock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+-
+ return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
+ }
+
+@@ -155,7 +145,6 @@ new_data (const char *string, struct secret_data_s **r_data)
+ struct secret_data_s *d, *d_enc;
+ size_t length;
+ int total;
+- int res;
+
+ *r_data = NULL;
+
+@@ -186,17 +175,9 @@ new_data (const char *string, struct secret_data_s **r_data)
+ }
+
+ d_enc->totallen = total;
+- res = npth_mutex_lock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to acquire cache encryption mutex: %s\n",
+- strerror (res));
+-
+ err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
+ d->data, total - 8);
+ xfree (d);
+- res = npth_mutex_unlock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
+ if (err)
+ {
+ xfree (d_enc);
+@@ -281,10 +262,15 @@ void
+ agent_flush_cache (void)
+ {
+ ITEM r;
++ int res;
+
+ if (DBG_CACHE)
+ log_debug ("agent_flush_cache\n");
+
++ res = npth_mutex_lock (&cache_lock);
++ if (res)
++ log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
++
+ for (r=thecache; r; r = r->next)
+ {
+ if (r->pw)
+@@ -296,6 +282,10 @@ agent_flush_cache (void)
+ r->accessed = 0;
+ }
+ }
++
++ res = npth_mutex_unlock (&cache_lock);
++ if (res)
++ log_fatal ("failed to release cache mutex: %s\n", strerror (res));
+ }
+
+
+@@ -321,6 +311,11 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+ {
+ gpg_error_t err = 0;
+ ITEM r;
++ int res;
++
++ res = npth_mutex_lock (&cache_lock);
++ if (res)
++ log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
+
+ if (DBG_CACHE)
+ log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
+@@ -336,7 +331,7 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+ }
+ }
+ if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
+- return 0;
++ goto out;
+
+ for (r=thecache; r; r = r->next)
+ {
+@@ -386,6 +381,12 @@ agent_put_cache (const char *key, cache_mode_t cache_mode,
+ if (err)
+ log_error ("error inserting cache item: %s\n", gpg_strerror (err));
+ }
++
++ out:
++ res = npth_mutex_unlock (&cache_lock);
++ if (res)
++ log_fatal ("failed to release cache mutex: %s\n", strerror (res));
++
+ return err;
+ }
+
+@@ -405,15 +406,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+ if (cache_mode == CACHE_MODE_IGNORE)
+ return NULL;
+
++ res = npth_mutex_lock (&cache_lock);
++ if (res)
++ log_fatal ("failed to acquire cache mutex: %s\n", strerror (res));
++
+ if (!key)
+ {
+ key = last_stored_cache_key;
+ if (!key)
+- return NULL;
++ goto out;
+ last_stored = 1;
+ }
+
+-
+ if (DBG_CACHE)
+ log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
+ key, cache_mode,
+@@ -440,17 +444,9 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+ err = gpg_error_from_syserror ();
+ else
+ {
+- res = npth_mutex_lock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to acquire cache encryption mutex: %s\n",
+- strerror (res));
+ err = gcry_cipher_decrypt (encryption_handle,
+ value, r->pw->totallen - 8,
+ r->pw->data, r->pw->totallen);
+- res = npth_mutex_unlock (&encryption_lock);
+- if (res)
+- log_fatal ("failed to release cache encryption mutex: %s\n",
+- strerror (res));
+ }
+ if (err)
+ {
+@@ -459,13 +455,18 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+ log_error ("retrieving cache entry '%s' failed: %s\n",
+ key, gpg_strerror (err));
+ }
+- return value;
++ break;
+ }
+ }
+- if (DBG_CACHE)
++ if (DBG_CACHE && value == NULL)
+ log_debug ("... miss\n");
+
+- return NULL;
++ out:
++ res = npth_mutex_unlock (&cache_lock);
++ if (res)
++ log_fatal ("failed to release cache mutex: %s\n", strerror (res));
++
++ return value;
+ }
+
+
diff --git a/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch b/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch
new file mode 100644
index 0000000..4c17652
--- /dev/null
+++ b/debian/patches/0065-gpg-Fix-printing-of-offline-taken-subkey.patch
@@ -0,0 +1,27 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 7 Apr 2017 10:11:07 +0200
+Subject: gpg: Fix printing of offline taken subkey.
+
+* g10/keylist.c (list_keyblock_print): Set SECRET to 2 and not 0x32.
+--
+
+Reported-by: Danielle McLean <dani at 00dani.me>
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 547bc01d57528ecc27b3b5e16797967a7f88fecf)
+---
+ g10/keylist.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/keylist.c b/g10/keylist.c
+index 4078053..1998ee9 100644
+--- a/g10/keylist.c
++++ b/g10/keylist.c
+@@ -1017,7 +1017,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
+ if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
+ secret = serialno? 3 : 1;
+ else
+- secret = '2'; /* Key not found. */
++ secret = 2; /* Key not found. */
+ }
+
+ /* Print the "sub" line. */
diff --git a/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch b/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch
new file mode 100644
index 0000000..aba3532
--- /dev/null
+++ b/debian/patches/0066-doc-Explain-the-in-a-key-listing.patch
@@ -0,0 +1,34 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Fri, 7 Apr 2017 10:26:55 +0200
+Subject: doc: Explain the '>' in a key listing.
+
+--
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 9c9fde1495be4accf4526a2626110876fd9d788d)
+---
+ doc/gpg.texi | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/doc/gpg.texi b/doc/gpg.texi
+index d658737..c591049 100644
+--- a/doc/gpg.texi
++++ b/doc/gpg.texi
+@@ -301,10 +301,13 @@ and other programs.
+ @itemx -K
+ @opindex list-secret-keys
+ List the specified secret keys. If no keys are specified, then all
+-known secret keys are listed. A @code{#} after the letters @code{sec}
+-means that the secret key is not usable (for example, if it was
+-exported using @option{--export-secret-subkeys}). See also
+- at option{--list-keys}.
++known secret keys are listed. A @code{#} after the intial tags
++ at code{sec} or @code{ssb} means that the secret key or subkey is
++currently not usable. We also say that this key has been taken
++offline (for example, a primary key can be taken offline by exported
++the key using the command @option{--export-secret-subkeys}). A
++ at code{>} after these tags indicate that the key is stored on a
++smartcard. See also @option{--list-keys}.
+
+ @item --list-signatures
+ @opindex list-signatures
diff --git a/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch b/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch
new file mode 100644
index 0000000..d71c926
--- /dev/null
+++ b/debian/patches/0067-dirmngr-Fix-possible-null-reference.patch
@@ -0,0 +1,28 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Wed, 12 Apr 2017 15:58:11 +0900
+Subject: dirmngr: Fix possible null reference.
+
+* dirmngr/dns.c (dns_error_t dns_trace_fput): Check NULL.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 7ae1857c90ab43ad9e31f0fb6dbd37f25cc37278)
+---
+ dirmngr/dns.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/dirmngr/dns.c b/dirmngr/dns.c
+index 869e7ed..ebfd4c3 100644
+--- a/dirmngr/dns.c
++++ b/dirmngr/dns.c
+@@ -4594,8 +4594,9 @@ dns_error_t dns_trace_fput(const struct dns_trace_event *te, const void *data, s
+
+ if (fwrite(&tmp, 1, headsize, fp) < headsize)
+ return errno;
+- if (fwrite(data, 1, datasize, fp) < datasize)
+- return errno;
++ if (data)
++ if (fwrite(data, 1, datasize, fp) < datasize)
++ return errno;
+ if (fflush(fp))
+ return errno;
+
diff --git a/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch b/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch
new file mode 100644
index 0000000..821d0a9
--- /dev/null
+++ b/debian/patches/0068-tools-Fix-condition-for-gpg-connect-agent.patch
@@ -0,0 +1,30 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Wed, 12 Apr 2017 16:01:16 +0900
+Subject: tools: Fix condition for gpg-connect-agent.
+
+* tools/gpg-connect-agent.c (start_agent): Add paren.
+
+--
+
+The intention is comparing the error code depending opt.use_dirmngr.
+Considering C Operator Precedence, we should have paren here.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit f52f6af834cc488d11612e349e4af023d69a45f4)
+---
+ tools/gpg-connect-agent.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
+index a5413cf..5af1465 100644
+--- a/tools/gpg-connect-agent.c
++++ b/tools/gpg-connect-agent.c
+@@ -2237,7 +2237,7 @@ start_agent (void)
+ {
+ if (!opt.autostart
+ && (gpg_err_code (err)
+- == opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT))
++ == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT)))
+ {
+ /* In the no-autostart case we don't make gpg-connect-agent
+ fail on a missing server. */
diff --git a/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch b/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch
new file mode 100644
index 0000000..ef6e2ce
--- /dev/null
+++ b/debian/patches/0069-dirmngr-Fix-alignment-of-ADDR.patch
@@ -0,0 +1,155 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Thu, 13 Apr 2017 14:33:33 +0900
+Subject: dirmngr: Fix alignment of ADDR.
+
+* dirmngr/dns-stuff.h (dns_addrinfo_s): Use struct sockaddr_storage
+for size and alignment.
+* dirmngr/dns-stuff.c (resolve_name_libdns): Follow the change.
+(resolve_dns_name): Use struct sockaddr_storage.
+(resolve_addr_standard, resolve_dns_addr): Likewise.
+(resolve_dns_addr): Likewise.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 892b33bb2c57785927ea6652091191da2deed464)
+---
+ dirmngr/dns-stuff.c | 31 +++++++++++++++++--------------
+ dirmngr/dns-stuff.h | 4 ++--
+ 2 files changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index ed77742..c63d958 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -827,7 +827,7 @@ resolve_name_libdns (const char *name, unsigned short port,
+ (*r_canonname)[strlen (*r_canonname)-1] = 0;
+ }
+
+- dai = xtrymalloc (sizeof *dai + ent->ai_addrlen -1);
++ dai = xtrymalloc (sizeof *dai);
+ if (dai == NULL)
+ {
+ err = gpg_error_from_syserror ();
+@@ -950,7 +950,7 @@ resolve_name_standard (const char *name, unsigned short port,
+ if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
+ continue;
+
+- dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
++ dai = xtrymalloc (sizeof *dai);
+ dai->family = ai->ai_family;
+ dai->socktype = ai->ai_socktype;
+ dai->protocol = ai->ai_protocol;
+@@ -1018,7 +1018,7 @@ resolve_dns_name (const char *name, unsigned short port,
+ #ifdef USE_LIBDNS
+ /* Resolve an address using libdns. */
+ static gpg_error_t
+-resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
++resolve_addr_libdns (const struct sockaddr_storage *addr, int addrlen,
+ unsigned int flags, char **r_name)
+ {
+ gpg_error_t err;
+@@ -1032,13 +1032,13 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+
+ /* First we turn ADDR into a DNS name (with ".arpa" suffix). */
+ err = 0;
+- if (addr->sa_family == AF_INET6)
++ if (addr->ss_family == AF_INET6)
+ {
+ const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr;
+ if (!dns_aaaa_arpa (host, sizeof host, (void*)&a6->sin6_addr))
+ err = gpg_error (GPG_ERR_INV_OBJ);
+ }
+- else if (addr->sa_family == AF_INET)
++ else if (addr->ss_family == AF_INET)
+ {
+ const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr;
+ if (!dns_a_arpa (host, sizeof host, (void*)&a4->sin_addr))
+@@ -1126,18 +1126,19 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+ buflen = sizeof ptr.host;
+
+ p = buffer;
+- if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++ if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+ {
+ *p++ = '[';
+ buflen -= 2;
+ }
+- ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
++ ec = getnameinfo ((const struct sockaddr *)addr,
++ addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
+ if (ec)
+ {
+ err = map_eai_to_gpg_error (ec);
+ goto leave;
+ }
+- if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++ if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+ strcat (buffer, "]");
+ }
+
+@@ -1151,7 +1152,7 @@ resolve_addr_libdns (const struct sockaddr *addr, int addrlen,
+
+ /* Resolve an address using the standard system function. */
+ static gpg_error_t
+-resolve_addr_standard (const struct sockaddr *addr, int addrlen,
++resolve_addr_standard (const struct sockaddr_storage *addr, int addrlen,
+ unsigned int flags, char **r_name)
+ {
+ gpg_error_t err;
+@@ -1169,20 +1170,22 @@ resolve_addr_standard (const struct sockaddr *addr, int addrlen,
+ if ((flags & DNS_NUMERICHOST) || tor_mode)
+ ec = EAI_NONAME;
+ else
+- ec = getnameinfo (addr, addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
++ ec = getnameinfo ((const struct sockaddr *)addr,
++ addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
+
+ if (!ec && *buffer == '[')
+ ec = EAI_FAIL; /* A name may never start with a bracket. */
+ else if (ec == EAI_NONAME)
+ {
+ p = buffer;
+- if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++ if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+ {
+ *p++ = '[';
+ buflen -= 2;
+ }
+- ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
+- if (!ec && addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
++ ec = getnameinfo ((const struct sockaddr *)addr,
++ addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
++ if (!ec && addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
+ strcat (buffer, "]");
+ }
+
+@@ -1211,7 +1214,7 @@ resolve_addr_standard (const struct sockaddr *addr, int addrlen,
+
+ /* A wrapper around getnameinfo. */
+ gpg_error_t
+-resolve_dns_addr (const struct sockaddr *addr, int addrlen,
++resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+ unsigned int flags, char **r_name)
+ {
+ gpg_error_t err;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index 71605b7..adb0b80 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -78,7 +78,7 @@ struct dns_addrinfo_s
+ int socktype;
+ int protocol;
+ int addrlen;
+- struct sockaddr addr[1];
++ struct sockaddr_storage addr[1];
+ };
+
+
+@@ -142,7 +142,7 @@ gpg_error_t resolve_dns_name (const char *name, unsigned short port,
+ dns_addrinfo_t *r_dai, char **r_canonname);
+
+ /* Function similar to getnameinfo. */
+-gpg_error_t resolve_dns_addr (const struct sockaddr *addr, int addrlen,
++gpg_error_t resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+ unsigned int flags, char **r_name);
+
+ /* Return true if NAME is a numerical IP address. */
diff --git a/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch b/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
new file mode 100644
index 0000000..a87e7b2
--- /dev/null
+++ b/debian/patches/0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
@@ -0,0 +1,70 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Thu, 13 Apr 2017 14:46:57 +0900
+Subject: dirmngr: Fix http.c for sockaddr_storage.
+
+dirmngr/http.c (use_socks): Use sockaddr_storage.
+(my_sock_new_for_addr, connect_server): Likewise.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 86dcb03134fd4957d51ebaa06b7991239f9ee56a)
+---
+ dirmngr/http.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index c9c16df..674cb3d 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -2415,13 +2415,13 @@ start_server ()
+ * This function is basically a copy of the same internal fucntion in
+ * Libassuan. */
+ static int
+-use_socks (struct sockaddr *addr)
++use_socks (struct sockaddr_storage *addr)
+ {
+ int mode;
+
+ if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
+ return 0; /* Not in Tor mode. */
+- else if (addr->sa_family == AF_INET6)
++ else if (addr->ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
+ const unsigned char *s;
+@@ -2436,7 +2436,7 @@ use_socks (struct sockaddr *addr)
+
+ return 0; /* This is the loopback address. */
+ }
+- else if (addr->sa_family == AF_INET)
++ else if (addr->ss_family == AF_INET)
+ {
+ struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+
+@@ -2453,7 +2453,7 @@ use_socks (struct sockaddr *addr)
+ /* Wrapper around assuan_sock_new which takes the domain from an
+ * address parameter. */
+ static assuan_fd_t
+-my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
++my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
+ {
+ int domain;
+
+@@ -2464,7 +2464,7 @@ my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
+ domain = AF_INET;
+ }
+ else
+- domain = addr->sa_family;
++ domain = addr->ss_family;
+
+ return assuan_sock_new (domain, type, proto);
+ }
+@@ -2589,7 +2589,8 @@ connect_server (const char *server, unsigned short port,
+ }
+
+ anyhostaddr = 1;
+- if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
++ if (assuan_sock_connect (sock, (struct sockaddr *)ai->addr,
++ ai->addrlen))
+ {
+ last_err = gpg_err_make (default_errsource,
+ gpg_err_code_from_syserror ());
diff --git a/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch b/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch
new file mode 100644
index 0000000..5c96039
--- /dev/null
+++ b/debian/patches/0071-g10-Fix-import-export-filter-property-match.patch
@@ -0,0 +1,25 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 17 Apr 2017 09:08:31 +0900
+Subject: g10: Fix import/export filter property match.
+
+* g10/import.c (impex_filter_getval): Fix to "else if".
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit af5f8ecf51f5e1f33e832d4946d02313b78a0536)
+---
+ g10/import.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index 4e6f692..125b994 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1235,7 +1235,7 @@ impex_filter_getval (void *cookie, const char *propname)
+ snprintf (numbuf, sizeof numbuf, "%d", pk->pubkey_algo);
+ result = numbuf;
+ }
+- if (!strcmp (propname, "key_created"))
++ else if (!strcmp (propname, "key_created"))
+ {
+ snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->timestamp);
+ result = numbuf;
diff --git a/debian/patches/0072-g10-Minor-fixes.patch b/debian/patches/0072-g10-Minor-fixes.patch
new file mode 100644
index 0000000..774e57d
--- /dev/null
+++ b/debian/patches/0072-g10-Minor-fixes.patch
@@ -0,0 +1,66 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 17 Apr 2017 09:15:13 +0900
+Subject: g10: Minor fixes.
+
+* g10/export.c (cleartext_secret_key_to_openpgp): No initialization.
+(do_export_one_keyblock): Initialize with GPG_ERR_NOT_FOUND.
+* g10/getkey.c (get_best_pubkey_byname): Add non-null check.
+* g10/tofu.c (tofu_set_policy): ERR initialize to 0.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 0dec0cc281dfa26db89f8cc5ee002dea5c2b2e81)
+---
+ g10/export.c | 4 ++--
+ g10/getkey.c | 3 ++-
+ g10/tofu.c | 2 +-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/g10/export.c b/g10/export.c
+index 207f994..ea9ffb4 100644
+--- a/g10/export.c
++++ b/g10/export.c
+@@ -580,7 +580,7 @@ canon_pk_algo (enum gcry_pk_algos algo)
+ static gpg_error_t
+ cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
+ {
+- gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
++ gpg_error_t err;
+ gcry_sexp_t top_list;
+ gcry_sexp_t key = NULL;
+ char *key_type = NULL;
+@@ -1524,7 +1524,7 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
+ KEYDB_SEARCH_DESC *desc, size_t ndesc,
+ size_t descindex, gcry_cipher_hd_t cipherhd)
+ {
+- gpg_error_t err;
++ gpg_error_t err = gpg_error (GPG_ERR_NOT_FOUND);
+ char *cache_nonce = NULL;
+ subkey_list_t subkey_list = NULL; /* Track already processed subkeys. */
+ int skip_until_subkey = 0;
+diff --git a/g10/getkey.c b/g10/getkey.c
+index 21dcf08..961d7de 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -1640,7 +1640,8 @@ get_best_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk,
+ if (! ctx->kr_handle)
+ {
+ xfree (ctx);
+- *retctx = NULL;
++ if (retctx)
++ *retctx = NULL;
+ rc = gpg_error_from_syserror ();
+ }
+ else
+diff --git a/g10/tofu.c b/g10/tofu.c
+index 39457a5..c3a4988 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -3857,7 +3857,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list,
+ gpg_error_t
+ tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy)
+ {
+- gpg_error_t err;
++ gpg_error_t err = 0;
+ time_t now = gnupg_get_time ();
+ tofu_dbs_t dbs;
+ PKT_public_key *pk;
diff --git a/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch b/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
new file mode 100644
index 0000000..0963208
--- /dev/null
+++ b/debian/patches/0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
@@ -0,0 +1,52 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 18 Apr 2017 09:04:11 +0900
+Subject: dirmngr: Fix final close of LISTEN_FD.
+
+* dirmngr/dirmngr.c (handle_connections): Close LISTEN_FD.
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 4b2581dc0ea1d03e70023bb0748aa0c21c0a2173)
+---
+ dirmngr/dirmngr.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 31d3ca2..513e2a6 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -1905,7 +1905,6 @@ handle_connections (assuan_fd_t listen_fd)
+ #endif
+ struct sockaddr_un paddr;
+ socklen_t plen = sizeof( paddr );
+- gnupg_fd_t fd;
+ int nfd, ret;
+ fd_set fdset, read_fdset;
+ int saved_errno;
+@@ -2030,6 +2029,8 @@ handle_connections (assuan_fd_t listen_fd)
+
+ if (FD_ISSET (FD2INT (listen_fd), &read_fdset))
+ {
++ gnupg_fd_t fd;
++
+ plen = sizeof paddr;
+ fd = INT2FD (npth_accept (FD2INT(listen_fd),
+ (struct sockaddr *)&paddr, &plen));
+@@ -2058,7 +2059,6 @@ handle_connections (assuan_fd_t listen_fd)
+ }
+ npth_setname_np (thread, threadname);
+ }
+- fd = GNUPG_INVALID_FD;
+ }
+ }
+
+@@ -2067,8 +2067,8 @@ handle_connections (assuan_fd_t listen_fd)
+ close (my_inotify_fd);
+ #endif /*HAVE_INOTIFY_INIT*/
+ npth_attr_destroy (&tattr);
+- if (listen_fd != -1)
+- assuan_sock_close (fd);
++ if (listen_fd != GNUPG_INVALID_FD)
++ assuan_sock_close (listen_fd);
+ cleanup ();
+ log_info ("%s %s stopped\n", strusage(11), strusage(13));
+ }
diff --git a/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch b/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch
new file mode 100644
index 0000000..e366af1
--- /dev/null
+++ b/debian/patches/0074-g10-invalidate-the-fd-cache-for-keyring.patch
@@ -0,0 +1,41 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 25 Apr 2017 07:48:51 +0900
+Subject: g10: invalidate the fd cache for keyring.
+
+* g10/keyring.c (keyring_search_reset): Don't keep the FD cache.
+
+--
+
+GnuPG-bug-id: 3096
+Fixes-commit: 5556eca5acd46983bff0b38a1ffbc2f07fbaba9f
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 116cfd60779fbb3540da629db54dc2e148f4a3a2)
+---
+ g10/keyring.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/g10/keyring.c b/g10/keyring.c
+index 328290e..d75fdbc 100644
+--- a/g10/keyring.c
++++ b/g10/keyring.c
+@@ -692,7 +692,6 @@ keyring_search_reset (KEYRING_HANDLE hd)
+ {
+ log_assert (hd);
+
+- hd->current.kr = NULL;
+ iobuf_close (hd->current.iobuf);
+ hd->current.iobuf = NULL;
+ hd->current.eof = 0;
+@@ -700,6 +699,12 @@ keyring_search_reset (KEYRING_HANDLE hd)
+
+ hd->found.kr = NULL;
+ hd->found.offset = 0;
++
++ if (hd->current.kr)
++ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0,
++ (char*)hd->current.kr->fname);
++ hd->current.kr = NULL;
++
+ return 0;
+ }
+
diff --git a/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch b/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
new file mode 100644
index 0000000..07c2b54
--- /dev/null
+++ b/debian/patches/0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
@@ -0,0 +1,89 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 25 Apr 2017 21:00:41 +0900
+Subject: dirmngr: Fix aliasing problem in dns.c.
+
+* dirmngr/dns.c (dns_ai_setent): Care about aliasing.
+
+--
+
+Co-authored-by: Tomas Mraz
+GnuPG-bug-id: 3105
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 247932f367f856e7ce91528e14f0aaf838150857)
+---
+ dirmngr/dns.c | 34 ++++++++++++++++++----------------
+ 1 file changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/dns.c b/dirmngr/dns.c
+index ebfd4c3..866f69d 100644
+--- a/dirmngr/dns.c
++++ b/dirmngr/dns.c
+@@ -9440,29 +9440,31 @@ void dns_ai_close(struct dns_addrinfo *ai) {
+
+
+ static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_type type, struct dns_addrinfo *ai) {
+- struct sockaddr *saddr;
+- struct sockaddr_in sin;
+- struct sockaddr_in6 sin6;
++ union u {
++ struct sockaddr_in sin;
++ struct sockaddr_in6 sin6;
++ struct sockaddr_storage ss;
++ } addr;
+ const char *cname;
+ size_t clen;
+
+ switch (type) {
+ case DNS_T_A:
+- saddr = memset(&sin, '\0', sizeof sin);
++ memset(&addr.sin, '\0', sizeof addr.sin);
+
+- sin.sin_family = AF_INET;
+- sin.sin_port = htons(ai->port);
++ addr.sin.sin_family = AF_INET;
++ addr.sin.sin_port = htons(ai->port);
+
+- memcpy(&sin.sin_addr, any, sizeof sin.sin_addr);
++ memcpy(&addr.sin.sin_addr, any, sizeof addr.sin.sin_addr);
+
+ break;
+ case DNS_T_AAAA:
+- saddr = memset(&sin6, '\0', sizeof sin6);
++ memset(&addr.sin6, '\0', sizeof addr.sin6);
+
+- sin6.sin6_family = AF_INET6;
+- sin6.sin6_port = htons(ai->port);
++ addr.sin6.sin6_family = AF_INET6;
++ addr.sin6.sin6_port = htons(ai->port);
+
+- memcpy(&sin6.sin6_addr, any, sizeof sin6.sin6_addr);
++ memcpy(&addr.sin6.sin6_addr, any, sizeof addr.sin6.sin6_addr);
+
+ break;
+ default:
+@@ -9477,20 +9479,20 @@ static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_typ
+ clen = 0;
+ }
+
+- if (!(*ent = malloc(sizeof **ent + dns_sa_len(saddr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0))))
++ if (!(*ent = malloc(sizeof **ent + dns_sa_len(&addr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0))))
+ return dns_syerr();
+
+ memset(*ent, '\0', sizeof **ent);
+
+- (*ent)->ai_family = saddr->sa_family;
++ (*ent)->ai_family = addr.ss.ss_family;
+ (*ent)->ai_socktype = ai->hints.ai_socktype;
+ (*ent)->ai_protocol = ai->hints.ai_protocol;
+
+- (*ent)->ai_addr = memcpy((unsigned char *)*ent + sizeof **ent, saddr, dns_sa_len(saddr));
+- (*ent)->ai_addrlen = dns_sa_len(saddr);
++ (*ent)->ai_addr = memcpy((unsigned char *)*ent + sizeof **ent, &addr, dns_sa_len(&addr));
++ (*ent)->ai_addrlen = dns_sa_len(&addr);
+
+ if (ai->hints.ai_flags & AI_CANONNAME)
+- (*ent)->ai_canonname = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(saddr), cname, clen + 1);
++ (*ent)->ai_canonname = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(&addr), cname, clen + 1);
+
+ ai->found++;
+
diff --git a/debian/patches/series b/debian/patches/series
index 6de976c..5082707 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -37,3 +37,39 @@ gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
0037-dirmngr-Do-a-DNS-lookup-even-if-it-is-missing-from-n.patch
0038-gpg-Make-export-ssh-key-work-for-the-primary-key.patch
0039-dirmngr-Avoid-PTR-lookup-for-hosts-in-a-pool.patch
+0040-gpgv-w32-Fix-status-fd.patch
+0041-gpg-tools-Make-trust-model-configurable-via-gpgconf.patch
+0042-gpg-tools-Make-auto-key-retrieve-configurable-via-gp.patch
+0043-gpg-Allow-creating-keys-using-an-existing-ECC-key.patch
+0044-gpg-Make-export-options-work-with-export-secret-keys.patch
+0045-common-tools-Always-escape-newlines-when-escaping-da.patch
+0046-g10-Signal-an-error-when-trying-to-revoke-non-exista.patch
+0047-gpg-Fix-possible-segv-when-attribute-packets-are-fil.patch
+0048-gpg-Fix-attempt-to-double-free-an-UID-structure.patch
+0049-doc-Add-a-note-to-the-trust-model-direct.patch
+0050-gpg-Flush-stdout-before-printing-stats-with-check-si.patch
+0051-dirmngr-Ignore-warning-alerts-in-the-GNUTLS-handshak.patch
+0052-gpg-Make-sure-the-conflict-set-includes-the-current-.patch
+0053-dirmngr-Load-the-hosts-file-into-libdns.patch
+0054-dirmngr-Fix-error-handling.patch
+0055-common-Implicitly-do-a-gpgconf-create-socketdir.patch
+0056-common-Fix-connecting-to-the-agent.patch
+0057-g10-Fix-memory-leak.patch
+0058-common-Avoid-undefined-behavior.patch
+0059-gpg-Handle-critical-marked-Reason-for-Revocation.patch
+0060-dirmngr-Do-not-assume-that-etc-hosts-exists.patch
+0061-dirmngr-Always-print-a-warning-for-a-missing-etc-hos.patch
+0062-dirmngr-Handle-EIO-which-is-sometimes-returned-by-co.patch
+0063-dirmngr-New-option-disable-ipv6.patch
+0064-agent-Serialize-access-to-passphrase-cache.patch
+0065-gpg-Fix-printing-of-offline-taken-subkey.patch
+0066-doc-Explain-the-in-a-key-listing.patch
+0067-dirmngr-Fix-possible-null-reference.patch
+0068-tools-Fix-condition-for-gpg-connect-agent.patch
+0069-dirmngr-Fix-alignment-of-ADDR.patch
+0070-dirmngr-Fix-http.c-for-sockaddr_storage.patch
+0071-g10-Fix-import-export-filter-property-match.patch
+0072-g10-Minor-fixes.patch
+0073-dirmngr-Fix-final-close-of-LISTEN_FD.patch
+0074-g10-invalidate-the-fd-cache-for-keyring.patch
+0075-dirmngr-Fix-aliasing-problem-in-dns.c.patch
--
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