[Pkg-gnupg-commit] [gnupg2] 01/20: include upstream bugfixes and improvements (Closes: #863221)
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed Jul 26 20:20:45 UTC 2017
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch experimental
in repository gnupg2.
commit 037a5c4049b87e4b5b243ec2c23b1a2c6d883546
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date: Fri May 26 20:04:34 2017 -0400
include upstream bugfixes and improvements (Closes: #863221)
---
...ault-key-selection-for-signing-possibly-b.patch | 169 ++++++++++++
...t-Add-const-qualifier-for-read-only-table.patch | 115 ++++++++
...ort-different-digest-algorithms-for-ssh-f.patch | 224 +++++++++++++++
...ectly-render-SHA256-based-ssh-fingerprint.patch | 303 +++++++++++++++++++++
...-both-ssh-fingerprints-to-sshcontrol-file.patch | 79 ++++++
...digest-algorithms-for-ssh-fingerprints-co.patch | 141 ++++++++++
...init-libdns-resolver-on-towel-change-of-r.patch | 110 ++++++++
...s-towel-should-better-detect-a-changed-re.patch | 47 ++++
debian/patches/series | 8 +
9 files changed, 1196 insertions(+)
diff --git a/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch b/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
new file mode 100644
index 0000000..70a6c48
--- /dev/null
+++ b/debian/patches/0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
@@ -0,0 +1,169 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Mon, 22 May 2017 09:27:36 +0900
+Subject: g10: Fix default-key selection for signing, possibly by card.
+
+* g10/call-agent.c (warn_version_mismatch): Revert.
+(start_agent): Suppress version mismatch if relevant.
+* g10/getkey.c (get_seckey_default_or_card): New.
+* g10/skclist.c (build_sk_list): Use get_seckey_default_or_card.
+
+--
+
+The change of 97a2394, which prefers available card than default key
+specified is too strong.
+
+Fixes-commit: 97a2394ecafaa6f58e4a1f70ecfd04408dc15606
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit fbb2259d22e6c6eadc2af722bdc52922da348677)
+---
+ g10/call-agent.c | 8 ++++----
+ g10/getkey.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ g10/keydb.h | 2 ++
+ g10/skclist.c | 16 ++++------------
+ 4 files changed, 62 insertions(+), 16 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 4698a25..e6dbb73 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -184,8 +184,7 @@ default_inq_cb (void *opaque, const char *line)
+
+
+ /* Print a warning if the server's version number is less than our
+- version number. Returns an error code on a connection problem.
+- Ignore an error for scdaemon (MODE==2). */
++ version number. Returns an error code on a connection problem. */
+ static gpg_error_t
+ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
+ {
+@@ -194,7 +193,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
+ const char *myversion = strusage (13);
+
+ err = get_assuan_server_version (ctx, mode, &serverversion);
+- if (err && mode != 2)
++ if (err)
+ log_error (_("error getting version from '%s': %s\n"),
+ servername, gpg_strerror (err));
+ else if (compare_version_strings (serverversion, myversion) < 0)
+@@ -290,7 +289,8 @@ start_agent (ctrl_t ctrl, int flag_for_card)
+
+ memset (&info, 0, sizeof info);
+
+- rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
++ if (!(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
++ rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
+ if (!rc)
+ rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
+ NULL, NULL, NULL, NULL,
+diff --git a/g10/getkey.c b/g10/getkey.c
+index a81041f..9ac32f7 100644
+--- a/g10/getkey.c
++++ b/g10/getkey.c
+@@ -3967,6 +3967,58 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
+ }
+ }
+
++gpg_error_t
++get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
++ const byte *fpr_card, size_t fpr_len)
++{
++ gpg_error_t err;
++ strlist_t namelist = NULL;
++
++ const char *def_secret_key = parse_def_secret_key (ctrl);
++
++ if (def_secret_key)
++ add_to_strlist (&namelist, def_secret_key);
++ else if (fpr_card)
++ return get_pubkey_byfprint (ctrl, pk, NULL, fpr_card, fpr_len);
++
++ if (!fpr_card
++ || (def_secret_key && def_secret_key[strlen (def_secret_key)-1] == '!'))
++ err = key_byname (ctrl, NULL, namelist, pk, 1, 0, NULL, NULL);
++ else
++ { /* Default key is specified and card key is also available. */
++ kbnode_t k, keyblock = NULL;
++
++ err = key_byname (ctrl, NULL, namelist, pk, 1, 0, &keyblock, NULL);
++ if (!err)
++ for (k = keyblock; k; k = k->next)
++ {
++ PKT_public_key *pk_candidate;
++ char fpr[MAX_FINGERPRINT_LEN];
++
++ if (k->pkt->pkttype != PKT_PUBLIC_KEY
++ &&k->pkt->pkttype != PKT_PUBLIC_SUBKEY)
++ continue;
++
++ pk_candidate = k->pkt->pkt.public_key;
++ if (!pk_candidate->flags.valid)
++ continue;
++ if (!((pk_candidate->pubkey_usage & USAGE_MASK) & pk->req_usage))
++ continue;
++ fingerprint_from_pk (pk_candidate, fpr, NULL);
++ if (!memcmp (fpr_card, fpr, fpr_len))
++ {
++ release_public_key_parts (pk);
++ copy_public_key (pk, pk_candidate);
++ break;
++ }
++ }
++ release_kbnode (keyblock);
++ }
++
++ free_strlist (namelist);
++
++ return err;
++}
+
+ /*********************************************
+ *********** User ID printing helpers *******
+diff --git a/g10/keydb.h b/g10/keydb.h
+index 1da93a7..4016723 100644
+--- a/g10/keydb.h
++++ b/g10/keydb.h
+@@ -351,6 +351,8 @@ const char *parse_def_secret_key (ctrl_t ctrl);
+
+ /* Look up a secret key. */
+ gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk);
++gpg_error_t get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
++ const byte *fpr, size_t fpr_len);
+
+ /* Search for keys matching some criteria. */
+ gpg_error_t getkey_bynames (ctrl_t ctrl,
+diff --git a/g10/skclist.c b/g10/skclist.c
+index 489277c..78890dc 100644
+--- a/g10/skclist.c
++++ b/g10/skclist.c
+@@ -137,7 +137,7 @@ build_sk_list (ctrl_t ctrl,
+ pk = xmalloc_clear (sizeof *pk);
+ pk->req_usage = use;
+
+- /* Check if a card is available. If any, use it. */
++ /* Check if a card is available. If any, use the key as a hint. */
+ err = agent_scd_serialno (&serialno, NULL);
+ if (!err)
+ {
+@@ -146,19 +146,11 @@ build_sk_list (ctrl_t ctrl,
+ if (err)
+ log_error ("error retrieving key fingerprint from card: %s\n",
+ gpg_strerror (err));
+- else if (info.fpr1valid)
+- {
+- if ((err = get_pubkey_byfprint (ctrl, pk, NULL, info.fpr1, 20)))
+- {
+- info.fpr1valid = 0;
+- log_error ("error on card key to sign: %s, try default\n",
+- gpg_strerror (err));
+- }
+- }
+ }
+
+- if (!info.fpr1valid
+- && (err = getkey_byname (ctrl, NULL, pk, NULL, 1, NULL)))
++ err = get_seckey_default_or_card (ctrl, pk,
++ info.fpr1valid? info.fpr1 : NULL, 20);
++ if (err)
+ {
+ free_public_key (pk);
+ pk = NULL;
diff --git a/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch b/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch
new file mode 100644
index 0000000..30d21ec
--- /dev/null
+++ b/debian/patches/0021-agent-Add-const-qualifier-for-read-only-table.patch
@@ -0,0 +1,115 @@
+From: NIIBE Yutaka <gniibe at fsij.org>
+Date: Tue, 23 May 2017 06:42:44 +0900
+Subject: agent: Add const qualifier for read-only table.
+
+* agent/call-pinentry.c (start_pinentry): Add const to tbl.
+* agent/command-ssh.c (request_specs): Add const.
+(ssh_key_types): Likewise.
+(request_spec_lookup): Add const to the return value and SPEC.
+(ssh_request_process): Likewise.
+* agent/protect.c (protect_info): Add const.
+(agent_unprotect): Add const to algotable.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
+(cherry picked from commit 509e4a4d7491daf496b21e5892f4f63ab90e8e21)
+---
+ agent/call-pinentry.c | 2 +-
+ agent/command-ssh.c | 10 +++++-----
+ agent/gpg-agent.c | 2 +-
+ agent/protect.c | 4 ++--
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
+index 1ff4059..9d8e7f6 100644
+--- a/agent/call-pinentry.c
++++ b/agent/call-pinentry.c
+@@ -489,7 +489,7 @@ start_pinentry (ctrl_t ctrl)
+ {
+ /* Provide a few default strings for use by the pinentries. This
+ may help a pinentry to avoid implementing localization code. */
+- static struct { const char *key, *value; int what; } tbl[] = {
++ static const struct { const char *key, *value; int what; } tbl[] = {
+ /* TRANSLATORS: These are labels for buttons etc used in
+ Pinentries. An underscore indicates that the next letter
+ should be used as an accelerator. Double the underscore for
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 57e2e42..99c80c0 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -262,7 +262,7 @@ static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
+ /* Associating request types with the corresponding request
+ handlers. */
+
+-static ssh_request_spec_t request_specs[] =
++static const ssh_request_spec_t request_specs[] =
+ {
+ #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
+ { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
+@@ -280,7 +280,7 @@ static ssh_request_spec_t request_specs[] =
+
+
+ /* Table holding key type specifications. */
+-static ssh_key_type_spec_t ssh_key_types[] =
++static const ssh_key_type_spec_t ssh_key_types[] =
+ {
+ {
+ "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
+@@ -3376,10 +3376,10 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
+ /* Return the request specification for the request identified by TYPE
+ or NULL in case the requested request specification could not be
+ found. */
+-static ssh_request_spec_t *
++static const ssh_request_spec_t *
+ request_spec_lookup (int type)
+ {
+- ssh_request_spec_t *spec;
++ const ssh_request_spec_t *spec;
+ unsigned int i;
+
+ for (i = 0; i < DIM (request_specs); i++)
+@@ -3403,7 +3403,7 @@ request_spec_lookup (int type)
+ static int
+ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
+ {
+- ssh_request_spec_t *spec;
++ const ssh_request_spec_t *spec;
+ estream_t response = NULL;
+ estream_t request = NULL;
+ unsigned char request_type;
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 098a335..e7eef2b 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -1922,7 +1922,7 @@ agent_copy_startup_env (ctrl_t ctrl)
+ const char *value;
+
+ for (idx=0; !err && names[idx]; idx++)
+- if ((value = session_env_getenv (opt.startup_env, names[idx])))
++ if ((value = session_env_getenv (opt.startup_env, names[idx])))
+ err = session_env_setenv (ctrl->session_env, names[idx], value);
+
+ if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
+diff --git a/agent/protect.c b/agent/protect.c
+index a9de732..66c3741 100644
+--- a/agent/protect.c
++++ b/agent/protect.c
+@@ -54,7 +54,7 @@
+
+ /* A table containing the information needed to create a protected
+ private key. */
+-static struct {
++static const struct {
+ const char *algo;
+ const char *parmlist;
+ int prot_from, prot_to;
+@@ -1010,7 +1010,7 @@ agent_unprotect (ctrl_t ctrl,
+ gnupg_isotime_t protected_at,
+ unsigned char **result, size_t *resultlen)
+ {
+- static struct {
++ static const struct {
+ const char *name; /* Name of the protection method. */
+ int algo; /* (A zero indicates the "openpgp-native" hack.) */
+ int keylen; /* Used key length in bytes. */
diff --git a/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch b/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch
new file mode 100644
index 0000000..8e7c8ad
--- /dev/null
+++ b/debian/patches/0022-common-Support-different-digest-algorithms-for-ssh-f.patch
@@ -0,0 +1,224 @@
+From: Justus Winter <justus at g10code.com>
+Date: Fri, 4 Dec 2015 15:19:07 +0100
+Subject: common: Support different digest algorithms for ssh fingerprints.
+
+* common/ssh-utils.c (get_fingerprint): Add and honor 'algo' parameter.
+(ssh_get_fingerprint{,_string}): Likewise.
+* common/ssh-utils.h (ssh_get_fingerprint{,_string}): Update prototypes.
+* common/t-ssh-utils.c (main): Adapt accordingly.
+* agent/command-ssh.c (agent_raw_key_from_file): Likewise.
+(ssh_identity_register): Likewise.
+* agent/command.c (do_one_keyinfo): Likewise.
+* agent/findkey.c (modify_description): Likewise.
+--
+This lays the foundation to support other algorithms.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 3ac1a9d3a018816233a855faff059b4e0657a0f1)
+---
+ agent/command-ssh.c | 4 ++--
+ agent/command.c | 2 +-
+ agent/findkey.c | 2 +-
+ common/ssh-utils.c | 59 +++++++++++++++++++++++++++-------------------------
+ common/ssh-utils.h | 6 ++++--
+ common/t-ssh-utils.c | 4 ++--
+ 6 files changed, 41 insertions(+), 36 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 99c80c0..3dd3dd7 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -2760,7 +2760,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
+ if (err)
+ goto out;
+- err = ssh_get_fingerprint_string (key, &fpr);
++ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
+ if (!err)
+ {
+ gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
+@@ -3038,7 +3038,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+
+ bin2hex (key_grip_raw, 20, key_grip);
+
+- err = ssh_get_fingerprint_string (key, &key_fpr);
++ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &key_fpr);
+ if (err)
+ goto out;
+
+diff --git a/agent/command.c b/agent/command.c
+index df788ef..d370821 100644
+--- a/agent/command.c
++++ b/agent/command.c
+@@ -1201,7 +1201,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
+
+ if (!agent_raw_key_from_file (ctrl, grip, &key))
+ {
+- ssh_get_fingerprint_string (key, &fpr);
++ ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
+ gcry_sexp_release (key);
+ }
+ }
+diff --git a/agent/findkey.c b/agent/findkey.c
+index b24d8f1..1f547b0 100644
+--- a/agent/findkey.c
++++ b/agent/findkey.c
+@@ -412,7 +412,7 @@ agent_modify_description (const char *in, const char *comment,
+
+ case 'F': /* SSH style fingerprint. */
+ if (!ssh_fpr && key)
+- ssh_get_fingerprint_string (key, &ssh_fpr);
++ ssh_get_fingerprint_string (key, GCRY_MD_MD5, &ssh_fpr);
+ if (ssh_fpr)
+ {
+ if (out)
+diff --git a/common/ssh-utils.c b/common/ssh-utils.c
+index 60aa07b..3925602 100644
+--- a/common/ssh-utils.c
++++ b/common/ssh-utils.c
+@@ -65,12 +65,13 @@ is_eddsa (gcry_sexp_t keyparms)
+ }
+
+
+-/* Return the Secure Shell type fingerprint for KEY. The length of
+- the fingerprint is returned at R_LEN and the fingerprint itself at
+- R_FPR. In case of a error code is returned and NULL stored at
+- R_FPR. */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
++ The length of the fingerprint is returned at R_LEN and the
++ fingerprint itself at R_FPR. In case of a error code is returned
++ and NULL stored at R_FPR. */
+ static gpg_error_t
+-get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
++get_fingerprint (gcry_sexp_t key, int algo,
++ void **r_fpr, size_t *r_len, int as_string)
+ {
+ gpg_error_t err;
+ gcry_sexp_t list = NULL;
+@@ -111,7 +112,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+ goto leave;
+ }
+
+- err = gcry_md_open (&md, GCRY_MD_MD5, 0);
++ err = gcry_md_open (&md, algo, 0);
+ if (err)
+ goto leave;
+
+@@ -229,23 +230,23 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+ }
+ }
+
+- *r_fpr = gcry_malloc (as_string? 61:20);
+- if (!*r_fpr)
+- {
+- err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+- goto leave;
+- }
+-
+ if (as_string)
+ {
+- bin2hexcolon (gcry_md_read (md, GCRY_MD_MD5), 16, *r_fpr);
+- *r_len = 3*16+1;
++ *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
++ (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
++ *r_len = strlen (*r_fpr) + 1;
+ strlwr (*r_fpr);
+ }
+ else
+ {
+- memcpy (*r_fpr, gcry_md_read (md, GCRY_MD_MD5), 16);
+- *r_len = 16;
++ *r_len = gcry_md_get_algo_dlen (algo);
++ *r_fpr = xtrymalloc (*r_len);
++ if (!*r_fpr)
++ {
++ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++ goto leave;
++ }
++ memcpy (*r_fpr, gcry_md_read (md, algo), *r_len);
+ }
+ err = 0;
+
+@@ -257,28 +258,30 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+ return err;
+ }
+
+-/* Return the Secure Shell type fingerprint for KEY. The length of
+- the fingerprint is returned at R_LEN and the fingerprint itself at
+- R_FPR. In case of an error an error code is returned and NULL
+- stored at R_FPR. */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
++ The length of the fingerprint is returned at R_LEN and the
++ fingerprint itself at R_FPR. In case of an error an error code is
++ returned and NULL stored at R_FPR. */
+ gpg_error_t
+-ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len)
++ssh_get_fingerprint (gcry_sexp_t key, int algo,
++ void **r_fpr, size_t *r_len)
+ {
+- return get_fingerprint (key, r_fpr, r_len, 0);
++ return get_fingerprint (key, algo, r_fpr, r_len, 0);
+ }
+
+
+-/* Return the Secure Shell type fingerprint for KEY as a string. The
+- fingerprint is mallcoed and stored at R_FPRSTR. In case of an
+- error an error code is returned and NULL stored at R_FPRSTR. */
++/* Return the Secure Shell type fingerprint for KEY using digest ALGO
++ as a string. The fingerprint is mallcoed and stored at R_FPRSTR.
++ In case of an error an error code is returned and NULL stored at
++ R_FPRSTR. */
+ gpg_error_t
+-ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr)
++ssh_get_fingerprint_string (gcry_sexp_t key, int algo, char **r_fprstr)
+ {
+ gpg_error_t err;
+ size_t dummy;
+ void *string;
+
+- err = get_fingerprint (key, &string, &dummy, 1);
++ err = get_fingerprint (key, algo, &string, &dummy, 1);
+ *r_fprstr = string;
+ return err;
+ }
+diff --git a/common/ssh-utils.h b/common/ssh-utils.h
+index 36d38a3..53d9f55 100644
+--- a/common/ssh-utils.h
++++ b/common/ssh-utils.h
+@@ -31,9 +31,11 @@
+ #define GNUPG_COMMON_SSH_UTILS_H
+
+
+-gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len);
++gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, int algo,
++ void **r_fpr, size_t *r_len);
+
+-gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr);
++gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, int algo,
++ char **r_fprstr);
+
+
+ #endif /*GNUPG_COMMON_SSH_UTILS_H*/
+diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c
+index f63ea95..a4e948f 100644
+--- a/common/t-ssh-utils.c
++++ b/common/t-ssh-utils.c
+@@ -262,7 +262,7 @@ main (int argc, char **argv)
+ if (argc == 2)
+ {
+ key = read_key (argv[1]);
+- err = ssh_get_fingerprint_string (key, &string);
++ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+ if (err)
+ {
+ fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
+@@ -287,7 +287,7 @@ main (int argc, char **argv)
+ exit (1);
+ }
+
+- err = ssh_get_fingerprint_string (key, &string);
++ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+ gcry_sexp_release (key);
+ if (err)
+ {
diff --git a/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch b/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
new file mode 100644
index 0000000..5c99f60
--- /dev/null
+++ b/debian/patches/0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
@@ -0,0 +1,303 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:03:58 +0200
+Subject: common: Correctly render SHA256-based ssh fingerprints.
+
+* common/ssh-utils.c (dummy_realloc): New function.
+(dummy_free): Likewise.
+(get_fingerprint): Prepend the fingerprint with the name of the digest
+algorithm. Correctly render SHA256-based ssh fingerprints.
+* common/t-ssh-utils.c (sample_keys): Add SHA256 hashes for the keys.
+(main): Add an option to dump the keys to gather fingerprints, also
+print the SHA256 fingerprint for keys given as arguments, and check
+the SHA256 fingerprints of the test keys.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 3a07a69dfc87b4fff610740d3dde8e23f0d2f8bc)
+---
+ common/ssh-utils.c | 73 ++++++++++++++++++++++++++++++++++++--
+ common/t-ssh-utils.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 158 insertions(+), 14 deletions(-)
+
+diff --git a/common/ssh-utils.c b/common/ssh-utils.c
+index 3925602..38d6e8a 100644
+--- a/common/ssh-utils.c
++++ b/common/ssh-utils.c
+@@ -64,6 +64,9 @@ is_eddsa (gcry_sexp_t keyparms)
+ return result;
+ }
+
++/* Dummy functions for es_mopen. */
++static void *dummy_realloc (void *mem, size_t size) { (void) size; return mem; }
++static void dummy_free (void *mem) { (void) mem; }
+
+ /* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+ The length of the fingerprint is returned at R_LEN and the
+@@ -232,10 +235,74 @@ get_fingerprint (gcry_sexp_t key, int algo,
+
+ if (as_string)
+ {
+- *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
+- (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
++ const char *algo_name;
++ char *fpr;
++
++ /* Prefix string with the algorithm name and a colon. */
++ algo_name = gcry_md_algo_name (algo);
++ *r_fpr = xtrymalloc (strlen (algo_name) + 1 + 3 * gcry_md_get_algo_dlen (algo) + 1);
++ if (*r_fpr == NULL)
++ {
++ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++ goto leave;
++ }
++
++ strncpy (*r_fpr, algo_name, strlen (algo_name));
++ fpr = (char *) *r_fpr + strlen (algo_name);
++ *fpr++ = ':';
++
++ if (algo == GCRY_MD_MD5)
++ {
++ bin2hexcolon (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), fpr);
++ strlwr (fpr);
++ }
++ else
++ {
++ struct b64state b64s;
++ estream_t stream;
++ char *p;
++ long int len;
++
++ /* Write the base64-encoded hash to fpr. */
++ stream = es_mopen (fpr, 3 * gcry_md_get_algo_dlen (algo) + 1, 0,
++ 0, dummy_realloc, dummy_free, "w");
++ if (stream == NULL)
++ {
++ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++ goto leave;
++ }
++
++ err = b64enc_start_es (&b64s, stream, "");
++ if (err)
++ {
++ es_fclose (stream);
++ goto leave;
++ }
++
++ err = b64enc_write (&b64s,
++ gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo));
++ if (err)
++ {
++ es_fclose (stream);
++ goto leave;
++ }
++
++ /* Finish, get the length, and close the stream. */
++ err = b64enc_finish (&b64s);
++ len = es_ftell (stream);
++ es_fclose (stream);
++ if (err)
++ goto leave;
++
++ /* Terminate. */
++ fpr[len] = 0;
++
++ /* Strip the trailing padding characters. */
++ for (p = fpr + len - 1; p > fpr && *p == '='; p--)
++ *p = 0;
++ }
++
+ *r_len = strlen (*r_fpr) + 1;
+- strlwr (*r_fpr);
+ }
+ else
+ {
+diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c
+index a4e948f..1c9b87b 100644
+--- a/common/t-ssh-utils.c
++++ b/common/t-ssh-utils.c
+@@ -28,7 +28,12 @@
+ #include "ssh-utils.h"
+
+
+-static struct { const char *key; const char *fpr; } sample_keys[] = {
++static struct
++{
++ const char *key;
++ const char *fpr_md5;
++ const char *fpr_sha256;
++} sample_keys[] = {
+ { "(protected-private-key "
+ "(rsa "
+ "(n #"
+@@ -70,7 +75,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment passphrase_is_abc)"
+ ")",
+- "c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1"
++ "MD5:c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1",
++ "SHA256:ksKb4DKk2SFX56GRtpt0szBnyjiYARSb2FNlUb7snnE"
+ },
+ {
+ "(protected-private-key "
+@@ -99,7 +105,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment sample_dsa_passphrase_is_abc)"
+ ")",
+- "2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3"
++ "MD5:2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3",
++ "SHA256:z8+8HEuD/5QpegGS4tSK02dJF+a6o2V67VM2gOPz9oQ"
+ },
+ { /* OpenSSH 6.7p1 generated key: */
+ "(protected-private-key "
+@@ -118,7 +125,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment \"ecdsa w/o comment\")"
+ ")", /* Passphrase="abc" */
+- "93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19"
++ "MD5:93:4f:08:02:7d:cb:16:9b:0c:39:21:4b:cf:28:5a:19",
++ "SHA256:zSj4uXfE1hlQnESD2LO723fMGXsNwzHrfqOfqep37is"
+ },
+ { /* OpenSSH 6.7p1 generated key: */
+ "(protected-private-key "
+@@ -139,7 +147,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment \"ecdsa w/o comment\")"
+ ")", /* Passphrase="abc" */
+- "a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76"
++ "MD5:a3:cb:44:c8:56:15:25:62:85:fd:e8:04:7a:26:dc:76",
++ "SHA256:JuQh5fjduynuuTEwI9C6yAKK1NnLX9PPd7TP0qZfbGs"
+ },
+ { /* OpenSSH 6.7p1 generated key: */
+ "(protected-private-key "
+@@ -161,7 +170,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment \"ecdsa w/o comment\")"
+ ")", /* Passphrase="abc" */
+- "1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df"
++ "MD5:1e:a6:94:ab:bd:81:73:5f:22:bc:0e:c7:89:f6:68:df",
++ "SHA256:+pbRyYa2UBwDki1k4Wziu2CKrdJIbZM/hOWOQ/sNe/0"
+ },
+ { /* OpenSSH 6.7p1 generated key: */
+ "(protected-private-key "
+@@ -180,7 +190,8 @@ static struct { const char *key; const char *fpr; } sample_keys[] = {
+ ")"
+ "(comment \"eddsa w/o comment\")"
+ ")", /* Passphrase="abc" */
+- "f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e"
++ "MD5:f1:fa:c8:a6:40:bb:b9:a1:65:d7:62:65:ac:26:78:0e",
++ "SHA256:yhwBfYnTOnSXcWf1EOPo+oIIpNJ6w/bG36udZ96MmsQ"
+ },
+ {
+ NULL,
+@@ -259,9 +270,43 @@ main (int argc, char **argv)
+ char *string;
+ int idx;
+
+- if (argc == 2)
++ /* --dump-keys dumps the keys as KEYGRIP.key.IDX. Useful to compute
++ fingerprints to enhance the test vectors. */
++ if (argc == 2 && strcmp (argv[1], "--dump-keys") == 0)
++ for (idx=0; sample_keys[idx].key; idx++)
++ {
++ FILE *s;
++ char *name;
++ char grip[20];
++ char *hexgrip;
++
++ err = keygrip_from_canon_sexp (sample_keys[idx].key,
++ strlen (sample_keys[idx].key),
++ grip);
++ if (err)
++ {
++ fprintf (stderr, "%s:%d: error computing keygrip: %s\n",
++ __FILE__, __LINE__, gpg_strerror (err));
++ exit (1);
++ }
++ hexgrip = bin2hex (grip, 20, NULL);
++
++ name = xtryasprintf ("%s.key.%d", hexgrip, idx);
++ s = fopen (name, "w");
++ if (s == NULL)
++ {
++ fprintf (stderr, "%s:%d: error opening file: %s\n",
++ __FILE__, __LINE__, gpg_strerror (gpg_error_from_syserror ()));
++ exit (1);
++ }
++ xfree (name);
++ fprintf (s, "%s", sample_keys[idx].key);
++ fclose (s);
++ }
++ else if (argc == 2)
+ {
+ key = read_key (argv[1]);
++
+ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+ if (err)
+ {
+@@ -271,6 +316,17 @@ main (int argc, char **argv)
+ }
+ puts (string);
+ xfree (string);
++
++ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
++ if (err)
++ {
++ fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
++ __FILE__, __LINE__, gpg_strerror (err));
++ exit (1);
++ }
++ puts (string);
++ xfree (string);
++
+ gcry_sexp_release (key);
+ }
+ else
+@@ -288,7 +344,6 @@ main (int argc, char **argv)
+ }
+
+ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
+- gcry_sexp_release (key);
+ if (err)
+ {
+ fprintf (stderr, "%s:%d: error getting fingerprint for "
+@@ -297,16 +352,38 @@ main (int argc, char **argv)
+ exit (1);
+ }
+
+- if (strcmp (string, sample_keys[idx].fpr))
++ if (strcmp (string, sample_keys[idx].fpr_md5))
++ {
++ fprintf (stderr, "%s:%d: fingerprint mismatch for "
++ "sample key %d\n",
++ __FILE__, __LINE__, idx);
++ fprintf (stderr, "want: %s\n got: %s\n",
++ sample_keys[idx].fpr_md5, string);
++ exit (1);
++ }
++ xfree (string);
++
++ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &string);
++ if (err)
++ {
++ fprintf (stderr, "%s:%d: error getting fingerprint for "
++ "sample key %d: %s\n",
++ __FILE__, __LINE__, idx, gpg_strerror (err));
++ exit (1);
++ }
++
++ if (strcmp (string, sample_keys[idx].fpr_sha256))
+ {
+ fprintf (stderr, "%s:%d: fingerprint mismatch for "
+ "sample key %d\n",
+ __FILE__, __LINE__, idx);
+ fprintf (stderr, "want: %s\n got: %s\n",
+- sample_keys[idx].fpr, string);
++ sample_keys[idx].fpr_sha256, string);
+ exit (1);
+ }
+ xfree (string);
++
++ gcry_sexp_release (key);
+ }
+ }
+
diff --git a/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch b/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
new file mode 100644
index 0000000..9e08e72
--- /dev/null
+++ b/debian/patches/0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
@@ -0,0 +1,79 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:29:31 +0200
+Subject: agent: Write both ssh fingerprints to 'sshcontrol' file.
+
+* agent/command-ssh.c (add_control_entry): Hand in the key, write both
+the MD5- and the SHA256-based fingerprint to the 'sshcontrol' file
+when adding ssh keys.
+(ssh_identity_register): Adapt callsite.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit a5f046d99a084b6a95268f03c1b588e8b78083cb)
+---
+ agent/command-ssh.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index 3dd3dd7..b8edd1a 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -1040,12 +1040,14 @@ search_control_file (ssh_control_file_t cf, const char *hexgrip,
+ We can assume that the user wants to allow ssh using this key. */
+ static gpg_error_t
+ add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+- const char *hexgrip, const char *fmtfpr,
++ const char *hexgrip, gcry_sexp_t key,
+ int ttl, int confirm)
+ {
+ gpg_error_t err;
+ ssh_control_file_t cf;
+ int disabled;
++ char *fpr_md5 = NULL;
++ char *fpr_sha256 = NULL;
+
+ (void)ctrl;
+
+@@ -1059,19 +1061,31 @@ add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ struct tm *tp;
+ time_t atime = time (NULL);
+
++ err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr_md5);
++ if (err)
++ goto out;
++
++ err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &fpr_sha256);
++ if (err)
++ goto out;
++
+ /* Not yet in the file - add it. Because the file has been
+ opened in append mode, we simply need to write to it. */
+ tp = localtime (&atime);
+ fprintf (cf->fp,
+ ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
+- "# MD5 Fingerprint: %s\n"
++ "# Fingerprints: %s\n"
++ "# %s\n"
+ "%s %d%s\n"),
+ spec->name,
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+ tp->tm_hour, tp->tm_min, tp->tm_sec,
+- fmtfpr, hexgrip, ttl, confirm? " confirm":"");
++ fpr_md5, fpr_sha256, hexgrip, ttl, confirm? " confirm":"");
+
+ }
++ out:
++ xfree (fpr_md5);
++ xfree (fpr_sha256);
+ close_control_file (cf);
+ return 0;
+ }
+@@ -3118,7 +3132,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+
+ key_exists:
+ /* And add an entry to the sshcontrol file. */
+- err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
++ err = add_control_entry (ctrl, spec, key_grip, key, ttl, confirm);
+
+
+ out:
diff --git a/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch b/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
new file mode 100644
index 0000000..e6307a4
--- /dev/null
+++ b/debian/patches/0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
@@ -0,0 +1,141 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 24 May 2017 17:48:42 +0200
+Subject: agent: Make digest algorithms for ssh fingerprints configurable.
+
+* agent/agent.h (opt): New field 'ssh_fingerprint_digest'.
+* agent/command-ssh.c (data_sign, ssh_identity_register): Honor the
+option for strings used to communicate with the user.
+* agent/findkey.c (agent_modify_description): Likewise.
+* agent/gpg-agent.c (cmd_and_opt_values): New value.
+(opts): New option '--ssh-fingerprint-digest'.
+(parse_rereadable_options): Set the default to MD5 for now.
+(main): Handle the new option.
+* doc/gpg-agent.texi: Document the new option.
+--
+
+OpenSSH has transitioned from using MD5 to compute key fingerprints to
+SHA256. This patch makes the digest used when communicating key
+fingerprints to the user (e.g. in pinentry dialogs) configurable.
+For now this patch conservatively defaults to MD5.
+
+GnuPG-bug-id: 2106
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 525f2c482abb6bc2002eb878b03558fb43e6b004)
+---
+ agent/agent.h | 4 ++++
+ agent/command-ssh.c | 4 ++--
+ agent/findkey.c | 3 ++-
+ agent/gpg-agent.c | 9 +++++++++
+ doc/gpg-agent.texi | 7 +++++++
+ 5 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/agent/agent.h b/agent/agent.h
+index fadc8e8..0fa4e1b 100644
+--- a/agent/agent.h
++++ b/agent/agent.h
+@@ -167,6 +167,10 @@ struct
+ gpg-agent.c: If the value is less than 2 the name has not yet
+ been malloced. */
+ int browser_socket;
++
++ /* The digest algorithm to use for ssh fingerprints when
++ * communicating with the user. */
++ int ssh_fingerprint_digest;
+ } opt;
+
+
+diff --git a/agent/command-ssh.c b/agent/command-ssh.c
+index b8edd1a..e450aed 100644
+--- a/agent/command-ssh.c
++++ b/agent/command-ssh.c
+@@ -2774,7 +2774,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+ err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
+ if (err)
+ goto out;
+- err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
++ err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &fpr);
+ if (!err)
+ {
+ gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
+@@ -3052,7 +3052,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
+
+ bin2hex (key_grip_raw, 20, key_grip);
+
+- err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &key_fpr);
++ err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &key_fpr);
+ if (err)
+ goto out;
+
+diff --git a/agent/findkey.c b/agent/findkey.c
+index 1f547b0..cff0a7d 100644
+--- a/agent/findkey.c
++++ b/agent/findkey.c
+@@ -412,7 +412,8 @@ agent_modify_description (const char *in, const char *comment,
+
+ case 'F': /* SSH style fingerprint. */
+ if (!ssh_fpr && key)
+- ssh_get_fingerprint_string (key, GCRY_MD_MD5, &ssh_fpr);
++ ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest,
++ &ssh_fpr);
+ if (ssh_fpr)
+ {
+ if (out)
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index e7eef2b..d522f18 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -132,6 +132,7 @@ enum cmd_and_opt_values
+ oKeepTTY,
+ oKeepDISPLAY,
+ oSSHSupport,
++ oSSHFingerprintDigest,
+ oPuttySupport,
+ oDisableScdaemon,
+ oDisableCheckOwnSocket,
+@@ -235,6 +236,8 @@ static ARGPARSE_OPTS opts[] = {
+ /* */ N_("allow passphrase to be prompted through Emacs")),
+
+ ARGPARSE_s_n (oSSHSupport, "enable-ssh-support", N_("enable ssh support")),
++ ARGPARSE_s_s (oSSHFingerprintDigest, "ssh-fingerprint-digest",
++ N_("digest to use when communicating ssh fingerprints")),
+ ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
+ #ifdef HAVE_W32_SYSTEM
+ /* */ N_("enable putty support")
+@@ -806,6 +809,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+ opt.allow_emacs_pinentry = 0;
+ opt.disable_scdaemon = 0;
+ disable_check_own_socket = 0;
++ opt.ssh_fingerprint_digest = GCRY_MD_MD5;
+ return 1;
+ }
+
+@@ -1187,6 +1191,11 @@ main (int argc, char **argv )
+ case oSSHSupport:
+ ssh_support = 1;
+ break;
++ case oSSHFingerprintDigest:
++ opt.ssh_fingerprint_digest = gcry_md_map_name (pargs.r.ret_str);
++ if (opt.ssh_fingerprint_digest == 0)
++ log_error ("Unknown digest algorithm: %s\n", pargs.r.ret_str);
++ break;
+ case oPuttySupport:
+ # ifdef HAVE_W32_SYSTEM
+ putty_support = 1;
+diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
+index 6ed0ff8..d61dc85 100644
+--- a/doc/gpg-agent.texi
++++ b/doc/gpg-agent.texi
+@@ -636,6 +636,13 @@ and allows the use of gpg-agent with the ssh implementation
+ @command{putty}. This is similar to the regular ssh-agent support but
+ makes use of Windows message queue as required by @command{putty}.
+
++ at anchor{option --ssh-fingerprint-digest}
++ at item --ssh-fingerprint-digest
++ at opindex ssh-fingerprint-digest
++
++Select the digest algorithm used to compute ssh fingerprints that are
++communicated to the user, e.g. in pinentry dialogs. OpenSSH has
++transitioned from using MD5 to the more secure SHA256.
+
+ @end table
+
diff --git a/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch b/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
new file mode 100644
index 0000000..6f9b332
--- /dev/null
+++ b/debian/patches/0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
@@ -0,0 +1,110 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 25 May 2017 11:33:07 +0200
+Subject: dirmngr: Re-init libdns resolver on towel change of resolv.conf
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+* dirmngr/dns-stuff.c: Include sys/stat.h.
+(RESOLV_CONF_NAME): New macro to replace a string.
+(resolv_conf_changed_p): New.
+(libdns_init): Call new function
+(libdns_res_open): Ditto.
+--
+
+Don't panic. This is a simple change
+Suggested-by: Stefan Bühler <stbuehler at web.de>
+to avoid complicated if-up.d hooks to reload resolv.conf.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit b5f356e9fba2d99909f8f54d7b7e6836bed87b68)
+---
+ dirmngr/dns-stuff.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index a6c14cd..a8ddbc6 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -45,6 +45,9 @@
+ # endif
+ # include <netdb.h>
+ #endif
++#ifdef HAVE_STAT
++# include <sys/stat.h>
++#endif
+ #include <string.h>
+ #include <unistd.h>
+
+@@ -111,6 +114,8 @@
+ #define DEFAULT_TIMEOUT 30
+
+
++#define RESOLV_CONF_NAME "/etc/resolv.conf"
++
+ /* Two flags to enable verbose and debug mode. */
+ static int opt_verbose;
+ static int opt_debug;
+@@ -391,6 +396,37 @@ libdns_error_to_gpg_error (int serr)
+ #endif /*USE_LIBDNS*/
+
+
++/* Return true if resolve.conf changed since it was last loaded. */
++#ifdef USE_LIBDNS
++static int
++resolv_conf_changed_p (void)
++{
++#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
++ return 0;
++#else
++ static time_t last_mtime;
++ const char *fname = RESOLV_CONF_NAME;
++ struct stat statbuf;
++ int changed;
++
++ if (stat (fname, &statbuf))
++ {
++ log_error ("stat'ing '%s' failed: %s\n",
++ fname, gpg_strerror (gpg_error_from_syserror ()));
++ changed = 0;
++ last_mtime = 1; /* Force a "changed" result the next time stat
++ * works. */
++ }
++ else
++ {
++ changed = last_mtime && (last_mtime != statbuf.st_mtime);
++ last_mtime = statbuf.st_mtime;
++ }
++ return changed;
++#endif
++}
++#endif /*USE_LIBDNS*/
++
+ #ifdef USE_LIBDNS
+ /* Initialize libdns. Returns 0 on success; prints a diagnostic and
+ * returns an error code on failure. */
+@@ -496,7 +532,8 @@ libdns_init (void)
+ #else /* Unix */
+ const char *fname;
+
+- fname = "/etc/resolv.conf";
++ fname = RESOLV_CONF_NAME;
++ resolv_conf_changed_p (); /* Reset timestamp. */
+ err = libdns_error_to_gpg_error
+ (dns_resconf_loadpath (ld.resolv_conf, fname));
+ if (err)
+@@ -653,6 +690,14 @@ libdns_res_open (struct dns_resolver **r_res)
+
+ *r_res = NULL;
+
++ /* Force a reload if resolv.conf has changed. */
++ if (resolv_conf_changed_p ())
++ {
++ if (opt_debug)
++ log_debug ("dns: resolv.conf changed - forcing reload\n");
++ libdns_reinit_pending = 1;
++ }
++
+ if (libdns_reinit_pending)
+ {
+ libdns_reinit_pending = 0;
diff --git a/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch b/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch
new file mode 100644
index 0000000..d38e30b
--- /dev/null
+++ b/debian/patches/0027-dirmngr-This-towel-should-better-detect-a-changed-re.patch
@@ -0,0 +1,47 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Thu, 25 May 2017 20:26:54 +0200
+Subject: dirmngr: This towel should better detect a changed resolv.conf.
+
+* dirmngr/dns-stuff.c (resolv_conf_changed_p): Fix initialization time
+issue.
+--
+
+Fixes-commit: b5f356e9fba2d99909f8f54d7b7e6836bed87b68
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit de3a0988ef9addccd6b5c7950fb8797afbc3978d)
+---
+ dirmngr/dns-stuff.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index a8ddbc6..7324aae 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -407,21 +407,23 @@ resolv_conf_changed_p (void)
+ static time_t last_mtime;
+ const char *fname = RESOLV_CONF_NAME;
+ struct stat statbuf;
+- int changed;
++ int changed = 0;
+
+ if (stat (fname, &statbuf))
+ {
+ log_error ("stat'ing '%s' failed: %s\n",
+ fname, gpg_strerror (gpg_error_from_syserror ()));
+- changed = 0;
+ last_mtime = 1; /* Force a "changed" result the next time stat
+ * works. */
+ }
+- else
++ else if (!last_mtime)
++ last_mtime = statbuf.st_mtime;
++ else if (last_mtime != statbuf.st_mtime)
+ {
+- changed = last_mtime && (last_mtime != statbuf.st_mtime);
++ changed = 1;
+ last_mtime = statbuf.st_mtime;
+ }
++
+ return changed;
+ #endif
+ }
diff --git a/debian/patches/series b/debian/patches/series
index ff2555e..de9346c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,3 +17,11 @@ skip-missing-signing-keys/0013-g10-Skip-signing-keys-where-no-secret-key-is-avai
0017-gpgscm-Fix-checking-for-opcode-arguments.patch
0018-docs-Point-to-https-dev.gnupg.org.patch
0019-doc-Fix-spellings.patch
+0020-g10-Fix-default-key-selection-for-signing-possibly-b.patch
+0021-agent-Add-const-qualifier-for-read-only-table.patch
+0022-common-Support-different-digest-algorithms-for-ssh-f.patch
+0023-common-Correctly-render-SHA256-based-ssh-fingerprint.patch
+0024-agent-Write-both-ssh-fingerprints-to-sshcontrol-file.patch
+0025-agent-Make-digest-algorithms-for-ssh-fingerprints-co.patch
+0026-dirmngr-Re-init-libdns-resolver-on-towel-change-of-r.patch
+0027-dirmngr-This-towel-should-better-detect-a-changed-re.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