aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2016-08-25 07:26:36 +0000
committerWerner Koch <[email protected]>2016-08-25 07:37:56 +0000
commit19d12be3cea5b4ee8153287a2f2442913a5e07a1 (patch)
tree1a75c09e6b44995832b02c2a5adad5a10a40ae22
parentgpg: Change TOFU_STATS to return timestamps. (diff)
downloadgnupg-19d12be3cea5b4ee8153287a2f2442913a5e07a1.tar.gz
gnupg-19d12be3cea5b4ee8153287a2f2442913a5e07a1.zip
gpg: New option --with-tofu-info.
* g10/gpg.c (oWithTofuInfo): New. (opts): Add --with-tofu-info. (main): Set opt.with_tofu_info. * g10/options.h (struct opt): Add field WITH_TOFU_INFO. * g10/tofu.c (show_statistics): Add optional arg OUTFP and enter special mode if not NULL. Change all callers. (tofu_write_tfs_record): New. * g10/keylist.c (list_keyblock_colon): Do not print the tofu policy as part of the "uid" record. Print a new "tfs" record if the new option is set. * tests/openpgp/tofu.scm (getpolicy): Change from UID to TFS record. -- A separate option is required to avoid slowing down key listings. Foer example the current code takes for a keylisting in tofu+pgp mode 17 seconds while it takes more than 5 minutes if the option is used. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to '')
-rw-r--r--doc/DETAILS6
-rw-r--r--g10/gpg.c12
-rw-r--r--g10/gpgv.c11
-rw-r--r--g10/keylist.c22
-rw-r--r--g10/options.h1
-rw-r--r--g10/test-stubs.c11
-rw-r--r--g10/tofu.c72
-rw-r--r--g10/tofu.h4
-rwxr-xr-xtests/openpgp/tofu.scm6
9 files changed, 107 insertions, 38 deletions
diff --git a/doc/DETAILS b/doc/DETAILS
index 454f2e315..cf779d27d 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -52,7 +52,7 @@ described here.
- sub :: Subkey (secondary key)
- sec :: Secret key
- ssb :: Secret subkey (secondary key)
- - uid :: User id (only field 10 is used).
+ - uid :: User id
- uat :: User attribute (same as user id except for field 10).
- sig :: Signature
- rev :: Revocation signature
@@ -214,10 +214,6 @@ described here.
For pub, sub, sec, and ssb records this field is used for the ECC
curve name.
-*** Field 18 - TOFU Policy
-
- This is the TOFU policy. It is either good, bad, unknown, ask or
- auto. This is only shows for uid records.
** Special fields
diff --git a/g10/gpg.c b/g10/gpg.c
index e02efe49e..3193e7426 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -193,6 +193,11 @@ enum cmd_and_opt_values
oWithKeygrip,
oWithSecret,
oWithWKDHash,
+ oWithColons,
+ oWithKeyData,
+ oWithTofuInfo,
+ oWithSigList,
+ oWithSigCheck,
oAnswerYes,
oAnswerNo,
oKeyring,
@@ -259,10 +264,6 @@ enum cmd_and_opt_values
oNoOptions,
oNoBatch,
oHomedir,
- oWithColons,
- oWithKeyData,
- oWithSigList,
- oWithSigCheck,
oSkipVerify,
oSkipHiddenRecipients,
oNoSkipHiddenRecipients,
@@ -699,6 +700,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_n (oNoBatch, "no-batch", "@"),
ARGPARSE_s_n (oWithColons, "with-colons", "@"),
+ ARGPARSE_s_n (oWithTofuInfo,"with-tofu-info", "@"),
ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
@@ -2650,6 +2652,8 @@ main (int argc, char **argv)
case oHomedir: break;
case oNoBatch: opt.batch = 0; break;
+ case oWithTofuInfo: opt.with_tofu_info = 1; break;
+
case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
case oWithColons: opt.with_colons=':'; break;
diff --git a/g10/gpgv.c b/g10/gpgv.c
index 4ef3e8b74..1f2cecbfc 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -661,6 +661,17 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
}
gpg_error_t
+tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
+ PKT_public_key *pk, const char *user_id)
+{
+ (void)ctrl;
+ (void)fp;
+ (void)pk;
+ (void)user_id;
+ return gpg_error (GPG_ERR_GENERAL);
+}
+
+gpg_error_t
tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy)
{
diff --git a/g10/keylist.c b/g10/keylist.c
index 59344b2c3..a34ef648c 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -1289,8 +1289,8 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
char *str;
PKT_user_id *uid = node->pkt->pkt.user_id;
- if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
- dump_attribs (node->pkt->pkt.user_id, pk);
+ if (attrib_fp && uid->attrib_data != NULL)
+ dump_attribs (uid, pk);
/*
* Fixme: We need a valid flag here too
*/
@@ -1326,18 +1326,16 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
else
es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
- es_fprintf (es_stdout, "::::::::");
- if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
- {
-#ifdef USE_TOFU
- enum tofu_policy policy;
- if (! tofu_get_policy (ctrl, pk, uid, &policy)
- && policy != TOFU_POLICY_NONE)
- es_fprintf (es_stdout, "%s", tofu_policy_str (policy));
-#endif /*USE_TOFU*/
- }
es_putc (':', es_stdout);
es_putc ('\n', es_stdout);
+#ifdef USE_TOFU
+ if (!uid->attrib_data && opt.with_tofu_info
+ && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
+ {
+ /* Print a "tfs" record. */
+ tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
+ }
+#endif /*USE_TOFU*/
}
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
diff --git a/g10/options.h b/g10/options.h
index 6b8f6490f..544be60ab 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -81,6 +81,7 @@ struct
int with_fingerprint; /* Option --with-fingerprint active. */
int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */
int with_keygrip; /* Option --with-keygrip active. */
+ int with_tofu_info; /* Option --with-tofu_info active. */
int with_secret; /* Option --with-secret active. */
int with_wkd_hash; /* Option --with-wkd-hash. */
int fingerprint; /* list fingerprints */
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index c5f2f79b3..55351b815 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -474,6 +474,17 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
}
gpg_error_t
+tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
+ PKT_public_key *pk, const char *user_id)
+{
+ (void)ctrl;
+ (void)fp;
+ (void)pk;
+ (void)user_id;
+ return gpg_error (GPG_ERR_GENERAL);
+}
+
+gpg_error_t
tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id,
enum tofu_policy *policy)
{
diff --git a/g10/tofu.c b/g10/tofu.c
index 29318c761..9d562c298 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -1919,10 +1919,13 @@ write_stats_status (estream_t fp, long messages, enum tofu_policy policy,
}
}
+
+/* Note: If OUTFP is not NULL, this function merely prints a "tfs" record
+ * to OUTFP. In this case USER_ID is not required. */
static void
show_statistics (tofu_dbs_t dbs, const char *fingerprint,
const char *email, const char *user_id,
- const char *sig_exclude)
+ const char *sig_exclude, estream_t outfp)
{
char *fingerprint_pp;
int rc;
@@ -1951,15 +1954,16 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint,
goto out;
}
-
- write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint,
- email, strlen (email), 0);
+ if (!outfp)
+ write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint,
+ email, strlen (email), 0);
if (! strlist)
{
- log_info (_("Have never verified a message signed by key %s!\n"),
- fingerprint_pp);
- write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0);
+ if (!outfp)
+ log_info (_("Have never verified a message signed by key %s!\n"),
+ fingerprint_pp);
+ write_stats_status (outfp, 0, TOFU_POLICY_NONE, 0, 0);
}
else
{
@@ -1999,10 +2003,17 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint,
if (messages == -1 || !first_seen)
{
- write_stats_status (NULL, 0, TOFU_POLICY_NONE, 0, 0);
- log_info (_("Failed to collect signature statistics for \"%s\"\n"
- "(key %s)\n"),
- user_id, fingerprint_pp);
+ write_stats_status (outfp, 0, TOFU_POLICY_NONE, 0, 0);
+ if (!outfp)
+ log_info (_("Failed to collect signature statistics for \"%s\"\n"
+ "(key %s)\n"),
+ user_id, fingerprint_pp);
+ }
+ else if (outfp)
+ {
+ write_stats_status (outfp, messages,
+ get_policy (dbs, fingerprint, email, NULL),
+ first_seen, most_recent_seen);
}
else
{
@@ -2010,7 +2021,8 @@ show_statistics (tofu_dbs_t dbs, const char *fingerprint,
estream_t fp;
char *msg;
- write_stats_status (NULL, messages, policy,
+ write_stats_status (NULL, messages,
+ policy,
first_seen, most_recent_seen);
fp = es_fopenmem (0, "rw,samethread");
@@ -2313,7 +2325,7 @@ tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
/* It's only appropriate to show the statistics in an interactive
context. */
show_statistics (dbs, fingerprint, email, user_id,
- already_verified ? NULL : sig_digest);
+ already_verified ? NULL : sig_digest, NULL);
xfree (email);
xfree (fingerprint);
@@ -2385,6 +2397,38 @@ tofu_wot_trust_combine (int tofu_base, int wot_base)
}
+/* Write a "tfs" record for a --with-colons listing. */
+gpg_error_t
+tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
+ PKT_public_key *pk, const char *user_id)
+{
+ gpg_error_t err;
+ tofu_dbs_t dbs;
+ char *fingerprint;
+ char *email;
+
+ if (!*user_id)
+ return 0; /* No TOFU stats possible for an empty ID. */
+
+ dbs = opendbs (ctrl);
+ if (!dbs)
+ {
+ err = gpg_error (GPG_ERR_GENERAL);
+ log_error (_("error opening TOFU database: %s\n"), gpg_strerror (err));
+ return err;
+ }
+
+ fingerprint = hexfingerprint (pk, NULL, 0);
+ email = email_from_user_id (user_id);
+
+ show_statistics (dbs, fingerprint, email, user_id, NULL, fp);
+
+ xfree (email);
+ xfree (fingerprint);
+ return 0;
+}
+
+
/* Return the validity (TRUST_NEVER, etc.) of the binding
<FINGERPRINT, USER_ID>.
@@ -2429,7 +2473,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
trust_level = TRUST_UNDEFINED;
if (may_ask && trust_level != TRUST_ULTIMATE)
- show_statistics (dbs, fingerprint, email, user_id, NULL);
+ show_statistics (dbs, fingerprint, email, user_id, NULL, NULL);
die:
xfree (email);
diff --git a/g10/tofu.h b/g10/tofu.h
index e3ec81965..d6854e9bf 100644
--- a/g10/tofu.h
+++ b/g10/tofu.h
@@ -88,6 +88,10 @@ int tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id,
interest when the trust model is tofu+pgp (TM_TOFU_PGP). */
int tofu_wot_trust_combine (int tofu, int wot);
+/* Write a "tfs" record for a --with-colons listing. */
+gpg_error_t tofu_write_tfs_record (ctrl_t ctrl, estream_t fp,
+ PKT_public_key *pk, const char *user_id);
+
/* Determine the validity (TRUST_NEVER, etc.) of the binding
<PK, USER_ID>. If MAY_ASK is 1, then this function may
interact with the user. If not, TRUST_UNKNOWN is returned. If an
diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm
index 2b302baaa..448c253c9 100755
--- a/tests/openpgp/tofu.scm
+++ b/tests/openpgp/tofu.scm
@@ -46,11 +46,11 @@
;; This function only supports keys with a single user id.
(define (getpolicy keyid format . args)
(let ((policy
- (list-ref (assoc "uid" (gpg-with-colons
+ (list-ref (assoc "tfs" (gpg-with-colons
`(--tofu-db-format ,format
- --trust-model=tofu
+ --trust-model=tofu --with-tofu-info
,@args
- --list-keys ,keyid))) 17)))
+ --list-keys ,keyid))) 5)))
(unless (member policy '("auto" "good" "unknown" "bad" "ask"))
(error "Bad policy:" policy))
policy))