aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2017-10-27 11:56:15 +0000
committerWerner Koch <[email protected]>2017-10-27 11:56:15 +0000
commitf6ab97fd9620bb8f512ffb471a66e5f96098a7cc (patch)
tree99db33d56ef4f0c05f1d6af6ec7ffaffd9547e1b
parentagent: Clean up pinentry access locking. (diff)
parentagent, tests: Support --disable-scdaemon build case. (diff)
downloadgnupg-f6ab97fd9620bb8f512ffb471a66e5f96098a7cc.tar.gz
gnupg-f6ab97fd9620bb8f512ffb471a66e5f96098a7cc.zip
Merge branch 'STABLE-BRANCH-2-2' into master
-- Resolved Conflicts: configure.ac - Adjust due to new log_clock otions
-rw-r--r--configure.ac20
-rw-r--r--dirmngr/ks-engine-http.c10
-rw-r--r--doc/gpg.texi3
-rw-r--r--doc/gpgv.texi2
-rw-r--r--g10/import.c5
-rw-r--r--g10/key-check.c143
-rw-r--r--g10/keyedit.c100
-rw-r--r--g10/keygen.c3
-rw-r--r--g10/trust.c20
-rw-r--r--sm/call-dirmngr.c4
-rw-r--r--sm/certlist.c40
-rw-r--r--sm/gpgsm.c2
-rw-r--r--sm/gpgsm.h2
-rw-r--r--sm/server.c2
-rw-r--r--tools/gpgconf-comp.c17
15 files changed, 253 insertions, 120 deletions
diff --git a/configure.ac b/configure.ac
index 22f082ed9..ebd0c2f07 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,12 +89,6 @@ AB_INIT
AC_GNU_SOURCE
-# Before we do anything with the C compiler, we first save the user's
-# CFLAGS (they are restored at the end of the configure script). This
-# is because some configure checks don't work with -Werror, but we'd
-# like to use -Werror with our build.
-CFLAGS_orig=$CFLAGS
-CFLAGS=
# Some status variables.
have_gpg_error=no
@@ -1693,6 +1687,15 @@ if test "$enable_log_clock" = yes ; then
AC_DEFINE(ENABLE_LOG_CLOCK,1,[Defined to use log_clock timestamps])
fi
+# Add -Werror to CFLAGS. This hack can be used to avoid problems with
+# misbehaving autoconf tests in case the user supplied -Werror.
+#
+AC_ARG_ENABLE(werror,
+ AC_HELP_STRING([--enable-werror],
+ [append -Werror to CFLAGS]),
+ [if test $enableval = yes ; then
+ CFLAGS="$CFLAGS -Werror"
+ fi])
#
# Configure option --enable-all-tests
@@ -1724,11 +1727,6 @@ if test x"$gnupg_builddir_envvar" = x"yes"; then
fi
#
-# Add user CFLAGS.
-#
-CFLAGS="$CFLAGS $CFLAGS_orig"
-
-#
# Decide what to build
#
diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
index 7fb77312d..6492dda8a 100644
--- a/dirmngr/ks-engine-http.c
+++ b/dirmngr/ks-engine-http.c
@@ -73,12 +73,13 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
estream_t fp = NULL;
char *request_buffer = NULL;
parsed_uri_t uri = NULL;
- int is_onion;
+ int is_onion, is_https;
err = http_parse_uri (&uri, url, 0);
if (err)
goto leave;
is_onion = uri->onion;
+ is_https = uri->use_tls;
once_more:
/* Note that we only use the system provided certificates with the
@@ -152,17 +153,18 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
url, s?s:"[none]", http_get_status_code (http));
if (s && *s && redirects_left-- )
{
- if (is_onion)
+ if (is_onion || is_https)
{
/* Make sure that an onion address only redirects to
- * another onion address. */
+ * another onion address, or that a https address
+ * only redirects to a https address. */
http_release_parsed_uri (uri);
uri = NULL;
err = http_parse_uri (&uri, s, 0);
if (err)
goto leave;
- if (! uri->onion)
+ if ((is_onion && ! uri->onion) || (is_https && ! uri->use_tls))
{
err = gpg_error (GPG_ERR_FORBIDDEN);
goto leave;
diff --git a/doc/gpg.texi b/doc/gpg.texi
index b14cb371b..bd45b0422 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2306,7 +2306,8 @@ opposite meaning. The options are:
Show a listing of the key as imported right before it is stored.
This can be combined with the option @option{--dry-run} to only look
at keys; the option @option{show-only} is a shortcut for this
- combination.
+ combination. Note that suffixes like '#' for "sec" and "sbb" lines
+ may or may not be printed.
@item import-export
Run the entire import code but instead of storing the key to the
diff --git a/doc/gpgv.texi b/doc/gpgv.texi
index 5336c98db..a05286171 100644
--- a/doc/gpgv.texi
+++ b/doc/gpgv.texi
@@ -187,6 +187,6 @@ The default keyring with the allowed keys.
@end table
@mansect see also
-@command{gpg2}(1)
+@command{gpg}(1)
@include see-also-note.texi
diff --git a/g10/import.c b/g10/import.c
index 8dd6b501e..71e39557c 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1778,7 +1778,7 @@ import_one (ctrl_t ctrl,
merge_keys_done = 1;
/* Note that we do not want to show the validity because the key
* has not yet imported. */
- list_keyblock_direct (ctrl, keyblock, 0, 0,
+ list_keyblock_direct (ctrl, keyblock, from_sk, 0,
opt.fingerprint || opt.with_fingerprint, 1);
es_fflush (es_stdout);
}
@@ -2532,7 +2532,8 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
/* At least we cancel the secret key import when the public key
import was skipped due to MERGE_ONLY option and a new
key. */
- if (stats->skipped_new_keys <= nr_prev)
+ if (!(opt.dry_run || (options & IMPORT_DRY_RUN))
+ && stats->skipped_new_keys <= nr_prev)
{
/* Read the keyblock again to get the effects of a merge. */
/* Fixme: we should do this based on the fingerprint or
diff --git a/g10/key-check.c b/g10/key-check.c
index d32067b99..86b1e769d 100644
--- a/g10/key-check.c
+++ b/g10/key-check.c
@@ -32,6 +32,27 @@
#include "key-check.h"
+
+/* Print PREFIX followed by TEXT. With mode > 0 use log_info, with
+ * mode < 0 use ttyio, else print to stdout. If TEXT is not NULL, it
+ * may be modified by this function. */
+static void
+print_info (int mode, const char *prefix, char *text)
+{
+ char *p;
+
+ if (!text)
+ text = "";
+ else if ((p = strchr (text,'\n')))
+ *p = 0; /* Strip LF. */
+
+ if (mode > 0)
+ log_info ("%s %s\n", prefix, text);
+ else
+ tty_fprintf (mode? NULL:es_stdout, "%s %s\n", prefix, text);
+}
+
+
/* Order two signatures. The actual ordering isn't important. Our
* goal is to ensure that identical signatures occur together. */
static int
@@ -100,7 +121,6 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
int only_selected, int only_selfsigs)
{
gpg_error_t err;
- estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
PKT_public_key *pk;
KBNODE n, n_next, *n_prevp, n2;
char *pending_desc = NULL;
@@ -476,8 +496,9 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
has_selfsig = 1;
}
- if ((n2 && n2 != last_printed_component)
- || (! n2 && last_printed_component != current_component))
+ if (DBG_PACKET
+ && ((n2 && n2 != last_printed_component)
+ || (! n2 && last_printed_component != current_component)))
{
int is_reordered = n2 && n2 != current_component;
if (n2)
@@ -489,36 +510,34 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
;
else if (last_printed_component->pkt->pkttype == PKT_USER_ID)
{
- tty_fprintf (fp, "uid ");
- tty_print_utf8_string2 (fp,
- last_printed_component
- ->pkt->pkt.user_id->name,
- last_printed_component
- ->pkt->pkt.user_id->len, 0);
+ log_debug ("uid ");
+ print_utf8_buffer (log_get_stream (),
+ last_printed_component
+ ->pkt->pkt.user_id->name,
+ last_printed_component
+ ->pkt->pkt.user_id->len);
+ log_flush ();
}
else if (last_printed_component->pkt->pkttype
== PKT_PUBLIC_KEY)
- tty_fprintf (fp, "pub %s",
- pk_keyid_str (last_printed_component
+ log_debug ("pub %s\n",
+ pk_keyid_str (last_printed_component
->pkt->pkt.public_key));
else
- tty_fprintf (fp, "sub %s",
- pk_keyid_str (last_printed_component
- ->pkt->pkt.public_key));
+ log_debug ("sub %s\n",
+ pk_keyid_str (last_printed_component
+ ->pkt->pkt.public_key));
if (modified)
{
if (is_reordered)
- tty_fprintf (fp, _(" (reordered signatures follow)"));
- if (mode > 0)
- log_printf ("\n");
- else
- tty_fprintf (fp, "\n");
+ log_debug ("%s\n", _(" (reordered signatures follow)"));
}
}
- if (modified)
- keyedit_print_one_sig (ctrl, fp, rc, kb, n, NULL, NULL, NULL,
+ if (DBG_PACKET && modified)
+ keyedit_print_one_sig (ctrl, log_get_stream (),
+ rc, kb, n, NULL, NULL, NULL,
has_selfsig, 0, only_selfsigs);
}
@@ -624,32 +643,62 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
}
}
- if (dups || missing_issuer || bad_signature || reordered)
- tty_fprintf (fp, _("key %s:\n"), pk_keyid_str (pk));
-
- if (dups)
- tty_fprintf (fp,
- ngettext ("%d duplicate signature removed\n",
- "%d duplicate signatures removed\n", dups), dups);
- if (missing_issuer)
- tty_fprintf (fp,
- ngettext ("%d signature not checked due to a missing key\n",
- "%d signatures not checked due to missing keys\n",
- missing_issuer), missing_issuer);
- if (bad_signature)
- tty_fprintf (fp,
- ngettext ("%d bad signature\n",
- "%d bad signatures\n",
- bad_signature), bad_signature);
- if (reordered)
- tty_fprintf (fp,
- ngettext ("%d signature reordered\n",
- "%d signatures reordered\n",
- reordered), reordered);
-
- if (only_selfsigs && (bad_signature || reordered))
- tty_fprintf (fp, _("Warning: errors found and only checked self-signatures,"
- " run '%s' to check all signatures.\n"), "check");
+ if (!opt.quiet)
+ {
+ char prefix[100];
+ char *p;
+
+ /* To avoid string changes in 2.2 we strip the LF here. */
+ snprintf (prefix, sizeof prefix, _("key %s:\n"), pk_keyid_str (pk));
+ p = strrchr (prefix, '\n');
+ if (p)
+ *p = 0;
+
+ if (dups)
+ {
+ p = xtryasprintf
+ (ngettext ("%d duplicate signature removed\n",
+ "%d duplicate signatures removed\n", dups), dups);
+ print_info (mode, prefix, p);
+ xfree (p);
+ }
+
+ if (missing_issuer)
+ {
+ p = xtryasprintf
+ (ngettext ("%d signature not checked due to a missing key\n",
+ "%d signatures not checked due to missing keys\n",
+ missing_issuer), missing_issuer);
+ print_info (mode, prefix, p);
+ xfree (p);
+ }
+ if (bad_signature)
+ {
+ p = xtryasprintf (ngettext ("%d bad signature\n",
+ "%d bad signatures\n",
+ bad_signature), bad_signature);
+ print_info (mode, prefix, p);
+ xfree (p);
+ }
+
+ if (reordered)
+ {
+ p = xtryasprintf (ngettext ("%d signature reordered\n",
+ "%d signatures reordered\n",
+ reordered), reordered);
+ print_info (mode, prefix, p);
+ xfree (p);
+ }
+
+ if (only_selfsigs && (bad_signature || reordered))
+ {
+ p = xtryasprintf
+ (_("Warning: errors found and only checked self-signatures,"
+ " run '%s' to check all signatures.\n"), "check");
+ print_info (mode, prefix, p);
+ xfree (p);
+ }
+ }
return modified;
}
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 38cdbce3a..4acb2de5f 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1223,10 +1223,8 @@ parse_sign_type (const char *str, int *localsig, int *nonrevokesig,
/* Need an SK for this command */
#define KEYEDIT_NEED_SK 1
-/* Cannot be viewing the SK for this command */
-#define KEYEDIT_NOT_SK 2
-/* Must be viewing the SK for this command */
-#define KEYEDIT_ONLY_SK 4
+/* Need an SUB KEY for this command */
+#define KEYEDIT_NEED_SUBSK 2
/* Match the tail of the string */
#define KEYEDIT_TAIL_MATCH 8
@@ -1268,12 +1266,12 @@ static struct
{ "key", cmdSELKEY, 0, N_("select subkey N")},
{ "check", cmdCHECK, 0, N_("check signatures")},
{ "c", cmdCHECK, 0, NULL},
- { "change-usage", cmdCHANGEUSAGE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
- { "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
- { "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
- { "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH,
+ { "change-usage", cmdCHANGEUSAGE, KEYEDIT_NEED_SK, NULL},
+ { "cross-certify", cmdBACKSIGN, KEYEDIT_NEED_SK, NULL},
+ { "backsign", cmdBACKSIGN, KEYEDIT_NEED_SK, NULL},
+ { "sign", cmdSIGN, KEYEDIT_TAIL_MATCH,
N_("sign selected user IDs [* see below for related commands]")},
- { "s", cmdSIGN, KEYEDIT_NOT_SK, NULL},
+ { "s", cmdSIGN, 0, NULL},
/* "lsign" and friends will never match since "sign" comes first
and it is a tail match. They are just here so they show up in
the help menu. */
@@ -1282,62 +1280,62 @@ static struct
{ "nrsign", cmdNOP, 0,
N_("sign selected user IDs with a non-revocable signature")},
{ "debug", cmdDEBUG, 0, NULL},
- { "adduid", cmdADDUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a user ID")},
- { "addphoto", cmdADDPHOTO, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "adduid", cmdADDUID, KEYEDIT_NEED_SK, N_("add a user ID")},
+ { "addphoto", cmdADDPHOTO, KEYEDIT_NEED_SK,
N_("add a photo ID")},
- { "deluid", cmdDELUID, KEYEDIT_NOT_SK, N_("delete selected user IDs")},
+ { "deluid", cmdDELUID, 0, N_("delete selected user IDs")},
/* delphoto is really deluid in disguise */
- { "delphoto", cmdDELUID, KEYEDIT_NOT_SK, NULL},
- { "addkey", cmdADDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a subkey")},
+ { "delphoto", cmdDELUID, 0, NULL},
+ { "addkey", cmdADDKEY, KEYEDIT_NEED_SK, N_("add a subkey")},
#ifdef ENABLE_CARD_SUPPORT
- { "addcardkey", cmdADDCARDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "addcardkey", cmdADDCARDKEY, KEYEDIT_NEED_SK,
N_("add a key to a smartcard")},
- { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
+ { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("move a key to a smartcard")},
- { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
+ { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("move a backup key to a smartcard")},
#endif /*ENABLE_CARD_SUPPORT */
- { "delkey", cmdDELKEY, KEYEDIT_NOT_SK, N_("delete selected subkeys")},
- { "addrevoker", cmdADDREVOKER, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "delkey", cmdDELKEY, 0, N_("delete selected subkeys")},
+ { "addrevoker", cmdADDREVOKER, KEYEDIT_NEED_SK,
N_("add a revocation key")},
- { "delsig", cmdDELSIG, KEYEDIT_NOT_SK,
+ { "delsig", cmdDELSIG, 0,
N_("delete signatures from the selected user IDs")},
- { "expire", cmdEXPIRE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "expire", cmdEXPIRE, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("change the expiration date for the key or selected subkeys")},
- { "primary", cmdPRIMARY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "primary", cmdPRIMARY, KEYEDIT_NEED_SK,
N_("flag the selected user ID as primary")},
{ "toggle", cmdTOGGLE, KEYEDIT_NEED_SK, NULL}, /* Dummy command. */
{ "t", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},
- { "pref", cmdPREF, KEYEDIT_NOT_SK, N_("list preferences (expert)")},
- { "showpref", cmdSHOWPREF, KEYEDIT_NOT_SK, N_("list preferences (verbose)")},
- { "setpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "pref", cmdPREF, 0, N_("list preferences (expert)")},
+ { "showpref", cmdSHOWPREF, 0, N_("list preferences (verbose)")},
+ { "setpref", cmdSETPREF, KEYEDIT_NEED_SK,
N_("set preference list for the selected user IDs")},
- { "updpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
- { "keyserver", cmdPREFKS, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "updpref", cmdSETPREF, KEYEDIT_NEED_SK, NULL},
+ { "keyserver", cmdPREFKS, KEYEDIT_NEED_SK,
N_("set the preferred keyserver URL for the selected user IDs")},
- { "notation", cmdNOTATION, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "notation", cmdNOTATION, KEYEDIT_NEED_SK,
N_("set a notation for the selected user IDs")},
- { "passwd", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "passwd", cmdPASSWD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("change the passphrase")},
- { "password", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+ { "password", cmdPASSWD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK, NULL},
#ifndef NO_TRUST_MODELS
- { "trust", cmdTRUST, KEYEDIT_NOT_SK, N_("change the ownertrust")},
+ { "trust", cmdTRUST, 0, N_("change the ownertrust")},
#endif /*!NO_TRUST_MODELS*/
- { "revsig", cmdREVSIG, KEYEDIT_NOT_SK,
+ { "revsig", cmdREVSIG, 0,
N_("revoke signatures on the selected user IDs")},
- { "revuid", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "revuid", cmdREVUID, KEYEDIT_NEED_SK,
N_("revoke selected user IDs")},
- { "revphoto", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
- { "revkey", cmdREVKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
+ { "revphoto", cmdREVUID, KEYEDIT_NEED_SK, NULL},
+ { "revkey", cmdREVKEY, KEYEDIT_NEED_SK,
N_("revoke key or selected subkeys")},
#ifndef NO_TRUST_MODELS
- { "enable", cmdENABLEKEY, KEYEDIT_NOT_SK, N_("enable key")},
- { "disable", cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key")},
+ { "enable", cmdENABLEKEY, 0, N_("enable key")},
+ { "disable", cmdDISABLEKEY, 0, N_("disable key")},
#endif /*!NO_TRUST_MODELS*/
{ "showphoto", cmdSHOWPHOTO, 0, N_("show selected photo IDs")},
- { "clean", cmdCLEAN, KEYEDIT_NOT_SK,
+ { "clean", cmdCLEAN, 0,
N_("compact unusable user IDs and remove unusable signatures from key")},
- { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
+ { "minimize", cmdMINIMIZE, 0,
N_("compact unusable user IDs and remove all signatures from key")},
{ NULL, cmdNONE, 0, NULL}
@@ -1406,6 +1404,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
KBNODE keyblock = NULL;
KEYDB_HANDLE kdbhd = NULL;
int have_seckey = 0;
+ int have_anyseckey = 0;
char *answer = NULL;
int redisplay = 1;
int modified = 0;
@@ -1448,9 +1447,18 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
/* See whether we have a matching secret key. */
if (seckey_check)
{
- have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
+ have_anyseckey = !agent_probe_any_secret_key (ctrl, keyblock);
+ if (have_anyseckey
+ && !agent_probe_secret_key (ctrl, keyblock->pkt->pkt.public_key))
+ {
+ /* The primary key is also available. */
+ have_seckey = 1;
+ }
+
if (have_seckey && !quiet)
- tty_printf (_("Secret key is available.\n"));
+ tty_printf (_("Secret key is available.\n"));
+ else if (have_anyseckey && !quiet)
+ tty_printf (_("Secret subkeys are available.\n"));
}
/* Main command loop. */
@@ -1548,12 +1556,14 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
else if (!ascii_strcasecmp (answer, cmds[i].name))
break;
}
- if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
+ if ((cmds[i].flags & (KEYEDIT_NEED_SK|KEYEDIT_NEED_SUBSK))
+ && !(((cmds[i].flags & KEYEDIT_NEED_SK) && have_seckey)
+ || ((cmds[i].flags & KEYEDIT_NEED_SUBSK) && have_anyseckey)))
{
tty_printf (_("Need the secret key to do this.\n"));
cmd = cmdNOP;
}
- else
+ else
cmd = cmds[i].id;
}
@@ -1563,7 +1573,9 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
case cmdHELP:
for (i = 0; cmds[i].name; i++)
{
- if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
+ if ((cmds[i].flags & (KEYEDIT_NEED_SK|KEYEDIT_NEED_SUBSK))
+ && !(((cmds[i].flags & KEYEDIT_NEED_SK) && have_seckey)
+ ||((cmds[i].flags&KEYEDIT_NEED_SUBSK)&&have_anyseckey)))
; /* Skip those item if we do not have the secret key. */
else if (cmds[i].desc)
tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc));
diff --git a/g10/keygen.c b/g10/keygen.c
index e959ee901..1dddfeeda 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -5050,6 +5050,9 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
err = agent_passwd (ctrl, hexgrip, desc, 1 /*=verify*/,
&cache_nonce, &passwd_nonce);
xfree (desc);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED
+ && gpg_err_source (err) == GPG_ERR_SOURCE_GPGAGENT)
+ err = 0; /* Very likely that the key is on a card. */
if (err)
goto leave;
}
diff --git a/g10/trust.c b/g10/trust.c
index ee6078b5a..6d4f0e74b 100644
--- a/g10/trust.c
+++ b/g10/trust.c
@@ -66,6 +66,26 @@ register_trusted_key (const char *string)
#ifdef NO_TRUST_MODELS
(void)string;
#else
+
+ /* Some users have conf files with entries like
+ * trusted-key 0x1234567812345678 # foo
+ * That is obviously wrong. Before fixing bug#1206 trailing garbage
+ * on a key specification if was ignored. We detect the above use case
+ * here and cut off the junk-looking-like-a comment. */
+ if (strchr (string, '#'))
+ {
+ char *buf;
+
+ buf = xtrystrdup (string);
+ if (buf)
+ {
+ *strchr (buf, '#') = 0;
+ tdb_register_trusted_key (buf);
+ xfree (buf);
+ return;
+ }
+ }
+
tdb_register_trusted_key (string);
#endif
}
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 930194076..e94311892 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -415,7 +415,7 @@ inq_certificate (void *opaque, const char *line)
ksba_cert_t cert;
- err = gpgsm_find_cert (parm->ctrl, line, ski, &cert);
+ err = gpgsm_find_cert (parm->ctrl, line, ski, &cert, 1);
if (err)
{
log_error ("certificate not found: %s\n", gpg_strerror (err));
@@ -936,7 +936,7 @@ run_command_inq_cb (void *opaque, const char *line)
if (!*line)
return gpg_error (GPG_ERR_ASS_PARAMETER);
- err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert);
+ err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert, 1);
if (err)
{
log_error ("certificate not found: %s\n", gpg_strerror (err));
diff --git a/sm/certlist.c b/sm/certlist.c
index 39ab03c5d..c9e275e9d 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -489,7 +489,8 @@ gpgsm_release_certlist (certlist_t list)
subjectKeyIdentifier. */
int
gpgsm_find_cert (ctrl_t ctrl,
- const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
+ const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert,
+ int allow_ambiguous)
{
int rc;
KEYDB_SEARCH_DESC desc;
@@ -537,6 +538,16 @@ gpgsm_find_cert (ctrl_t ctrl,
won't lead to ambiguous names. */
if (!rc && !keyid)
{
+ ksba_isotime_t notbefore = "";
+ const unsigned char *image = NULL;
+ size_t length = 0;
+ if (allow_ambiguous)
+ {
+ /* We want to return the newest certificate */
+ if (ksba_cert_get_validity (*r_cert, 0, notbefore))
+ *notbefore = '\0';
+ image = ksba_cert_get_image (*r_cert, &length);
+ }
next_ambiguous:
rc = keydb_search (ctrl, kh, &desc, 1);
if (rc == -1)
@@ -546,6 +557,10 @@ gpgsm_find_cert (ctrl_t ctrl,
if (!rc)
{
ksba_cert_t cert2 = NULL;
+ ksba_isotime_t notbefore2 = "";
+ const unsigned char *image2 = NULL;
+ size_t length2 = 0;
+ int cmp = 0;
if (!keydb_get_cert (kh, &cert2))
{
@@ -554,6 +569,29 @@ gpgsm_find_cert (ctrl_t ctrl,
ksba_cert_release (cert2);
goto next_ambiguous;
}
+ if (allow_ambiguous)
+ {
+ if (ksba_cert_get_validity (cert2, 0, notbefore2))
+ *notbefore2 = '\0';
+ image2 = ksba_cert_get_image (cert2, &length2);
+ cmp = strcmp (notbefore, notbefore2);
+ /* use certificate image bits as last resort for stable ordering */
+ if (!cmp)
+ cmp = memcmp (image, image2, length < length2 ? length : length2);
+ if (!cmp)
+ cmp = length < length2 ? -1 : length > length2 ? 1 : 0;
+ if (cmp < 0)
+ {
+ ksba_cert_release (*r_cert);
+ *r_cert = cert2;
+ strcpy (notbefore, notbefore2);
+ image = image2;
+ length = length2;
+ }
+ else
+ ksba_cert_release (cert2);
+ goto next_ambiguous;
+ }
ksba_cert_release (cert2);
}
rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index bd701ab7f..e80de6378 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -2058,7 +2058,7 @@ main ( int argc, char **argv)
ksba_cert_t cert = NULL;
char *grip = NULL;
- rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert);
+ rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert, 0);
if (rc)
;
else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 0421b97bb..3e2f95fb3 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -331,7 +331,7 @@ int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
certlist_t *listaddr, int is_encrypt_to);
void gpgsm_release_certlist (certlist_t list);
int gpgsm_find_cert (ctrl_t ctrl, const char *name, ksba_sexp_t keyid,
- ksba_cert_t *r_cert);
+ ksba_cert_t *r_cert, int allow_ambiguous);
/*-- keylist.c --*/
gpg_error_t gpgsm_list_keys (ctrl_t ctrl, strlist_t names,
diff --git a/sm/server.c b/sm/server.c
index 64a3add9a..568e51b17 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -1179,7 +1179,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
line = skip_options (line);
- err = gpgsm_find_cert (ctrl, line, NULL, &cert);
+ err = gpgsm_find_cert (ctrl, line, NULL, &cert, 0);
if (err)
;
else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index e6ef4f4e3..9ce752b18 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -2085,9 +2085,12 @@ get_config_filename (gc_component_t component, gc_backend_t backend)
/* Retrieve the options for the component COMPONENT from backend
- BACKEND, which we already know is a program-type backend. */
+ * BACKEND, which we already know is a program-type backend. With
+ * ONLY_INSTALLED set components which are not installed are silently
+ * ignored. */
static void
-retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
+retrieve_options_from_program (gc_component_t component, gc_backend_t backend,
+ int only_installed)
{
gpg_error_t err;
const char *pgmname;
@@ -2107,6 +2110,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
argv[0] = "--gpgconf-list";
argv[1] = NULL;
+ if (only_installed && access (pgmname, X_OK))
+ {
+ return; /* The component is not installed. */
+ }
+
err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
NULL, &outfp, NULL, &pid);
if (err)
@@ -2378,7 +2386,7 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
/* Retrieve the currently active options and their defaults from all
involved backends for this component. Using -1 for component will
- retrieve all options from all components. */
+ retrieve all options from all installed components. */
void
gc_component_retrieve_options (int component)
{
@@ -2420,7 +2428,8 @@ gc_component_retrieve_options (int component)
assert (backend != GC_BACKEND_ANY);
if (gc_backend[backend].program)
- retrieve_options_from_program (component, backend);
+ retrieve_options_from_program (component, backend,
+ process_all);
else
retrieve_options_from_file (component, backend);
}