diff options
author | Werner Koch <[email protected]> | 2016-08-25 07:26:36 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-08-25 07:37:56 +0000 |
commit | 19d12be3cea5b4ee8153287a2f2442913a5e07a1 (patch) | |
tree | 1a75c09e6b44995832b02c2a5adad5a10a40ae22 | |
parent | gpg: Change TOFU_STATS to return timestamps. (diff) | |
download | gnupg-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/DETAILS | 6 | ||||
-rw-r--r-- | g10/gpg.c | 12 | ||||
-rw-r--r-- | g10/gpgv.c | 11 | ||||
-rw-r--r-- | g10/keylist.c | 22 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/test-stubs.c | 11 | ||||
-rw-r--r-- | g10/tofu.c | 72 | ||||
-rw-r--r-- | g10/tofu.h | 4 | ||||
-rwxr-xr-x | tests/openpgp/tofu.scm | 6 |
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 @@ -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)) |