1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-03 12:11:33 +01:00

gpg: Re-format some tofu messages.

* common/status.h (STATUS_TOFU_USER, STATUS_TOFU_STATS)
(STATUS_TOFU_STATS_SHORT, STATUS_TOFU_STATS_LONG): New.
* g10/tofu.c (NO_WARNING_THRESHOLD): New.
(record_binding, tofu_register): Take care of --dry-run.
(show_statistics): Print STATUS_TOFU_USER.  Reformat some messages.
Fix the ngettext/strcmp thing.  Use log_string instead of log_info.
Use NO_WARNING_THRESHOLD constant.
(get_trust): Use format_text and print a compact fingerprint.

--

The use of log_string makes long messages better readable; instead of

  gpg: Warning: if you think you've seen more[...]
  key, then this key might be a forgery!  Car[...]
  address for small variations.  If the key i[...]

we now have

  gpg: Warning: if you think you've seen more[...]
       key, then this key might be a forgery![...]
       address for small variations.  If the [...]

We also put the key information after the message and not between the
user id and the last used info like here:

  gpg: Verified 7 messages signed by "Werner Koch <werner@eifzilla.de>"
       in the past 4 days, 16 hours.
       The most recent message was verified 3 days, 13 hours ago.
       (key: 8061 5870 F5BA D690 3336  [...] 1E42 B367, policy: auto)

This also makes the key info a separate translatable string.

Further a compact version of the fingerprint (hex w/o spaces) is
printed in some messages.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-05-02 09:48:19 +02:00
parent c88efcc2cc
commit d73e83c3b6
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 154 additions and 105 deletions

View File

@ -133,6 +133,11 @@ enum
STATUS_PKA_TRUST_BAD, STATUS_PKA_TRUST_BAD,
STATUS_PKA_TRUST_GOOD, STATUS_PKA_TRUST_GOOD,
STATUS_TOFU_USER,
STATUS_TOFU_STATS,
STATUS_TOFU_STATS_SHORT,
STATUS_TOFU_STATS_LONG,
STATUS_TRUNCATED, STATUS_TRUNCATED,
STATUS_MOUNTPOINT, STATUS_MOUNTPOINT,

View File

@ -40,12 +40,16 @@
#include "trustdb.h" #include "trustdb.h"
#include "mkdir_p.h" #include "mkdir_p.h"
#include "sqlite.h" #include "sqlite.h"
#include "status.h"
#include "tofu.h" #include "tofu.h"
#define CONTROL_L ('L' - 'A' + 1) #define CONTROL_L ('L' - 'A' + 1)
/* Number of signed messages required to not show extra warnings. */
#define NO_WARNING_THRESHOLD 10
#define DEBUG_TOFU_CACHE 0 #define DEBUG_TOFU_CACHE 0
#if DEBUG_TOFU_CACHE #if DEBUG_TOFU_CACHE
@ -1205,7 +1209,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
{ {
log_debug ("TOFU: Error reading from binding database" log_debug ("TOFU: Error reading from binding database"
" (reading policy for <%s, %s>): %s\n", " (reading policy for <%s, %s>): %s\n",
fingerprint_pp, email, err); fingerprint, email, err);
sqlite3_free (err); sqlite3_free (err);
} }
} }
@ -1215,12 +1219,12 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
if (policy_old != TOFU_POLICY_NONE) if (policy_old != TOFU_POLICY_NONE)
log_debug ("Changing TOFU trust policy for binding <%s, %s>" log_debug ("Changing TOFU trust policy for binding <%s, %s>"
" from %s to %s.\n", " from %s to %s.\n",
fingerprint_pp, email, fingerprint, email,
tofu_policy_str (policy_old), tofu_policy_str (policy_old),
tofu_policy_str (policy)); tofu_policy_str (policy));
else else
log_debug ("Set TOFU trust policy for binding <%s, %s> to %s.\n", log_debug ("Set TOFU trust policy for binding <%s, %s> to %s.\n",
fingerprint_pp, email, fingerprint, email,
tofu_policy_str (policy)); tofu_policy_str (policy));
} }
@ -1228,6 +1232,12 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
/* Nothing to do. */ /* Nothing to do. */
goto out; goto out;
if (opt.dry_run)
{
log_info ("TOFU database update skipped due to --dry-run\n");
goto out;
}
rc = sqlite3_stepx rc = sqlite3_stepx
(db_email->db, &db_email->s.record_binding_update, NULL, NULL, &err, (db_email->db, &db_email->s.record_binding_update, NULL, NULL, &err,
"insert or replace into bindings\n" "insert or replace into bindings\n"
@ -1246,7 +1256,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
{ {
log_error (_("error updating TOFU database: %s\n"), err); log_error (_("error updating TOFU database: %s\n"), err);
print_further_info (" insert bindings <%s, %s> = %s", print_further_info (" insert bindings <%s, %s> = %s",
fingerprint_pp, email, tofu_policy_str (policy)); fingerprint, email, tofu_policy_str (policy));
sqlite3_free (err); sqlite3_free (err);
goto out; goto out;
} }
@ -1273,7 +1283,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
{ {
log_error (_("error updating TOFU database: %s\n"), err); log_error (_("error updating TOFU database: %s\n"), err);
print_further_info ("insert bindings <%s, %s>", print_further_info ("insert bindings <%s, %s>",
fingerprint_pp, email); fingerprint, email);
sqlite3_free (err); sqlite3_free (err);
goto out; goto out;
} }
@ -1680,7 +1690,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
policy = opt.tofu_default_policy; policy = opt.tofu_default_policy;
if (DBG_TRUST) if (DBG_TRUST)
log_debug ("TOFU: binding <%s, %s>'s policy is auto (default: %s).\n", log_debug ("TOFU: binding <%s, %s>'s policy is auto (default: %s).\n",
fingerprint_pp, email, fingerprint, email,
tofu_policy_str (opt.tofu_default_policy)); tofu_policy_str (opt.tofu_default_policy));
} }
switch (policy) switch (policy)
@ -1693,7 +1703,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
We don't need to ask the user anything. */ We don't need to ask the user anything. */
if (DBG_TRUST) if (DBG_TRUST)
log_debug ("TOFU: Known binding <%s, %s>'s policy: %s\n", log_debug ("TOFU: Known binding <%s, %s>'s policy: %s\n",
fingerprint_pp, email, tofu_policy_str (policy)); fingerprint, email, tofu_policy_str (policy));
trust_level = tofu_policy_to_trust_level (policy); trust_level = tofu_policy_to_trust_level (policy);
goto out; goto out;
@ -1771,7 +1781,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
if (DBG_TRUST) if (DBG_TRUST)
log_debug ("TOFU: New binding <%s, %s>, no conflict.\n", log_debug ("TOFU: New binding <%s, %s>, no conflict.\n",
email, fingerprint_pp); email, fingerprint);
if (record_binding (dbs, fingerprint, email, user_id, if (record_binding (dbs, fingerprint, email, user_id,
TOFU_POLICY_AUTO, 0) != 0) TOFU_POLICY_AUTO, 0) != 0)
@ -1828,8 +1838,6 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
((policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0) ((policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0)
|| (policy == TOFU_POLICY_ASK && conflict)); || (policy == TOFU_POLICY_ASK && conflict));
estream_t fp; estream_t fp;
char *binding;
int binding_shown;
strlist_t other_user_ids = NULL; strlist_t other_user_ids = NULL;
struct signature_stats *stats = NULL; struct signature_stats *stats = NULL;
struct signature_stats *stats_iter = NULL; struct signature_stats *stats_iter = NULL;
@ -1838,43 +1846,65 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
fp = es_fopenmem (0, "rw,samethread"); fp = es_fopenmem (0, "rw,samethread");
if (! fp) if (! fp)
log_fatal ("Error creating memory stream\n"); log_fatal ("error creating memory stream: %s\n",
gpg_strerror (gpg_error_from_syserror()));
binding = xasprintf ("<%s, %s>", fingerprint_pp, email); /* Format the first part of the message. */
binding_shown = 0; {
estream_t fp1;
char *binding = xasprintf ("<%s, %s>", fingerprint, email);
int binding_shown = 0;
char *tmpstr, *text;
if (policy == TOFU_POLICY_NONE) fp1 = es_fopenmem (0, "rw,samethread");
{ if (!fp1)
es_fprintf (fp, _("The binding %s is NOT known."), binding); log_fatal ("error creating memory stream: %s\n",
es_fputs (" ", fp); gpg_strerror (gpg_error_from_syserror()));
binding_shown = 1;
}
else if (policy == TOFU_POLICY_ASK
/* If there the conflict is with itself, then don't
display this message. */
&& conflict && strcmp (conflict, fingerprint) != 0)
{
char *conflict_pp = format_hexfingerprint (conflict, NULL, 0);
es_fprintf (fp,
_("The key %s raised a conflict with this binding (%s)."
" Since this binding's policy was 'auto', it was "
"changed to 'ask'."),
conflict_pp, binding);
es_fputs (" ", fp);
xfree (conflict_pp);
binding_shown = 1;
}
/* TRANSLATORS: The %s%s is replaced by either a fingerprint and a
blank or by two empty strings. */
es_fprintf (fp,
_("Please indicate whether you believe the binding %s%s"
"is legitimate (the key belongs to the stated owner) "
"or a forgery (bad)."),
binding_shown ? "" : binding,
binding_shown ? "" : " ");
es_fputs ("\n\n", fp);
xfree (binding); if (policy == TOFU_POLICY_NONE)
{
es_fprintf (fp1, _("The binding %s is NOT known."), binding);
es_fputs (" ", fp1);
binding_shown = 1;
}
else if (policy == TOFU_POLICY_ASK
/* If there the conflict is with itself, then don't
display this message. */
&& conflict && strcmp (conflict, fingerprint) != 0)
{
es_fprintf (fp1,
_("The key with fingerprint %s raised a conflict "
"with the binding %s."
" Since this binding's policy was 'auto', it was "
"changed to 'ask'."),
conflict, binding);
es_fputs (" ", fp1);
binding_shown = 1;
}
/* TRANSLATORS: The %s%s is replaced by either a fingerprint and a
blank or by two empty strings. */
es_fprintf (fp1,
_("Please indicate whether you believe the binding %s%s"
"is legitimate (the key belongs to the stated owner) "
"or a forgery (bad)."),
binding_shown ? "" : binding,
binding_shown ? "" : " ");
es_fputc ('\n', fp1);
xfree (binding);
es_fputc (0, fp1);
if (es_fclose_snatch (fp1, (void **)&tmpstr, NULL))
log_fatal ("error snatching memory stream\n");
text = format_text (tmpstr, 0, 72, 80);
es_free (tmpstr);
es_fputs (text, fp);
xfree (text);
}
es_fputc ('\n', fp);
/* Find other user ids associated with this key and whether the /* Find other user ids associated with this key and whether the
bindings are marked as good or bad. */ bindings are marked as good or bad. */
@ -2370,6 +2400,9 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
goto out; goto out;
} }
write_status_text_and_buffer (STATUS_TOFU_USER, fingerprint,
email, strlen (email), 0);
if (! strlist) if (! strlist)
log_info (_("Have never verified a message signed by key %s!\n"), log_info (_("Have never verified a message signed by key %s!\n"),
fingerprint_pp); fingerprint_pp);
@ -2396,8 +2429,8 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
} }
if (messages == -1 || first_seen_ago == 0) if (messages == -1 || first_seen_ago == 0)
log_info (_("Failed to collect signature statistics" log_info (_("Failed to collect signature statistics for \"%s\"\n"
" for \"%s\" (key %s)\n"), "(key %s)\n"),
user_id, fingerprint_pp); user_id, fingerprint_pp);
else else
{ {
@ -2407,55 +2440,67 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
fp = es_fopenmem (0, "rw,samethread"); fp = es_fopenmem (0, "rw,samethread");
if (! fp) if (! fp)
log_fatal ("error creating memory stream\n"); log_fatal ("error creating memory stream: %s\n",
gpg_strerror (gpg_error_from_syserror()));
if (messages == 0) if (messages == 0)
es_fprintf (fp, {
_("Verified 0 messages signed by \"%s\"" es_fprintf (fp, _("Verified %ld messages signed by \"%s\"."),
" (key: %s, policy: %s)."), 0L, user_id);
user_id, fingerprint_pp, tofu_policy_str (policy)); es_fputc ('\n', fp);
}
else else
{ {
char *first_seen_ago_str = char *first_seen_ago_str = time_ago_str (first_seen_ago);
time_ago_str (first_seen_ago);
char *most_recent_seen_ago_str =
time_ago_str (most_recent_seen_ago);
/* TRANSLATORS: The final %s is replaced by a string like /* TRANSLATORS: The final %s is replaced by a string like
"7 months, 1 day, 5 minutes, 0 seconds". */ "7 months, 1 day, 5 minutes, 0 seconds". */
es_fprintf (fp, ngettext("Verified %ld message signed by \"%s\"" es_fprintf (fp,
" (key: %s, policy: %s) in the past %s.", ngettext("Verified %ld message signed by \"%s\"\n"
"Verified %ld messages signed by \"%s\"" "in the past %s.",
" (key: %s, policy: %s) in the past %s.", "Verified %ld messages signed by \"%s\"\n"
messages), "in the past %s.",
messages, user_id, messages),
fingerprint_pp, tofu_policy_str (policy), messages, user_id, first_seen_ago_str);
first_seen_ago_str);
if (messages > 1) if (messages > 1)
{ {
char *tmpstr = time_ago_str (most_recent_seen_ago);
es_fputs (" ", fp); es_fputs (" ", fp);
es_fprintf (fp, es_fprintf (fp, _("The most recent message was"
_("The most recent message was verified %s ago."), " verified %s ago."), tmpstr);
most_recent_seen_ago_str); xfree (tmpstr);
} }
xfree (first_seen_ago_str); xfree (first_seen_ago_str);
xfree (most_recent_seen_ago_str);
if (opt.verbose)
{
es_fputs (" ", fp);
es_fputc ('(', fp);
es_fprintf (fp, _("policy: %s"), tofu_policy_str (policy));
es_fputs (")\n", fp);
}
else
es_fputs ("\n", fp);
} }
es_fputc (0, fp); {
if (es_fclose_snatch (fp, (void **) &msg, NULL)) char *tmpmsg;
log_fatal ("error snatching memory stream\n"); es_fputc (0, fp);
if (es_fclose_snatch (fp, (void **) &tmpmsg, NULL))
log_fatal ("error snatching memory stream\n");
msg = format_text (tmpmsg, 0, 72, 80);
es_free (tmpmsg);
}
log_info ("%s\n", msg); log_string (GPGRT_LOG_INFO, msg);
xfree (msg); xfree (msg);
if (policy == TOFU_POLICY_AUTO && messages < 10) if (policy == TOFU_POLICY_AUTO && messages < NO_WARNING_THRESHOLD)
{ {
char *set_policy_command; char *set_policy_command;
char *text; char *text;
char *tmp; char *tmpmsg;
if (messages == 0) if (messages == 0)
log_info (_("Warning: we've have yet to see" log_info (_("Warning: we've have yet to see"
@ -2465,34 +2510,29 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
" single message signed by this key!\n")); " single message signed by this key!\n"));
set_policy_command = set_policy_command =
xasprintf ("gpg --tofu-policy bad \"%s\"", fingerprint); xasprintf ("gpg --tofu-policy bad %s", fingerprint);
/* TRANSLATORS: translate the below text. We don't
directly internationalize that text so that we can
tweak it without breaking translations. */
text = ngettext("TOFU: few signatures %d message %s",
"TOFU: few signatures %d messages %s", 1);
if (strcmp (text, "TOFU: few signatures %d message %s") == 0)
{
text =
(messages == 1?
"Warning: if you think you've seen more than %d message "
"signed by this key, then this key might be a forgery! "
"Carefully examine the email address for small variations "
"(e.g., additional white space). If the key is suspect, "
"then use '%s' to mark it as being bad.\n"
:
"Warning: if you think you've seen more than %d messages "
"signed by this key, then this key might be a forgery! "
"Carefully examine the email address for small variations "
"(e.g., additional white space). If the key is suspect, "
"then use '%s' to mark it as being bad.\n");
}
tmp = xasprintf (text, messages, set_policy_command); tmpmsg = xasprintf
text = format_text (tmp, 0, 72, 80); (ngettext
xfree (tmp); ("Warning: if you think you've seen more than %ld message "
log_info ("%s", text); "signed by this key, then this key might be a forgery! "
"Carefully examine the email address for small "
"variations. If the key is suspect, then use\n"
" %s\n"
"to mark it as being bad.\n",
"Warning: if you think you've seen more than %ld messages "
"signed by this key, then this key might be a forgery! "
"Carefully examine the email address for small "
"variations. If the key is suspect, then use\n"
" %s\n"
"to mark it as being bad.\n",
messages),
messages, set_policy_command);
text = format_text (tmpmsg, 0, 72, 80);
xfree (tmpmsg);
log_string (GPGRT_LOG_INFO, text);
xfree (text); xfree (text);
es_free (set_policy_command); es_free (set_policy_command);
} }
} }
@ -2634,26 +2674,30 @@ tofu_register (PKT_public_key *pk, const char *user_id,
because <fingerprint, email, sig_time, sig_digest> is the because <fingerprint, email, sig_time, sig_digest> is the
primary key! */ primary key! */
log_debug ("SIGNATURES DB contains duplicate records" log_debug ("SIGNATURES DB contains duplicate records"
" <key: %s, %s, time: 0x%lx, sig: %s, %s>." " <%s, %s, 0x%lx, %s, %s>."
" Please report.\n", " Please report.\n",
fingerprint_pp, email, (unsigned long) sig_time, fingerprint, email, (unsigned long) sig_time,
sig_digest, origin); sig_digest, origin);
else if (c == 1) else if (c == 1)
{ {
already_verified = 1; already_verified = 1;
if (DBG_TRUST) if (DBG_TRUST)
log_debug ("Already observed the signature" log_debug ("Already observed the signature"
" <key: %s, %s, time: 0x%lx, sig: %s, %s>\n", " <%s, %s, 0x%lx, %s, %s>\n",
fingerprint_pp, email, (unsigned long) sig_time, fingerprint, email, (unsigned long) sig_time,
sig_digest, origin); sig_digest, origin);
} }
else if (opt.dry_run)
{
log_info ("TOFU database update skipped due to --dry-run\n");
}
else else
/* This is the first time that we've seen this signature. /* This is the first time that we've seen this signature.
Record it. */ Record it. */
{ {
if (DBG_TRUST) if (DBG_TRUST)
log_debug ("TOFU: Saving signature <%s, %s, %s>\n", log_debug ("TOFU: Saving signature <%s, %s, %s>\n",
fingerprint_pp, email, sig_digest); fingerprint, email, sig_digest);
log_assert (c == 0); log_assert (c == 0);