LCOV - code coverage report
Current view: top level - g10 - tofu.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 505 1098 46.0 %
Date: 2015-11-05 17:10:59 Functions: 32 42 76.2 %

          Line data    Source code
       1             : /* tofu.c - TOFU trust model.
       2             :  * Copyright (C) 2015 g10 Code GmbH
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /* TODO:
      21             : 
      22             :    - Format the fingerprints nicely when printing (similar to gpg
      23             :      --list-keys)
      24             :  */
      25             : 
      26             : #include <config.h>
      27             : #include <stdio.h>
      28             : #include <sys/stat.h>
      29             : #include <assert.h>
      30             : #include <stdarg.h>
      31             : #include <sched.h>
      32             : #include <sqlite3.h>
      33             : 
      34             : #include "gpg.h"
      35             : #include "types.h"
      36             : #include "logging.h"
      37             : #include "stringhelp.h"
      38             : #include "options.h"
      39             : #include "mbox-util.h"
      40             : #include "i18n.h"
      41             : #include "trustdb.h"
      42             : #include "mkdir_p.h"
      43             : #include "sqlite.h"
      44             : 
      45             : #include "tofu.h"
      46             : 
      47             : #define DEBUG_TOFU_CACHE 0
      48             : #if DEBUG_TOFU_CACHE
      49             : static int prepares_saved;
      50             : static int queries;
      51             : #endif
      52             : 
      53             : /* The TOFU data can be saved in two different formats: either in a
      54             :    single combined database (opt.tofu_db_format == TOFU_DB_FLAT) or in
      55             :    a split file format (opt.tofu_db_format == TOFU_DB_SPLIT).  In the
      56             :    split format, there is one database per normalized email address
      57             :    (DB_EMAIL) and one per key (DB_KEY).  */
      58             : enum db_type
      59             :   {
      60             :     DB_COMBINED,
      61             :     DB_EMAIL,
      62             :     DB_KEY
      63             :   };
      64             : 
      65             : /* A list of open DBs.
      66             : 
      67             :    In the flat format, this consists of a single element with the type
      68             :    DB_COMBINED and whose name is the empty string.
      69             : 
      70             :    In the split format, the first element is a dummy element (DB is
      71             :    NULL) whose type is DB_COMBINED and whose name is the empty string.
      72             :    Any following elements describe either DB_EMAIL or DB_KEY DBs.  In
      73             :    theis case, NAME is either the normalized email address or the
      74             :    fingerprint.
      75             : 
      76             :    To initialize this data structure, call opendbs().  When you are
      77             :    done, clean it up using closedbs().  To get a handle to a database,
      78             :    use the getdb() function.  This will either return an existing
      79             :    handle or open a new DB connection, as appropriate.  */
      80             : struct db
      81             : {
      82             :   struct db *next;
      83             :   struct db **prevp;
      84             : 
      85             :   enum db_type type;
      86             : 
      87             :   sqlite3 *db;
      88             : 
      89             :   struct
      90             :   {
      91             :     sqlite3_stmt *savepoint_batch;
      92             :     sqlite3_stmt *savepoint_batch_commit;
      93             : 
      94             :     sqlite3_stmt *savepoint_inner;
      95             :     sqlite3_stmt *savepoint_inner_commit;
      96             : 
      97             :     sqlite3_stmt *record_binding_get_old_policy;
      98             :     sqlite3_stmt *record_binding_update;
      99             :     sqlite3_stmt *record_binding_update2;
     100             :     sqlite3_stmt *get_policy_select_policy_and_conflict;
     101             :     sqlite3_stmt *get_trust_bindings_with_this_email;
     102             :     sqlite3_stmt *get_trust_gather_other_user_ids;
     103             :     sqlite3_stmt *get_trust_gather_other_keys;
     104             :     sqlite3_stmt *register_already_seen;
     105             :     sqlite3_stmt *register_insert;
     106             :   } s;
     107             : 
     108             : #if DEBUG_TOFU_CACHE
     109             :   int hits;
     110             : #endif
     111             : 
     112             :   int batch_update;
     113             : 
     114             :   /* If TYPE is DB_COMBINED, this is "".  Otherwise, it is either the
     115             :      fingerprint (type == DB_KEY) or the normalized email address
     116             :      (type == DB_EMAIL).  */
     117             :   char name[1];
     118             : };
     119             : 
     120             : static struct db *db_cache;
     121             : static int db_cache_count;
     122             : #define DB_CACHE_ENTRIES 16
     123             : 
     124             : static void tofu_cache_dump (struct db *db) GPGRT_ATTR_USED;
     125             : 
     126             : static void
     127           0 : tofu_cache_dump (struct db *db)
     128             : {
     129           0 :   log_info ("Connection %p:\n", db);
     130           0 :   for (; db; db = db->next)
     131           0 :     log_info ("  %s: %sbatch mode\n", db->name, db->batch_update ? "" : "NOT ");
     132           0 :   log_info ("Cache:\n");
     133           0 :   for (db = db_cache; db; db = db->next)
     134           0 :     log_info ("  %s: %sbatch mode\n", db->name, db->batch_update ? "" : "NOT ");
     135           0 : }
     136             : 
     137             : #define STRINGIFY(s) STRINGIFY2(s)
     138             : #define STRINGIFY2(s) #s
     139             : 
     140             : /* The grouping parameters when collecting signature statistics.  */
     141             : 
     142             : /* If a message is signed a couple of hours in the future, just assume
     143             :    some clock skew.  */
     144             : #define TIME_AGO_FUTURE_IGNORE (2 * 60 * 60)
     145             : #if 0
     146             : #  define TIME_AGO_UNIT_SMALL 60
     147             : #  define TIME_AGO_UNIT_SMALL_NAME _("minute")
     148             : #  define TIME_AGO_UNIT_SMALL_NAME_PLURAL _("minutes")
     149             : #  define TIME_AGO_MEDIUM_THRESHOLD (60 * TIME_AGO_UNIT_SMALL)
     150             : #  define TIME_AGO_UNIT_MEDIUM (60 * 60)
     151             : #  define TIME_AGO_UNIT_MEDIUM_NAME _("hour")
     152             : #  define TIME_AGO_UNIT_MEDIUM_NAME_PLURAL _("hours")
     153             : #  define TIME_AGO_LARGE_THRESHOLD (24 * 60 * TIME_AGO_UNIT_SMALL)
     154             : #  define TIME_AGO_UNIT_LARGE (24 * 60 * 60)
     155             : #  define TIME_AGO_UNIT_LARGE_NAME _("day")
     156             : #  define TIME_AGO_UNIT_LARGE_NAME_PLURAL _("days")
     157             : #else
     158             : #  define TIME_AGO_UNIT_SMALL (24 * 60 * 60)
     159             : #  define TIME_AGO_UNIT_SMALL_NAME _("day")
     160             : #  define TIME_AGO_UNIT_SMALL_NAME_PLURAL _("days")
     161             : #  define TIME_AGO_MEDIUM_THRESHOLD (4 * TIME_AGO_UNIT_SMALL)
     162             : #  define TIME_AGO_UNIT_MEDIUM (7 * 24 * 60 * 60)
     163             : #  define TIME_AGO_UNIT_MEDIUM_NAME _("week")
     164             : #  define TIME_AGO_UNIT_MEDIUM_NAME_PLURAL _("weeks")
     165             : #  define TIME_AGO_LARGE_THRESHOLD (28 * TIME_AGO_UNIT_SMALL)
     166             : #  define TIME_AGO_UNIT_LARGE (30 * 24 * 60 * 60)
     167             : #  define TIME_AGO_UNIT_LARGE_NAME _("month")
     168             : #  define TIME_AGO_UNIT_LARGE_NAME_PLURAL _("months")
     169             : #endif
     170             : 
     171             : static char *
     172         266 : fingerprint_str (const byte *fingerprint_bin)
     173             : {
     174         266 :   char *fingerprint = bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, NULL);
     175         266 :   if (! fingerprint)
     176           0 :     log_fatal ("bin2hex failed: %s\n",
     177             :                gpg_strerror (gpg_error_from_syserror()));
     178         266 :   return fingerprint;
     179             : }
     180             : 
     181             : /* Pretty print a MAX_FINGERPRINT_LEN-byte binary fingerprint into a
     182             :    malloc'd string.  */
     183             : static char *
     184         202 : fingerprint_format (const byte *fingerprint)
     185             : {
     186             :   char *fingerprint_pretty;
     187         202 :   int space = (/* The characters and the NUL.  */
     188             :                2 * MAX_FINGERPRINT_LEN + 1
     189             :                /* After every fourth character, we add a space (except
     190             :                   the last).  */
     191             :                + 2 * MAX_FINGERPRINT_LEN / 4 - 1
     192             :                /* Half way through we add a second space.  */
     193             :                + 1);
     194             :   int i;
     195             :   int j;
     196             : 
     197         202 :   if (strlen (fingerprint) != 2 * MAX_FINGERPRINT_LEN)
     198             :     {
     199           0 :       log_info (_("Fingerprint with unexpected length (%zu chars)\n"),
     200             :                 strlen (fingerprint));
     201           0 :       return xstrdup (fingerprint);
     202             :     }
     203             : 
     204         202 :   fingerprint_pretty = xmalloc (space);
     205             : 
     206        8282 :   for (i = 0, j = 0; i < MAX_FINGERPRINT_LEN * 2; i ++)
     207             :     {
     208        8080 :       if (i && i % 4 == 0)
     209        1818 :         fingerprint_pretty[j ++] = ' ';
     210        8080 :       if (i == MAX_FINGERPRINT_LEN * 2 / 2)
     211         202 :         fingerprint_pretty[j ++] = ' ';
     212             : 
     213        8080 :       fingerprint_pretty[j ++] = fingerprint[i];
     214             :     }
     215         202 :   fingerprint_pretty[j ++] = 0;
     216         202 :   assert (j == space);
     217             : 
     218         202 :   return fingerprint_pretty;
     219             : }
     220             : 
     221             : const char *
     222          88 : tofu_policy_str (enum tofu_policy policy)
     223             : {
     224          88 :   switch (policy)
     225             :     {
     226           0 :     case TOFU_POLICY_NONE: return "none";
     227          14 :     case TOFU_POLICY_AUTO: return "auto";
     228          20 :     case TOFU_POLICY_GOOD: return "good";
     229          20 :     case TOFU_POLICY_UNKNOWN: return "unknown";
     230          24 :     case TOFU_POLICY_BAD: return "bad";
     231          10 :     case TOFU_POLICY_ASK: return "ask";
     232           0 :     default: return "???";
     233             :     }
     234             : }
     235             : 
     236             : /* Convert a binding policy (e.g., TOFU_POLICY_BAD) to a trust level
     237             :    (e.g., TRUST_BAD) in light of the current configuration.  */
     238             : int
     239         156 : tofu_policy_to_trust_level (enum tofu_policy policy)
     240             : {
     241         156 :   if (policy == TOFU_POLICY_AUTO)
     242             :     /* If POLICY is AUTO, fallback to OPT.TOFU_DEFAULT_POLICY.  */
     243          16 :     policy = opt.tofu_default_policy;
     244             : 
     245         156 :   switch (policy)
     246             :     {
     247             :     case TOFU_POLICY_AUTO:
     248             :       /* If POLICY and OPT.TOFU_DEFAULT_POLICY are both AUTO, default
     249             :          to marginal trust.  */
     250          16 :       return TRUST_MARGINAL;
     251             :     case TOFU_POLICY_GOOD:
     252          44 :       return TRUST_FULLY;
     253             :     case TOFU_POLICY_UNKNOWN:
     254          44 :       return TRUST_UNKNOWN;
     255             :     case TOFU_POLICY_BAD:
     256          52 :       return TRUST_NEVER;
     257             :     case TOFU_POLICY_ASK:
     258           0 :       return TRUST_UNKNOWN;
     259             :     default:
     260           0 :       log_bug ("Bad value for trust policy: %d\n",
     261           0 :                opt.tofu_default_policy);
     262             :       return 0;
     263             :     }
     264             : }
     265             : 
     266             : static int batch_update;
     267             : static time_t batch_update_started;
     268             : 
     269             : static gpg_error_t end_transaction (struct db *db, int only_batch);
     270             : 
     271             : /* Start a transaction on DB.  */
     272             : static gpg_error_t
     273          27 : begin_transaction (struct db *db, int only_batch)
     274             : {
     275             :   int rc;
     276          27 :   char *err = NULL;
     277             : 
     278          27 :   if (batch_update && batch_update_started != gnupg_get_time ())
     279             :     /* We've been in batch update mode for a while (on average, more
     280             :        than 500 ms).  To prevent starving other gpg processes, we drop
     281             :        and retake the batch lock.
     282             : 
     283             :        Note: if we wanted higher resolution, we could use
     284             :        npth_clock_gettime.  */
     285             :     {
     286             :       struct db *t;
     287             : 
     288           0 :       for (t = db_cache; t; t = t->next)
     289           0 :         if (t->batch_update)
     290           0 :           end_transaction (t, 1);
     291           0 :       for (t = db; t; t = t->next)
     292           0 :         if (t->batch_update)
     293           0 :           end_transaction (t, 1);
     294             : 
     295           0 :       batch_update_started = gnupg_get_time ();
     296             : 
     297             :       /* Yield to allow another process a chance to run.  */
     298           0 :       sched_yield ();
     299             :     }
     300             : 
     301             :   /* XXX: In split mode, this can end in deadlock.
     302             : 
     303             :      Consider: we have two gpg processes running simultaneously and
     304             :      they each want to lock DB A and B, but in different orders.  This
     305             :      will be automatically resolved by causing one of them to return
     306             :      EBUSY and aborting.
     307             : 
     308             :      A more intelligent approach would be to commit and retake the
     309             :      batch transaction.  This requires a list of all DBs that are
     310             :      currently in batch mode.  */
     311             : 
     312          27 :   if (batch_update && ! db->batch_update)
     313             :     {
     314           0 :       rc = sqlite3_stepx (db->db, &db->s.savepoint_batch,
     315             :                           NULL, NULL, &err,
     316             :                           "savepoint batch;", SQLITE_ARG_END);
     317           0 :       if (rc)
     318             :         {
     319           0 :           log_error
     320           0 :             (_("error beginning %s transaction on TOFU database '%s': %s\n"),
     321           0 :              "batch", *db->name ? db->name : "combined", err);
     322           0 :           sqlite3_free (err);
     323           0 :           return gpg_error (GPG_ERR_GENERAL);
     324             :         }
     325             : 
     326           0 :       db->batch_update = 1;
     327             :     }
     328             : 
     329          27 :   if (only_batch)
     330           7 :     return 0;
     331             : 
     332          20 :   rc = sqlite3_stepx (db->db, &db->s.savepoint_inner,
     333             :                       NULL, NULL, &err,
     334             :                       "savepoint inner;", SQLITE_ARG_END);
     335          20 :   if (rc)
     336             :     {
     337           0 :       log_error
     338           0 :         (_("error beginning %s transaction on TOFU database '%s': %s\n"),
     339           0 :          "inner", *db->name ? db->name : "combined", err);
     340           0 :       sqlite3_free (err);
     341           0 :       return gpg_error (GPG_ERR_GENERAL);
     342             :     }
     343             : 
     344          20 :   return 0;
     345             : }
     346             : 
     347             : /* Commit a transaction.  If ONLY_BATCH is 1, then this only ends the
     348             :    batch transaction if we have left batch mode.  If ONLY_BATCH is 2,
     349             :    this ends any open batch transaction even if we are still in batch
     350             :    mode.  */
     351             : static gpg_error_t
     352         102 : end_transaction (struct db *db, int only_batch)
     353             : {
     354             :   int rc;
     355         102 :   char *err = NULL;
     356             : 
     357         102 :   if ((! batch_update || only_batch == 2) && db->batch_update)
     358             :     /* The batch transaction is still in open, but we left batch
     359             :        mode.  */
     360             :     {
     361           0 :       db->batch_update = 0;
     362             : 
     363           0 :       rc = sqlite3_stepx (db->db, &db->s.savepoint_batch_commit,
     364             :                           NULL, NULL, &err,
     365             :                           "release batch;", SQLITE_ARG_END);
     366           0 :       if (rc)
     367             :         {
     368           0 :           log_error
     369           0 :             (_("error committing %s transaction on TOFU database '%s': %s\n"),
     370           0 :              "batch", *db->name ? db->name : "combined", err);
     371           0 :           sqlite3_free (err);
     372           0 :           return gpg_error (GPG_ERR_GENERAL);
     373             :         }
     374             : 
     375             :       /* Releasing an outer transaction releases an open inner
     376             :          transactions.  We're done.  */
     377           0 :       return 0;
     378             :     }
     379             : 
     380         102 :   if (only_batch)
     381          82 :     return 0;
     382             : 
     383          20 :   rc = sqlite3_stepx (db->db, &db->s.savepoint_inner_commit,
     384             :                       NULL, NULL, &err,
     385             :                       "release inner;", SQLITE_ARG_END);
     386          20 :   if (rc)
     387             :     {
     388           0 :       log_error
     389           0 :         (_("error committing %s transaction on TOFU database '%s': %s\n"),
     390           0 :          "inner", *db->name ? db->name : "combined", err);
     391           0 :       sqlite3_free (err);
     392           0 :       return gpg_error (GPG_ERR_GENERAL);
     393             :     }
     394             : 
     395          20 :   return 0;
     396             : }
     397             : 
     398             : static gpg_error_t
     399           0 : rollback_transaction (struct db *db)
     400             : {
     401             :   int rc;
     402           0 :   char *err = NULL;
     403             : 
     404           0 :   if (db->batch_update)
     405             :     /* Just undo the most recent update; don't revert any progress
     406             :        made by the batch transaction.  */
     407           0 :     rc = sqlite3_exec (db->db, "rollback to inner;", NULL, NULL, &err);
     408             :   else
     409             :     /* Rollback the whole she-bang.  */
     410           0 :     rc = sqlite3_exec (db->db, "rollback;", NULL, NULL, &err);
     411             : 
     412           0 :   if (rc)
     413             :     {
     414           0 :       log_error
     415           0 :         (_("error rolling back inner transaction on TOFU database '%s': %s\n"),
     416           0 :          *db->name ? db->name : "combined", err);
     417           0 :       sqlite3_free (err);
     418           0 :       return gpg_error (GPG_ERR_GENERAL);
     419             :     }
     420             : 
     421           0 :   return 0;
     422             : }
     423             : 
     424             : void
     425          87 : tofu_begin_batch_update (void)
     426             : {
     427          87 :   if (! batch_update)
     428          87 :     batch_update_started = gnupg_get_time ();
     429             : 
     430          87 :   batch_update ++;
     431          87 : }
     432             : 
     433             : void
     434          87 : tofu_end_batch_update (void)
     435             : {
     436          87 :   assert (batch_update > 0);
     437          87 :   batch_update --;
     438             : 
     439          87 :   if (batch_update == 0)
     440             :     {
     441             :       struct db *db;
     442             : 
     443         169 :       for (db = db_cache; db; db = db->next)
     444          82 :         end_transaction (db, 1);
     445             :     }
     446          87 : }
     447             : 
     448             : /* Collect results of a select count (*) ...; style query.  Aborts if
     449             :    the argument is not a valid integer (or real of the form X.0).  */
     450             : static int
     451         109 : get_single_unsigned_long_cb (void *cookie, int argc, char **argv,
     452             :                              char **azColName)
     453             : {
     454         109 :   unsigned long int *count = cookie;
     455         109 :   char *tail = NULL;
     456             : 
     457             :   (void) azColName;
     458             : 
     459         109 :   assert (argc == 1);
     460             : 
     461         109 :   errno = 0;
     462         109 :   *count = strtoul (argv[0], &tail, 0);
     463         109 :   if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0'))
     464             :     /* Abort.  */
     465           0 :     return 1;
     466         109 :   return 0;
     467             : }
     468             : 
     469             : static int
     470           6 : get_single_unsigned_long_cb2 (void *cookie, int argc, char **argv,
     471             :                              char **azColName, sqlite3_stmt *stmt)
     472             : {
     473             :   (void) stmt;
     474           6 :   return get_single_unsigned_long_cb (cookie, argc, argv, azColName);
     475             : }
     476             : 
     477             : /* We expect a single integer column whose name is "version".  COOKIE
     478             :    must point to an int.  This function always aborts.  On error or a
     479             :    if the version is bad, sets *VERSION to -1.  */
     480             : static int
     481          98 : version_check_cb (void *cookie, int argc, char **argv, char **azColName)
     482             : {
     483          98 :   int *version = cookie;
     484             : 
     485          98 :   if (argc != 1 || strcmp (azColName[0], "version") != 0)
     486             :     {
     487           0 :       *version = -1;
     488           0 :       return 1;
     489             :     }
     490             : 
     491          98 :   if (strcmp (argv[0], "1") == 0)
     492          98 :     *version = 1;
     493             :   else
     494             :     {
     495           0 :       log_error (_("unsupported TOFU DB version: %s\n"), argv[0]);
     496           0 :       *version = -1;
     497             :     }
     498             : 
     499             :   /* Don't run again.  */
     500          98 :   return 1;
     501             : }
     502             : 
     503             : 
     504             : /* If the DB is new, initialize it.  Otherwise, check the DB's
     505             :    version.
     506             : 
     507             :    Return 0 if the database is okay and 1 otherwise.  */
     508             : static int
     509         103 : initdb (sqlite3 *db, enum db_type type)
     510             : {
     511         103 :   char *err = NULL;
     512             :   int rc;
     513             :   unsigned long int count;
     514         103 :   int version = -1;
     515             : 
     516         103 :   rc = sqlite3_exec (db, "begin transaction;", NULL, NULL, &err);
     517         103 :   if (rc)
     518             :     {
     519           0 :       log_error (_("error beginning transaction on TOFU database: %s\n"),
     520             :                  err);
     521           0 :       sqlite3_free (err);
     522           0 :       return 1;
     523             :     }
     524             : 
     525             :   /* If the DB has no tables, then assume this is a new DB that needs
     526             :      to be initialized.  */
     527         103 :   rc = sqlite3_exec (db,
     528             :                      "select count(*) from sqlite_master where type='table';",
     529             :                      get_single_unsigned_long_cb, &count, &err);
     530         103 :   if (rc)
     531             :     {
     532           0 :       log_error (_("error querying TOFU DB's available tables: %s\n"),
     533             :                  err);
     534           0 :       sqlite3_free (err);
     535           0 :       goto out;
     536             :     }
     537         103 :   else if (count != 0)
     538             :     /* Assume that the DB is already initialized.  Make sure the
     539             :        version is okay.  */
     540             :     {
     541          98 :       rc = sqlite3_exec (db, "select version from version;", version_check_cb,
     542             :                          &version, &err);
     543          98 :       if (rc == SQLITE_ABORT && version == 1)
     544             :         /* Happy, happy, joy, joy.  */
     545             :         {
     546          98 :           sqlite3_free (err);
     547          98 :           rc = 0;
     548          98 :           goto out;
     549             :         }
     550           0 :       else if (rc == SQLITE_ABORT && version == -1)
     551             :         /* Unsupported version.  */
     552             :         {
     553             :           /* An error message was already displayed.  */
     554           0 :           sqlite3_free (err);
     555           0 :           goto out;
     556             :         }
     557           0 :       else if (rc)
     558             :         /* Some error.  */
     559             :         {
     560           0 :           log_error (_("error determining TOFU DB's version: %s\n"), err);
     561           0 :           sqlite3_free (err);
     562           0 :           goto out;
     563             :         }
     564             :       else
     565             :         /* Unexpected success.  This can only happen if there are no
     566             :            rows.  */
     567             :         {
     568           0 :           log_error (_("error determining TOFU DB's version: %s\n"),
     569             :                      "select returned 0, but expected ABORT");
     570           0 :           rc = 1;
     571           0 :           goto out;
     572             :         }
     573             :     }
     574             : 
     575             :   /* Create the version table.  */
     576           5 :   rc = sqlite3_exec (db,
     577             :                      "create table version (version INTEGER);",
     578             :                      NULL, NULL, &err);
     579           5 :   if (rc)
     580             :     {
     581           0 :       log_error (_("error initializing TOFU database (%s): %s\n"),
     582             :                  "version", err);
     583           0 :       sqlite3_free (err);
     584           0 :       goto out;
     585             :     }
     586             : 
     587             :   /* Initialize the version table, which contains a single integer
     588             :      value.  */
     589           5 :   rc = sqlite3_exec (db,
     590             :                      "insert into version values (1);",
     591             :                      NULL, NULL, &err);
     592           5 :   if (rc)
     593             :     {
     594           0 :       log_error (_("error initializing TOFU database (%s): %s\n"),
     595             :                  "version, init", err);
     596           0 :       sqlite3_free (err);
     597           0 :       goto out;
     598             :     }
     599             : 
     600             :   /* The list of <fingerprint, email> bindings and auxiliary data.
     601             : 
     602             :        OID is a unique ID identifying this binding (and used by the
     603             :          signatures table, see below).  Note: OIDs will never be
     604             :          reused.
     605             : 
     606             :        FINGERPRINT: The key's fingerprint.
     607             : 
     608             :        EMAIL: The normalized email address.
     609             : 
     610             :        USER_ID: The unmodified user id from which EMAIL was extracted.
     611             : 
     612             :        TIME: The time this binding was first observed.
     613             : 
     614             :        POLICY: The trust policy (-1, 0, 1, or 2; see the
     615             :          documentation for TOFU_POLICY_BAD, etc. above).
     616             : 
     617             :        CONFLICT is either NULL or a fingerprint.  Assume that we have
     618             :          a binding <0xdeadbeef, foo@example.com> and then we observe
     619             :          <0xbaddecaf, foo@example.com>.  There two bindings conflict
     620             :          (they have the same email address).  When we observe the
     621             :          latter binding, we warn the user about the conflict and ask
     622             :          for a policy decision about the new binding.  We also change
     623             :          the old binding's policy to ask if it was auto.  So that we
     624             :          know why this occured, we also set conflict to 0xbaddecaf.
     625             :   */
     626           5 :   if (type == DB_EMAIL || type == DB_COMBINED)
     627           2 :     rc = sqlite3_exec_printf
     628             :       (db, NULL, NULL, &err,
     629             :        "create table bindings\n"
     630             :        " (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
     631             :        "  fingerprint TEXT, email TEXT, user_id TEXT, time INTEGER,\n"
     632             :        "  policy BOOLEAN CHECK (policy in (%d, %d, %d, %d, %d)),\n"
     633             :        "  conflict STRING,\n"
     634             :        "  unique (fingerprint, email));\n"
     635             :        "create index bindings_fingerprint_email\n"
     636             :        " on bindings (fingerprint, email);\n"
     637             :        "create index bindings_email on bindings (email);\n",
     638             :        TOFU_POLICY_AUTO, TOFU_POLICY_GOOD, TOFU_POLICY_UNKNOWN,
     639             :        TOFU_POLICY_BAD, TOFU_POLICY_ASK);
     640             :   else
     641             :     /* In the split DB case, the fingerprint DB only contains a subset
     642             :        of the fields.  This reduces the amount of duplicated data.
     643             : 
     644             :        Note: since the data is split on the email address, there is no
     645             :        need to index the email column.  */
     646           3 :     rc = sqlite3_exec_printf
     647             :       (db, NULL, NULL, &err,
     648             :        "create table bindings\n"
     649             :        " (oid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
     650             :        "  fingerprint TEXT, email TEXT, user_id,\n"
     651             :        "  unique (fingerprint, email));\n"
     652             :        "create index bindings_fingerprint\n"
     653             :        " on bindings (fingerprint);\n");
     654           5 :   if (rc)
     655             :     {
     656           0 :       log_error (_("error initializing TOFU database (%s): %s\n"),
     657             :                  "bindings", err);
     658           0 :       sqlite3_free (err);
     659           0 :       goto out;
     660             :     }
     661             : 
     662           5 :   if (type != DB_KEY)
     663             :     {
     664             :       /* The signatures that we have observed.
     665             : 
     666             :          BINDING refers to a record in the bindings table, which
     667             :          describes the binding (i.e., this is a foreign key that
     668             :          references bindings.oid).
     669             : 
     670             :          SIG_DIGEST is the digest stored in the signature.
     671             : 
     672             :          SIG_TIME is the timestamp stored in the signature.
     673             : 
     674             :          ORIGIN is a free-form string that describes who fed this
     675             :          signature to GnuPG (e.g., email:claws).
     676             : 
     677             :          TIME is the time this signature was registered.  */
     678           2 :       rc = sqlite3_exec (db,
     679             :                          "create table signatures "
     680             :                          " (binding INTEGER NOT NULL, sig_digest TEXT,"
     681             :                          "  origin TEXT, sig_time INTEGER, time INTEGER,"
     682             :                          "  primary key (binding, sig_digest, origin));",
     683             :                          NULL, NULL, &err);
     684           2 :       if (rc)
     685             :         {
     686           0 :           log_error (_("error initializing TOFU database (%s): %s\n"),
     687             :                      "signatures", err);
     688           0 :           sqlite3_free (err);
     689           0 :           goto out;
     690             :         }
     691             :     }
     692             : 
     693             :  out:
     694         103 :   if (rc)
     695             :     {
     696           0 :       rc = sqlite3_exec (db, "rollback;", NULL, NULL, &err);
     697           0 :       if (rc)
     698             :         {
     699           0 :           log_error (_("error aborting transaction on TOFU DB: %s\n"),
     700             :                      err);
     701           0 :           sqlite3_free (err);
     702             :         }
     703           0 :       return 1;
     704             :     }
     705             :   else
     706             :     {
     707         103 :       rc = sqlite3_exec (db, "end transaction;", NULL, NULL, &err);
     708         103 :       if (rc)
     709             :         {
     710           0 :           log_error (_("error committing transaction on TOFU DB: %s\n"),
     711             :                      err);
     712           0 :           sqlite3_free (err);
     713           0 :           return 1;
     714             :         }
     715         103 :       return 0;
     716             :     }
     717             : }
     718             : 
     719             : /* Open and initialize a low-level TOFU database.  Returns NULL on
     720             :    failure.  This function should not normally be directly called to
     721             :    get a database handle.  Instead, use getdb().  */
     722             : static sqlite3 *
     723         103 : opendb (char *filename, enum db_type type)
     724             : {
     725             :   sqlite3 *db;
     726         103 :   int filename_free = 0;
     727             :   int rc;
     728             : 
     729         103 :   if (opt.tofu_db_format == TOFU_DB_FLAT)
     730             :     {
     731          48 :       assert (! filename);
     732          48 :       assert (type == DB_COMBINED);
     733             : 
     734          48 :       filename = make_filename (opt.homedir, "tofu.db", NULL);
     735          48 :       filename_free = 1;
     736             :     }
     737             :   else
     738          55 :     assert (type == DB_EMAIL || type == DB_KEY);
     739             : 
     740         103 :   assert (filename);
     741             : 
     742         103 :   rc = sqlite3_open (filename, &db);
     743         103 :   if (rc)
     744             :     {
     745           0 :       log_error (_("can't open TOFU DB ('%s'): %s\n"),
     746             :                  filename, sqlite3_errmsg (db));
     747             :       /* Even if an error occurs, DB is guaranteed to be valid.  */
     748           0 :       sqlite3_close (db);
     749           0 :       db = NULL;
     750             :     }
     751             : 
     752             :   /* If a DB is locked wait up to 5 seconds for the lock to be cleared
     753             :      before failing.  */
     754         103 :   sqlite3_busy_timeout (db, 5 * 1000);
     755             : 
     756         103 :   if (filename_free)
     757          48 :     xfree (filename);
     758             : 
     759         103 :   if (db && initdb (db, type))
     760             :     {
     761           0 :       sqlite3_close (db);
     762           0 :       db = NULL;
     763             :     }
     764             : 
     765         103 :   return db;
     766             : }
     767             : 
     768             : struct dbs
     769             : {
     770             :   struct db *db;
     771             : };
     772             : 
     773             : static void
     774         170 : unlink_db (struct db *db)
     775             : {
     776         170 :   *db->prevp = db->next;
     777         170 :   if (db->next)
     778           0 :     db->next->prevp = db->prevp;
     779         170 : }
     780             : 
     781             : static void
     782         273 : link_db (struct db **head, struct db *db)
     783             : {
     784         273 :   db->next = *head;
     785         273 :   if (db->next)
     786           7 :     db->next->prevp = &db->next;
     787         273 :   db->prevp = head;
     788         273 :   *head = db;
     789         273 : }
     790             : 
     791             : /* Return a database handle.  <type, name> describes the required
     792             :    database.  If there is a cached handle in DBS, that handle is
     793             :    returned.  Otherwise, the database is opened and cached in DBS.
     794             : 
     795             :    NAME is the name of the DB and may not be NULL.
     796             : 
     797             :    TYPE must be either DB_MAIL or DB_KEY.  In the combined format, the
     798             :    combined DB is always returned.  */
     799             : static struct db *
     800         473 : getdb (struct dbs *dbs, const char *name, enum db_type type)
     801             : {
     802         473 :   struct db *t = NULL;
     803         473 :   char *name_sanitized = NULL;
     804             :   int count;
     805         473 :   char *filename = NULL;
     806         473 :   int need_link = 1;
     807         473 :   sqlite3 *sqlitedb = NULL;
     808             : 
     809         473 :   assert (dbs);
     810         473 :   assert (name);
     811         473 :   assert (type == DB_EMAIL || type == DB_KEY);
     812             : 
     813         473 :   if (opt.tofu_db_format == TOFU_DB_FLAT)
     814             :     /* When using the flat format, we only have a single DB, the
     815             :        combined DB.  */
     816             :     {
     817         233 :       if (dbs->db)
     818             :         {
     819         100 :           assert (dbs->db->type == DB_COMBINED);
     820         100 :           assert (! dbs->db->next);
     821         100 :           return dbs->db;
     822             :         }
     823             : 
     824         133 :       type = DB_COMBINED;
     825             :     }
     826             : 
     827         373 :   if (type != DB_COMBINED)
     828             :     /* Only allow alpha-numeric characters in the name.  */
     829             :     {
     830             :       int i;
     831             : 
     832         240 :       name_sanitized = xstrdup (name);
     833        4947 :       for (i = 0; name[i]; i ++)
     834             :         {
     835        4707 :           char c = name_sanitized[i];
     836        5817 :           if (! (('a' <= c && c <= 'z')
     837        1212 :                  || ('A' <= c && c <= 'Z')
     838         178 :                  || ('0' <= c && c <= '9')))
     839         932 :             name_sanitized[i] = '_';
     840             :         }
     841             :     }
     842             : 
     843             :   /* See if the DB is cached.  */
     844         380 :   for (t = dbs->db; t; t = t->next)
     845         107 :     if (t->type == type
     846         100 :         && (type == DB_COMBINED || strcmp (t->name, name_sanitized) == 0))
     847             :       {
     848         100 :         need_link = 0;
     849         100 :         goto out;
     850             :       }
     851             : 
     852         276 :   for (t = db_cache, count = 0; t; t = t->next, count ++)
     853         173 :     if (type == t->type
     854         170 :         && (type == DB_COMBINED || strcmp (t->name, name_sanitized) == 0))
     855             :       {
     856         170 :         unlink_db (t);
     857         170 :         db_cache_count --;
     858         170 :         goto out;
     859             :       }
     860             : 
     861         103 :   assert (db_cache_count == count);
     862             : 
     863         103 :   if (type == DB_COMBINED)
     864          48 :     filename = NULL;
     865             :   else
     866             :     {
     867             :       /* Open the DB.  The filename has the form:
     868             : 
     869             :          tofu.d/TYPE/PREFIX/NAME.db
     870             : 
     871             :          We use a short prefix to try to avoid having many files in a
     872             :          single directory.  */
     873             :       {
     874          55 :         char *type_str = type == DB_EMAIL ? "email" : "key";
     875          55 :         char prefix[3] = { name_sanitized[0], name_sanitized[1], 0 };
     876             :         char *name_db;
     877             : 
     878             :         /* Make the directory.  */
     879          55 :         if (gnupg_mkdir_p (opt.homedir, "tofu.d", type_str, prefix, NULL) != 0)
     880             :           {
     881           0 :             log_error (_("unable to create directory %s/%s/%s/%s"),
     882             :                        opt.homedir, "tofu.d", type_str, prefix);
     883           0 :             goto out;
     884             :           }
     885             : 
     886          55 :         name_db = xstrconcat (name_sanitized, ".db", NULL);
     887          55 :         filename = make_filename
     888             :           (opt.homedir, "tofu.d", type_str, prefix, name_db, NULL);
     889          55 :         xfree (name_db);
     890             :       }
     891             :     }
     892             : 
     893         103 :   sqlitedb = opendb (filename, type);
     894         103 :   if (! sqlitedb)
     895           0 :     goto out;
     896             : 
     897         103 :   t = xmalloc_clear (sizeof (struct db)
     898             :                      + (name_sanitized ? strlen (name_sanitized) : 0));
     899         103 :   t->type = type;
     900         103 :   t->db = sqlitedb;
     901         103 :   if (name_sanitized)
     902          55 :     strcpy (t->name, name_sanitized);
     903             : 
     904             :  out:
     905         373 :   if (t && need_link)
     906         273 :     link_db (&dbs->db, t);
     907             : 
     908             : #if DEBUG_TOFU_CACHE
     909             :   if (t)
     910             :     t->hits ++;
     911             : #endif
     912             : 
     913         373 :   xfree (filename);
     914         373 :   xfree (name_sanitized);
     915         373 :   return t;
     916             : }
     917             : 
     918             : static void
     919           0 : closedb (struct db *db)
     920             : {
     921             :   sqlite3_stmt **statements;
     922             : 
     923           0 :   if (opt.tofu_db_format == TOFU_DB_FLAT)
     924             :     /* If we are using the flat format, then there is only ever the
     925             :        combined DB.  */
     926           0 :     assert (! db->next);
     927             : 
     928           0 :   if (db->type == DB_COMBINED)
     929             :     {
     930           0 :       assert (opt.tofu_db_format == TOFU_DB_FLAT);
     931           0 :       assert (! db->name[0]);
     932             :     }
     933             :   else
     934             :     {
     935           0 :       assert (opt.tofu_db_format == TOFU_DB_SPLIT);
     936           0 :       assert (db->type != DB_COMBINED);
     937           0 :       assert (db->name[0]);
     938             :     }
     939             : 
     940           0 :   if (db->batch_update)
     941           0 :     end_transaction (db, 2);
     942             : 
     943           0 :   for (statements = (void *) &db->s;
     944           0 :        (void *) statements < (void *) &(&db->s)[1];
     945           0 :        statements ++)
     946           0 :     sqlite3_finalize (*statements);
     947             : 
     948           0 :   sqlite3_close (db->db);
     949             : 
     950             : #if DEBUG_TOFU_CACHE
     951             :   log_debug ("Freeing db.  Used %d times.\n", db->hits);
     952             : #endif
     953             : 
     954           0 :   xfree (db);
     955           0 : }
     956             : 
     957             : 
     958             : /* Create a new DB meta-handle.  Returns NULL on error.  */
     959             : static struct dbs *
     960         266 : opendbs (void)
     961             : {
     962         266 :   if (opt.tofu_db_format == TOFU_DB_AUTO)
     963             :     {
     964           0 :       char *filename = make_filename (opt.homedir, "tofu.db", NULL);
     965             :       struct stat s;
     966           0 :       int have_tofu_db = 0;
     967           0 :       int have_tofu_d = 0;
     968             : 
     969           0 :       if (stat (filename, &s) == 0)
     970             :         {
     971           0 :           have_tofu_db = 1;
     972           0 :           if (DBG_TRUST)
     973           0 :             log_debug ("%s exists.\n", filename);
     974             :         }
     975             :       else
     976             :         {
     977           0 :           if (DBG_TRUST)
     978           0 :             log_debug ("%s does not exist.\n", filename);
     979             :         }
     980             : 
     981             :       /* We now have tofu.d.  */
     982           0 :       filename[strlen (filename) - 1] = '\0';
     983           0 :       if (stat (filename, &s) == 0)
     984             :         {
     985           0 :           have_tofu_d = 1;
     986           0 :           if (DBG_TRUST)
     987           0 :             log_debug ("%s exists.\n", filename);
     988             :         }
     989             :       else
     990             :         {
     991           0 :           if (DBG_TRUST)
     992           0 :             log_debug ("%s does not exist.\n", filename);
     993             :         }
     994             : 
     995           0 :       xfree (filename);
     996             : 
     997           0 :       if (have_tofu_db && have_tofu_d)
     998             :         {
     999           0 :           log_info (_("Warning: Home directory contains both tofu.db"
    1000             :                       " and tofu.d.  Using split format for TOFU DB.\n"));
    1001           0 :           opt.tofu_db_format = TOFU_DB_SPLIT;
    1002             :         }
    1003           0 :       else if (have_tofu_db)
    1004             :         {
    1005           0 :           opt.tofu_db_format = TOFU_DB_FLAT;
    1006           0 :           if (DBG_TRUST)
    1007           0 :             log_debug ("Using flat format for TOFU DB.\n");
    1008             :         }
    1009           0 :       else if (have_tofu_d)
    1010             :         {
    1011           0 :           opt.tofu_db_format = TOFU_DB_SPLIT;
    1012           0 :           if (DBG_TRUST)
    1013           0 :             log_debug ("Using split format for TOFU DB.\n");
    1014             :         }
    1015             :       else
    1016             :         {
    1017           0 :           opt.tofu_db_format = TOFU_DB_SPLIT;
    1018           0 :           if (DBG_TRUST)
    1019           0 :             log_debug ("Using split format for TOFU DB.\n");
    1020             :         }
    1021             :     }
    1022             : 
    1023         266 :   return xmalloc_clear (sizeof (struct dbs));
    1024             : }
    1025             : 
    1026             : /* Release all of the resources associated with a DB meta-handle.  */
    1027             : static void
    1028         266 : closedbs (struct dbs *dbs)
    1029             : {
    1030         266 :   if (dbs->db)
    1031             :     {
    1032         266 :       struct db *old_head = db_cache;
    1033             :       struct db *db;
    1034             :       int count;
    1035             : 
    1036             :       /* Find the last DB.  */
    1037         273 :       for (db = dbs->db, count = 1; db->next; db = db->next, count ++)
    1038             :         {
    1039             :           /* When we leave batch mode we leave batch mode on any
    1040             :              cached connections.  */
    1041           7 :           if (! batch_update)
    1042           7 :             assert (! db->batch_update);
    1043             :         }
    1044         266 :       if (! batch_update)
    1045          20 :         assert (! db->batch_update);
    1046             : 
    1047             :       /* Join the two lists.  */
    1048         266 :       db->next = db_cache;
    1049         266 :       if (db_cache)
    1050           3 :         db_cache->prevp = &db->next;
    1051             : 
    1052             :       /* Update the (new) first element.  */
    1053         266 :       db_cache = dbs->db;
    1054         266 :       dbs->db->prevp = &db_cache;
    1055             : 
    1056         266 :       db_cache_count += count;
    1057             : 
    1058             :       /* Make sure that we don't have too many DBs on DB_CACHE.  If
    1059             :          so, free some.  */
    1060         266 :       if (db_cache_count > DB_CACHE_ENTRIES)
    1061             :         {
    1062             :           /* We need to find the (DB_CACHE_ENTRIES + 1)th entry.  It
    1063             :              is easy to skip the first COUNT entries since we still
    1064             :              have a handle on the old head.  */
    1065           0 :           int skip = DB_CACHE_ENTRIES - count;
    1066           0 :           while (-- skip > 0)
    1067           0 :             old_head = old_head->next;
    1068             : 
    1069           0 :           *old_head->prevp = NULL;
    1070             : 
    1071           0 :           while (old_head)
    1072             :             {
    1073           0 :               db = old_head->next;
    1074           0 :               closedb (old_head);
    1075           0 :               old_head = db;
    1076           0 :               db_cache_count --;
    1077             :             }
    1078             :         }
    1079             :     }
    1080             : 
    1081         266 :   xfree (dbs);
    1082             : 
    1083             : #if DEBUG_TOFU_CACHE
    1084             :   log_debug ("Queries: %d (prepares saved: %d)\n",
    1085             :              queries, prepares_saved);
    1086             : #endif
    1087         266 : }
    1088             : 
    1089             : 
    1090             : /* Collect results of a select min (foo) ...; style query.  Aborts if
    1091             :    the argument is not a valid integer (or real of the form X.0).  */
    1092             : static int
    1093           8 : get_single_long_cb (void *cookie, int argc, char **argv, char **azColName)
    1094             : {
    1095           8 :   long *count = cookie;
    1096           8 :   char *tail = NULL;
    1097             : 
    1098             :   (void) azColName;
    1099             : 
    1100           8 :   assert (argc == 1);
    1101             : 
    1102           8 :   errno = 0;
    1103           8 :   *count = strtol (argv[0], &tail, 0);
    1104           8 :   if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0'))
    1105             :     /* Abort.  */
    1106           0 :     return 1;
    1107           8 :   return 0;
    1108             : }
    1109             : 
    1110             : static int
    1111           8 : get_single_long_cb2 (void *cookie, int argc, char **argv, char **azColName,
    1112             :                      sqlite3_stmt *stmt)
    1113             : {
    1114             :   (void) stmt;
    1115           8 :   return get_single_long_cb (cookie, argc, argv, azColName);
    1116             : }
    1117             : 
    1118             : /* Record (or update) a trust policy about a (possibly new)
    1119             :    binding.
    1120             : 
    1121             :    If SHOW_OLD is set, the binding's old policy is displayed.  */
    1122             : static gpg_error_t
    1123          14 : record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
    1124             :                 const char *user_id, enum tofu_policy policy, int show_old)
    1125             : {
    1126          14 :   char *fingerprint_pp = fingerprint_format (fingerprint);
    1127          14 :   struct db *db_email = NULL, *db_key = NULL;
    1128             :   int rc;
    1129          14 :   char *err = NULL;
    1130          14 :   enum tofu_policy policy_old = TOFU_POLICY_NONE;
    1131             : 
    1132          18 :   if (! (policy == TOFU_POLICY_AUTO
    1133          10 :          || policy == TOFU_POLICY_GOOD
    1134           8 :          || policy == TOFU_POLICY_UNKNOWN
    1135           6 :          || policy == TOFU_POLICY_BAD
    1136             :          || policy == TOFU_POLICY_ASK))
    1137           0 :     log_bug ("%s: Bad value for policy (%d)!\n", __func__, policy);
    1138             : 
    1139          14 :   db_email = getdb (dbs, email, DB_EMAIL);
    1140          14 :   if (! db_email)
    1141           0 :     return gpg_error (GPG_ERR_GENERAL);
    1142             : 
    1143          14 :   if (opt.tofu_db_format == TOFU_DB_SPLIT)
    1144             :     /* In the split format, we need to update two DBs.  To keep them
    1145             :        consistent, we start a transaction on each.  Note: this is the
    1146             :        only place where we start two transaction and we always start
    1147             :        transaction on the DB_KEY DB first, thus deadlock is not
    1148             :        possible.  */
    1149             :     {
    1150           7 :       db_key = getdb (dbs, fingerprint, DB_KEY);
    1151           7 :       if (! db_key)
    1152           0 :         return gpg_error (GPG_ERR_GENERAL);
    1153             : 
    1154           7 :       rc = begin_transaction (db_email, 0);
    1155           7 :       if (rc)
    1156           0 :         return gpg_error (GPG_ERR_GENERAL);
    1157             : 
    1158           7 :       rc = begin_transaction (db_key, 0);
    1159           7 :       if (rc)
    1160           0 :         goto out_revert_one;
    1161             :     }
    1162             :   else
    1163             :     {
    1164           7 :       rc = begin_transaction (db_email, 1);
    1165           7 :       if (rc)
    1166           0 :         return gpg_error (GPG_ERR_GENERAL);
    1167             :     }
    1168             : 
    1169             : 
    1170          14 :   if (show_old)
    1171             :     /* Get the old policy.  Since this is just for informational
    1172             :        purposes, there is no need to start a transaction or to die if
    1173             :        there is a failure.  */
    1174             :     {
    1175           8 :       rc = sqlite3_stepx
    1176             :         (db_email->db, &db_email->s.record_binding_get_old_policy,
    1177             :          get_single_long_cb2, &policy_old, &err,
    1178             :          "select policy from bindings where fingerprint = ? and email = ?",
    1179             :          SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    1180             :          SQLITE_ARG_END);
    1181           8 :       if (rc)
    1182             :         {
    1183           0 :           log_debug ("TOFU: Error reading from binding database"
    1184             :                      " (reading policy for <%s, %s>): %s\n",
    1185             :                      fingerprint_pp, email, err);
    1186           0 :           sqlite3_free (err);
    1187             :         }
    1188             :     }
    1189             : 
    1190          14 :   if (DBG_TRUST)
    1191             :     {
    1192           0 :       if (policy_old != TOFU_POLICY_NONE)
    1193           0 :         log_debug ("Changing TOFU trust policy for binding <%s, %s>"
    1194             :                    " from %s to %s.\n",
    1195             :                    fingerprint_pp, email,
    1196             :                    tofu_policy_str (policy_old),
    1197             :                    tofu_policy_str (policy));
    1198             :       else
    1199           0 :         log_debug ("Set TOFU trust policy for binding <%s, %s> to %s.\n",
    1200             :                    fingerprint_pp, email,
    1201             :                    tofu_policy_str (policy));
    1202             :     }
    1203             : 
    1204          14 :   if (policy_old == policy)
    1205             :     /* Nothing to do.  */
    1206           0 :     goto out;
    1207             : 
    1208          14 :   rc = sqlite3_stepx
    1209             :     (db_email->db, &db_email->s.record_binding_update, NULL, NULL, &err,
    1210             :      "insert or replace into bindings\n"
    1211             :      " (oid, fingerprint, email, user_id, time, policy)\n"
    1212             :      " values (\n"
    1213             :      /* If we don't explicitly reuse the OID, then SQLite will
    1214             :         reallocate a new one.  We just need to search for the OID
    1215             :         based on the fingerprint and email since they are unique.  */
    1216             :      "  (select oid from bindings where fingerprint = ? and email = ?),\n"
    1217             :      "  ?, ?, ?, strftime('%s','now'), ?);",
    1218             :      SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    1219             :      SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    1220             :      SQLITE_ARG_STRING, user_id, SQLITE_ARG_INT, (int) policy,
    1221             :      SQLITE_ARG_END);
    1222          14 :   if (rc)
    1223             :     {
    1224           0 :       log_error (_("error updating TOFU binding database"
    1225             :                    " (inserting <%s, %s> = %s): %s\n"),
    1226             :                  fingerprint_pp, email, tofu_policy_str (policy),
    1227             :                  err);
    1228           0 :       sqlite3_free (err);
    1229           0 :       goto out;
    1230             :     }
    1231             : 
    1232          14 :   if (db_key)
    1233             :     /* We also need to update the key DB.  */
    1234             :     {
    1235           7 :       assert (opt.tofu_db_format == TOFU_DB_SPLIT);
    1236             : 
    1237           7 :       rc = sqlite3_stepx
    1238             :         (db_key->db, &db_key->s.record_binding_update2, NULL, NULL, &err,
    1239             :          "insert or replace into bindings\n"
    1240             :          " (oid, fingerprint, email, user_id)\n"
    1241             :          " values (\n"
    1242             :          /* If we don't explicitly reuse the OID, then SQLite will
    1243             :             reallocate a new one.  We just need to search for the OID
    1244             :             based on the fingerprint and email since they are unique.  */
    1245             :          "  (select oid from bindings where fingerprint = ? and email = ?),\n"
    1246             :          "  ?, ?, ?);",
    1247             :          SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    1248             :          SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    1249             :          SQLITE_ARG_STRING, user_id, SQLITE_ARG_END);
    1250           7 :       if (rc)
    1251             :         {
    1252           0 :           log_error (_("error updating TOFU binding database"
    1253             :                        " (inserting <%s, %s>): %s\n"),
    1254             :                      fingerprint_pp, email, err);
    1255           0 :           sqlite3_free (err);
    1256           0 :           goto out;
    1257             :         }
    1258             :     }
    1259             :   else
    1260           7 :     assert (opt.tofu_db_format == TOFU_DB_FLAT);
    1261             : 
    1262             :  out:
    1263          14 :   if (opt.tofu_db_format == TOFU_DB_SPLIT)
    1264             :     /* We only need a transaction for the split format.  */
    1265             :     {
    1266             :       int rc2;
    1267             : 
    1268           7 :       if (rc)
    1269           0 :         rc2 = rollback_transaction (db_key);
    1270             :       else
    1271           7 :         rc2 = end_transaction (db_key, 0);
    1272           7 :       if (rc2)
    1273             :         {
    1274           0 :           log_error (_("error ending transaction on TOFU database: %s\n"),
    1275             :                      err);
    1276           0 :           sqlite3_free (err);
    1277             :         }
    1278             : 
    1279             :     out_revert_one:
    1280           7 :       if (rc)
    1281           0 :         rc2 = rollback_transaction (db_email);
    1282             :       else
    1283           7 :         rc2 = end_transaction (db_email, 0);
    1284           7 :       if (rc2)
    1285             :         {
    1286           0 :           log_error (_("error ending transaction on TOFU database: %s\n"),
    1287             :                      err);
    1288           0 :           sqlite3_free (err);
    1289             :         }
    1290             :     }
    1291             : 
    1292          14 :   xfree (fingerprint_pp);
    1293             : 
    1294          14 :   if (rc)
    1295           0 :     return gpg_error (GPG_ERR_GENERAL);
    1296          14 :   return 0;
    1297             : }
    1298             : 
    1299             : 
    1300             : /* Collect the strings returned by a query in a simply string list.
    1301             :    Any NULL values are converted to the empty string.
    1302             : 
    1303             :    If a result has 3 rows and each row contains two columns, then the
    1304             :    results are added to the list as follows (the value is parentheses
    1305             :    is the 1-based index in the final list):
    1306             : 
    1307             :      row 1, col 2 (6)
    1308             :      row 1, col 1 (5)
    1309             :      row 2, col 2 (4)
    1310             :      row 2, col 1 (3)
    1311             :      row 3, col 2 (2)
    1312             :      row 3, col 1 (1)
    1313             : 
    1314             :    This is because add_to_strlist pushes the results onto the front of
    1315             :    the list.  The end result is that the rows are backwards, but the
    1316             :    columns are in the expected order.  */
    1317             : static int
    1318         270 : strings_collect_cb (void *cookie, int argc, char **argv, char **azColName)
    1319             : {
    1320             :   int i;
    1321         270 :   strlist_t *strlist = cookie;
    1322             : 
    1323             :   (void) azColName;
    1324             : 
    1325         810 :   for (i = argc - 1; i >= 0; i --)
    1326         540 :     add_to_strlist (strlist, argv[i] ? argv[i] : "");
    1327             : 
    1328         270 :   return 0;
    1329             : }
    1330             : 
    1331             : static int
    1332         264 : strings_collect_cb2 (void *cookie, int argc, char **argv, char **azColName,
    1333             :                      sqlite3_stmt *stmt)
    1334             : {
    1335             :   (void) stmt;
    1336         264 :   return strings_collect_cb (cookie, argc, argv, azColName);
    1337             : 
    1338             : }
    1339             : 
    1340             : /* Auxiliary data structure to collect statistics about
    1341             :    signatures.  */
    1342             : struct signature_stats
    1343             : {
    1344             :   struct signature_stats *next;
    1345             : 
    1346             :   /* The user-assigned policy for this binding.  */
    1347             :   enum tofu_policy policy;
    1348             : 
    1349             :   /* How long ago the signature was created (rounded to a multiple of
    1350             :      TIME_AGO_UNIT_SMALL, etc.).  */
    1351             :   long time_ago;
    1352             :   /* Number of signatures during this time.  */
    1353             :   unsigned long count;
    1354             : 
    1355             :   /* The key that generated this signature.  */
    1356             :   char fingerprint[1];
    1357             : };
    1358             : 
    1359             : static void
    1360           0 : signature_stats_free (struct signature_stats *stats)
    1361             : {
    1362           0 :   while (stats)
    1363             :     {
    1364           0 :       struct signature_stats *next = stats->next;
    1365           0 :       xfree (stats);
    1366           0 :       stats = next;
    1367             :     }
    1368           0 : }
    1369             : 
    1370             : static void
    1371           0 : signature_stats_prepend (struct signature_stats **statsp,
    1372             :                          const char *fingerprint,
    1373             :                          enum tofu_policy policy,
    1374             :                          long time_ago,
    1375             :                          unsigned long count)
    1376             : {
    1377           0 :   struct signature_stats *stats =
    1378           0 :     xmalloc (sizeof (*stats) + strlen (fingerprint));
    1379             : 
    1380           0 :   stats->next = *statsp;
    1381           0 :   *statsp = stats;
    1382             : 
    1383           0 :   strcpy (stats->fingerprint, fingerprint);
    1384           0 :   stats->policy = policy;
    1385           0 :   stats->time_ago = time_ago;
    1386           0 :   stats->count = count;
    1387           0 : }
    1388             : 
    1389             : 
    1390             : /* Process rows that contain the four columns:
    1391             : 
    1392             :      <fingerprint, policy, time ago, count>.  */
    1393             : static int
    1394           0 : signature_stats_collect_cb (void *cookie, int argc, char **argv,
    1395             :                             char **azColName, sqlite3_stmt *stmt)
    1396             : {
    1397           0 :   struct signature_stats **statsp = cookie;
    1398             :   char *tail;
    1399           0 :   int i = 0;
    1400             :   enum tofu_policy policy;
    1401             :   long time_ago;
    1402             :   unsigned long count;
    1403             : 
    1404             :   (void) azColName;
    1405             :   (void) stmt;
    1406             : 
    1407           0 :   i ++;
    1408             : 
    1409           0 :   tail = NULL;
    1410           0 :   errno = 0;
    1411           0 :   policy = strtol (argv[i], &tail, 0);
    1412           0 :   if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0'))
    1413             :     {
    1414             :       /* Abort.  */
    1415           0 :       log_error ("%s: Error converting %s to an integer (tail = '%s')\n",
    1416           0 :                  __func__, argv[i], tail);
    1417           0 :       return 1;
    1418             :     }
    1419           0 :   i ++;
    1420             : 
    1421           0 :   if (! argv[i])
    1422           0 :     time_ago = 0;
    1423             :   else
    1424             :     {
    1425           0 :       tail = NULL;
    1426           0 :       errno = 0;
    1427           0 :       time_ago = strtol (argv[i], &tail, 0);
    1428           0 :       if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0'))
    1429             :         {
    1430             :           /* Abort.  */
    1431           0 :           log_error ("%s: Error converting %s to an integer (tail = '%s')\n",
    1432           0 :                      __func__, argv[i], tail);
    1433           0 :           return 1;
    1434             :         }
    1435             :     }
    1436           0 :   i ++;
    1437             : 
    1438             :   /* If time_ago is NULL, then we had no messages, but we still have a
    1439             :      single row, which count(*) turns into 1.  */
    1440           0 :   if (! argv[i - 1])
    1441           0 :     count = 0;
    1442             :   else
    1443             :     {
    1444           0 :       tail = NULL;
    1445           0 :       errno = 0;
    1446           0 :       count = strtoul (argv[i], &tail, 0);
    1447           0 :       if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0'))
    1448             :         {
    1449             :           /* Abort.  */
    1450           0 :           log_error ("%s: Error converting %s to an integer (tail = '%s')\n",
    1451           0 :                      __func__, argv[i], tail);
    1452           0 :           return 1;
    1453             :         }
    1454             :     }
    1455           0 :   i ++;
    1456             : 
    1457           0 :   assert (argc == i);
    1458             : 
    1459           0 :   signature_stats_prepend (statsp, argv[0], policy, time_ago, count);
    1460             : 
    1461           0 :   return 0;
    1462             : }
    1463             : 
    1464             : /* Convert from seconds to time units.
    1465             : 
    1466             :    Note: T should already be a multiple of TIME_AGO_UNIT_SMALL or
    1467             :    TIME_AGO_UNIT_MEDIUM or TIME_AGO_UNIT_LARGE.  */
    1468             : signed long
    1469           0 : time_ago_scale (signed long t)
    1470             : {
    1471           0 :   if (t < TIME_AGO_UNIT_MEDIUM)
    1472           0 :     return t / TIME_AGO_UNIT_SMALL;
    1473           0 :   if (t < TIME_AGO_UNIT_LARGE)
    1474           0 :     return t / TIME_AGO_UNIT_MEDIUM;
    1475           0 :   return t / TIME_AGO_UNIT_LARGE;
    1476             : }
    1477             : 
    1478             : /* Return the appropriate unit (respecting whether it is plural or
    1479             :    singular).  */
    1480             : const char *
    1481           0 : time_ago_unit (signed long t)
    1482             : {
    1483           0 :   signed long t_scaled = time_ago_scale (t);
    1484             : 
    1485           0 :   if (t < TIME_AGO_UNIT_MEDIUM)
    1486             :     {
    1487           0 :       if (t_scaled == 1)
    1488           0 :         return TIME_AGO_UNIT_SMALL_NAME;
    1489           0 :       return TIME_AGO_UNIT_SMALL_NAME_PLURAL;
    1490             :     }
    1491           0 :   if (t < TIME_AGO_UNIT_LARGE)
    1492             :     {
    1493           0 :       if (t_scaled == 1)
    1494           0 :         return TIME_AGO_UNIT_MEDIUM_NAME;
    1495           0 :       return TIME_AGO_UNIT_MEDIUM_NAME_PLURAL;
    1496             :     }
    1497           0 :   if (t_scaled == 1)
    1498           0 :     return TIME_AGO_UNIT_LARGE_NAME;
    1499           0 :   return TIME_AGO_UNIT_LARGE_NAME_PLURAL;
    1500             : }
    1501             : 
    1502             : 
    1503             : /* Return the policy for the binding <FINGERPRINT, EMAIL> (email has
    1504             :    already been normalized) and any conflict information in *CONFLICT
    1505             :    if CONFLICT is not NULL.  Returns _tofu_GET_POLICY_ERROR if an error
    1506             :    occurs.  */
    1507             : static enum tofu_policy
    1508         264 : get_policy (struct dbs *dbs, const char *fingerprint, const char *email,
    1509             :             char **conflict)
    1510             : {
    1511             :   struct db *db;
    1512             :   int rc;
    1513         264 :   char *err = NULL;
    1514         264 :   strlist_t strlist = NULL;
    1515         264 :   char *tail = NULL;
    1516         264 :   enum tofu_policy policy = _tofu_GET_POLICY_ERROR;
    1517             : 
    1518         264 :   db = getdb (dbs, email, DB_EMAIL);
    1519         264 :   if (! db)
    1520           0 :     return _tofu_GET_POLICY_ERROR;
    1521             : 
    1522             :   /* Check if the <FINGERPRINT, EMAIL> binding is known
    1523             :      (TOFU_POLICY_NONE cannot appear in the DB.  Thus, if POLICY is
    1524             :      still TOFU_POLICY_NONE after executing the query, then the
    1525             :      result set was empty.)  */
    1526         264 :   rc = sqlite3_stepx (db->db, &db->s.get_policy_select_policy_and_conflict,
    1527             :                       strings_collect_cb2, &strlist, &err,
    1528             :                       "select policy, conflict from bindings\n"
    1529             :                       " where fingerprint = ? and email = ?",
    1530             :                       SQLITE_ARG_STRING, fingerprint,
    1531             :                       SQLITE_ARG_STRING, email,
    1532             :                       SQLITE_ARG_END);
    1533         264 :   if (rc)
    1534             :     {
    1535           0 :       log_error (_("error reading from TOFU database"
    1536             :                    " (checking for existing bad bindings): %s\n"),
    1537             :                  err);
    1538           0 :       sqlite3_free (err);
    1539           0 :       goto out;
    1540             :     }
    1541             : 
    1542         264 :   if (strlist_length (strlist) == 0)
    1543             :     /* No results.  */
    1544             :     {
    1545           6 :       policy = TOFU_POLICY_NONE;
    1546           6 :       goto out;
    1547             :     }
    1548         258 :   else if (strlist_length (strlist) != 2)
    1549             :     /* The result has the wrong form.  */
    1550             :     {
    1551           0 :       log_error (_("error reading from TOFU database"
    1552             :                    " (checking for existing bad bindings):"
    1553             :                    " expected 2 results, got %d\n"),
    1554             :                  strlist_length (strlist));
    1555           0 :       goto out;
    1556             :     }
    1557             : 
    1558             :   /* The result has the right form.  */
    1559             : 
    1560         258 :   errno = 0;
    1561         258 :   policy = strtol (strlist->d, &tail, 0);
    1562         258 :   if (errno || *tail != '\0')
    1563             :     {
    1564           0 :       log_error (_("error reading from TOFU database: bad value for policy: %s\n"),
    1565           0 :                  strlist->d);
    1566           0 :       goto out;
    1567             :     }
    1568             : 
    1569         284 :   if (! (policy == TOFU_POLICY_AUTO
    1570         218 :          || policy == TOFU_POLICY_GOOD
    1571         158 :          || policy == TOFU_POLICY_UNKNOWN
    1572          98 :          || policy == TOFU_POLICY_BAD
    1573             :          || policy == TOFU_POLICY_ASK))
    1574             :     {
    1575           0 :       log_error (_("TOFU DB is corrupted.  Invalid value for policy (%d).\n"),
    1576             :                  policy);
    1577           0 :       policy = _tofu_GET_POLICY_ERROR;
    1578           0 :       goto out;
    1579             :     }
    1580             : 
    1581             : 
    1582             :   /* If CONFLICT is set, then policy should be TOFU_POLICY_ASK.  But,
    1583             :      just in case, we do the check again here and ignore the conflict
    1584             :      is POLICY is not TOFU_POLICY_ASK.  */
    1585         258 :   if (conflict)
    1586             :     {
    1587         170 :       if (policy == TOFU_POLICY_ASK && *strlist->next->d)
    1588          16 :         *conflict = xstrdup (strlist->next->d);
    1589             :       else
    1590         154 :         *conflict = NULL;
    1591             :     }
    1592             : 
    1593             :  out:
    1594         264 :   assert (policy == _tofu_GET_POLICY_ERROR
    1595             :           || policy == TOFU_POLICY_NONE
    1596             :           || policy == TOFU_POLICY_AUTO
    1597             :           || policy == TOFU_POLICY_GOOD
    1598             :           || policy == TOFU_POLICY_UNKNOWN
    1599             :           || policy == TOFU_POLICY_BAD
    1600             :           || policy == TOFU_POLICY_ASK);
    1601             : 
    1602         264 :   free_strlist (strlist);
    1603             : 
    1604         264 :   return policy;
    1605             : }
    1606             : 
    1607             : /* Return the trust level (TRUST_NEVER, etc.) for the binding
    1608             :    <FINGERPRINT, EMAIL> (email is already normalized).  If no policy
    1609             :    is registered, returns TOFU_POLICY_NONE.  If an error occurs,
    1610             :    returns _tofu_GET_TRUST_ERROR.
    1611             : 
    1612             :    USER_ID is the unadultered user id.
    1613             : 
    1614             :    If MAY_ASK is set, then we may interact with the user.  This is
    1615             :    necessary if there is a conflict or the binding's policy is
    1616             :    TOFU_POLICY_ASK.  In the case of a conflict, we set the new
    1617             :    conflicting binding's policy to TOFU_POLICY_ASK.  In either case,
    1618             :    we return TRUST_UNDEFINED.  */
    1619             : static enum tofu_policy
    1620         176 : get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
    1621             :            const char *user_id, int may_ask)
    1622             : {
    1623             :   char *fingerprint_pp;
    1624             :   struct db *db;
    1625             :   enum tofu_policy policy;
    1626         176 :   char *conflict = NULL;
    1627             :   int rc;
    1628         176 :   char *err = NULL;
    1629         176 :   strlist_t bindings_with_this_email = NULL;
    1630             :   int bindings_with_this_email_count;
    1631         176 :   int change_conflicting_to_ask = 0;
    1632         176 :   int trust_level = TRUST_UNKNOWN;
    1633             : 
    1634         176 :   if (opt.batch)
    1635         176 :     may_ask = 0;
    1636             : 
    1637             :   /* Make sure _tofu_GET_TRUST_ERROR isn't equal to any of the trust
    1638             :      levels.  */
    1639             :   assert (_tofu_GET_TRUST_ERROR != TRUST_UNKNOWN
    1640             :           && _tofu_GET_TRUST_ERROR != TRUST_EXPIRED
    1641             :           && _tofu_GET_TRUST_ERROR != TRUST_UNDEFINED
    1642             :           && _tofu_GET_TRUST_ERROR != TRUST_NEVER
    1643             :           && _tofu_GET_TRUST_ERROR != TRUST_MARGINAL
    1644             :           && _tofu_GET_TRUST_ERROR != TRUST_FULLY
    1645             :           && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE);
    1646             : 
    1647         176 :   db = getdb (dbs, email, DB_EMAIL);
    1648         176 :   if (! db)
    1649           0 :     return _tofu_GET_TRUST_ERROR;
    1650             : 
    1651         176 :   fingerprint_pp = fingerprint_format (fingerprint);
    1652             : 
    1653         176 :   policy = get_policy (dbs, fingerprint, email, &conflict);
    1654         176 :   if (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_NONE)
    1655             :     /* See if the key is ultimately trusted.  If so, we're done.  */
    1656             :     {
    1657             :       const char *keyid;
    1658             :       KEYDB_SEARCH_DESC desc;
    1659             : 
    1660             :       /* We need to convert the fingerprint as a string to a long
    1661             :          keyid.
    1662             : 
    1663             :          FINGERPRINT is stored as follows:
    1664             : 
    1665             :            362D3527F53AAD1971AAFDE658859975EE37CF96
    1666             :                                 -------------------
    1667             : 
    1668             :          The last 16 characters are the long keyid.
    1669             :       */
    1670          32 :       assert (strlen (fingerprint) > 4 * 4);
    1671          32 :       keyid = &fingerprint[strlen (fingerprint) - 16];
    1672             : 
    1673          32 :       rc = classify_user_id (keyid, &desc, 1);
    1674          32 :       if (rc || desc.mode != KEYDB_SEARCH_MODE_LONG_KID)
    1675             :         {
    1676           0 :           log_error (_("'%s' is not a valid long keyID\n"), keyid);
    1677           0 :           goto out;
    1678             :         }
    1679             : 
    1680          32 :       if (tdb_keyid_is_utk (desc.u.kid))
    1681             :         {
    1682           0 :           if (policy == TOFU_POLICY_NONE)
    1683             :             {
    1684           0 :               if (record_binding (dbs, fingerprint, email, user_id,
    1685             :                                   TOFU_POLICY_AUTO, 0) != 0)
    1686             :                 {
    1687           0 :                   log_error (_("error setting TOFU binding's trust level"
    1688             :                                " to %s\n"), "auto");
    1689           0 :                   trust_level = _tofu_GET_TRUST_ERROR;
    1690           0 :                   goto out;
    1691             :                 }
    1692             :             }
    1693             : 
    1694           0 :           trust_level = TRUST_ULTIMATE;
    1695           0 :           goto out;
    1696             :         }
    1697             :     }
    1698             : 
    1699         176 :   if (policy == TOFU_POLICY_AUTO)
    1700             :     {
    1701          26 :       policy = opt.tofu_default_policy;
    1702          26 :       if (DBG_TRUST)
    1703           0 :         log_debug ("TOFU: binding <%s, %s>'s policy is auto (default: %s).\n",
    1704             :                    fingerprint_pp, email,
    1705             :                    tofu_policy_str (opt.tofu_default_policy));
    1706             :     }
    1707         176 :   switch (policy)
    1708             :     {
    1709             :     case TOFU_POLICY_AUTO:
    1710             :     case TOFU_POLICY_GOOD:
    1711             :     case TOFU_POLICY_UNKNOWN:
    1712             :     case TOFU_POLICY_BAD:
    1713             :       /* The saved judgement is auto -> auto, good, unknown or bad.
    1714             :          We don't need to ask the user anything.  */
    1715         154 :       if (DBG_TRUST)
    1716           0 :         log_debug ("TOFU: Known binding <%s, %s>'s policy: %s\n",
    1717             :                    fingerprint_pp, email, tofu_policy_str (policy));
    1718         154 :       trust_level = tofu_policy_to_trust_level (policy);
    1719         154 :       goto out;
    1720             : 
    1721             :     case TOFU_POLICY_ASK:
    1722             :       /* We need to ask the user what to do.  Case #1 or #2 below.  */
    1723          16 :       if (! may_ask)
    1724             :         {
    1725          16 :           trust_level = TRUST_UNDEFINED;
    1726          16 :           goto out;
    1727             :         }
    1728             : 
    1729           0 :       break;
    1730             : 
    1731             :     case TOFU_POLICY_NONE:
    1732             :       /* The binding is new, we need to check for conflicts.  Case #3
    1733             :          below.  */
    1734           6 :       break;
    1735             : 
    1736             :     case _tofu_GET_POLICY_ERROR:
    1737           0 :       trust_level = _tofu_GET_TRUST_ERROR;
    1738           0 :       goto out;
    1739             : 
    1740             :     default:
    1741           0 :       log_bug ("%s: Impossible value for policy (%d)\n", __func__, policy);
    1742             :     }
    1743             : 
    1744             : 
    1745             :   /* We get here if:
    1746             : 
    1747             :        1. The saved policy is auto and the default policy is ask
    1748             :           (get_policy() == TOFU_POLICY_AUTO
    1749             :            && opt.tofu_default_policy == TOFU_POLICY_ASK)
    1750             : 
    1751             :        2. The saved policy is ask (either last time the user selected
    1752             :           accept once or reject once or there was a conflict and this
    1753             :           binding's policy was changed from auto to ask)
    1754             :           (policy == TOFU_POLICY_ASK), or,
    1755             : 
    1756             :        3. We don't have a saved policy (policy == TOFU_POLICY_NONE)
    1757             :           (need to check for a conflict).
    1758             :    */
    1759             : 
    1760             :   /* Look for conflicts.  This is needed in all 3 cases.
    1761             : 
    1762             :      Get the fingerprints of any bindings that share the email
    1763             :      address.  Note: if the binding in question is in the DB, it will
    1764             :      also be returned.  Thus, if the result set is empty, then this is
    1765             :      a new binding.  */
    1766           6 :   rc = sqlite3_stepx
    1767             :     (db->db, &db->s.get_trust_bindings_with_this_email,
    1768             :      strings_collect_cb2, &bindings_with_this_email, &err,
    1769             :      "select distinct fingerprint from bindings where email = ?;",
    1770             :      SQLITE_ARG_STRING, email, SQLITE_ARG_END);
    1771           6 :   if (rc)
    1772             :     {
    1773           0 :       log_error (_("error reading from TOFU database"
    1774             :                    " (listing fingerprints): %s\n"),
    1775             :                  err);
    1776           0 :       sqlite3_free (err);
    1777           0 :       goto out;
    1778             :     }
    1779             : 
    1780           6 :   bindings_with_this_email_count = strlist_length (bindings_with_this_email);
    1781           6 :   if (bindings_with_this_email_count == 0
    1782           2 :       && opt.tofu_default_policy != TOFU_POLICY_ASK)
    1783             :     /* New binding with no conflict and a concrete default policy.
    1784             : 
    1785             :        We've never observed a binding with this email address
    1786             :        (BINDINGS_WITH_THIS_EMAIL_COUNT is 0 and the above query would return
    1787             :        the current binding if it were in the DB) and we have a default
    1788             :        policy, which is not to ask the user.  */
    1789             :     {
    1790             :       /* If we've seen this binding, then we've seen this email and
    1791             :          policy couldn't possibly be TOFU_POLICY_NONE.  */
    1792           2 :       assert (policy == TOFU_POLICY_NONE);
    1793             : 
    1794           2 :       if (DBG_TRUST)
    1795           0 :         log_debug ("TOFU: New binding <%s, %s>, no conflict.\n",
    1796             :                    email, fingerprint_pp);
    1797             : 
    1798           2 :       if (record_binding (dbs, fingerprint, email, user_id,
    1799             :                           TOFU_POLICY_AUTO, 0) != 0)
    1800             :         {
    1801           0 :           log_error (_("error setting TOFU binding's trust level to %s\n"),
    1802             :                        "auto");
    1803           0 :           trust_level = _tofu_GET_TRUST_ERROR;
    1804           0 :           goto out;
    1805             :         }
    1806             : 
    1807           2 :       trust_level = tofu_policy_to_trust_level (TOFU_POLICY_AUTO);
    1808           2 :       goto out;
    1809             :     }
    1810             : 
    1811           4 :   if (policy == TOFU_POLICY_NONE)
    1812             :     /* This is a new binding and we have a conflict.  Mark any
    1813             :        conflicting bindings that have an automatic policy as now
    1814             :        requiring confirmation.  Note: we delay this until after we ask
    1815             :        for confirmation so that when the current policy is printed, it
    1816             :        is correct.  */
    1817           4 :     change_conflicting_to_ask = 1;
    1818             : 
    1819           4 :   if (! may_ask)
    1820             :     /* We can only get here in the third case (no saved policy) and if
    1821             :        there is a conflict.  (If the policy was ask (cases #1 and #2)
    1822             :        and we weren't allowed to ask, we'd have already exited).  */
    1823             :     {
    1824           4 :       assert (policy == TOFU_POLICY_NONE);
    1825             : 
    1826           4 :       if (record_binding (dbs, fingerprint, email, user_id,
    1827             :                           TOFU_POLICY_ASK, 0) != 0)
    1828           0 :         log_error (_("error setting TOFU binding's trust level to %s\n"),
    1829             :                    "ask");
    1830             : 
    1831           4 :       trust_level = TRUST_UNDEFINED;
    1832           4 :       goto out;
    1833             :     }
    1834             : 
    1835             :   /* If we get here, we need to ask the user about the binding.  There
    1836             :      are three ways we could end up here:
    1837             : 
    1838             :        - This is a new binding and there is a conflict
    1839             :          (policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0),
    1840             : 
    1841             :        - This is a new binding and opt.tofu_default_policy is set to
    1842             :          ask.  (policy == TOFU_POLICY_NONE && opt.tofu_default_policy ==
    1843             :          TOFU_POLICY_ASK), or,
    1844             : 
    1845             :        - The policy is ask (the user deferred last time) (policy ==
    1846             :          TOFU_POLICY_ASK).
    1847             :    */
    1848             :   {
    1849           0 :     int is_conflict =
    1850           0 :       ((policy == TOFU_POLICY_NONE && bindings_with_this_email_count > 0)
    1851           0 :        || (policy == TOFU_POLICY_ASK && conflict));
    1852             :     estream_t fp;
    1853             :     char *binding;
    1854             :     int binding_shown;
    1855           0 :     strlist_t other_user_ids = NULL;
    1856           0 :     struct signature_stats *stats = NULL;
    1857           0 :     struct signature_stats *stats_iter = NULL;
    1858             :     char *prompt;
    1859             :     char *choices;
    1860             : 
    1861           0 :     fp = es_fopenmem (0, "rw,samethread");
    1862           0 :     if (! fp)
    1863           0 :       log_fatal ("Error creating memory stream\n");
    1864             : 
    1865           0 :     binding = xasprintf ("<%s, %s>", fingerprint_pp, email);
    1866           0 :     binding_shown = 0;
    1867             : 
    1868           0 :     if (policy == TOFU_POLICY_NONE)
    1869             :       {
    1870           0 :         es_fprintf (fp, _("The binding %s is NOT known.  "), binding);
    1871           0 :         binding_shown = 1;
    1872             :       }
    1873           0 :     else if (policy == TOFU_POLICY_ASK
    1874             :              /* If there the conflict is with itself, then don't
    1875             :                 display this message.  */
    1876           0 :              && conflict && strcmp (conflict, fingerprint) != 0)
    1877             :       {
    1878           0 :         char *conflict_pp = fingerprint_format (conflict);
    1879           0 :         es_fprintf (fp,
    1880           0 :                     _("The key %s raised a conflict with this binding (%s)."
    1881             :                       "  Since this binding's policy was 'auto', it was "
    1882             :                       "changed to 'ask'.  "),
    1883             :                     conflict_pp, binding);
    1884           0 :         xfree (conflict_pp);
    1885           0 :         binding_shown = 1;
    1886             :       }
    1887           0 :     es_fprintf (fp,
    1888           0 :                 _("Please indicate whether you believe the binding %s%s"
    1889             :                   "is legitimate (the key belongs to the stated owner) "
    1890             :                   "or a forgery (bad).\n\n"),
    1891             :                 binding_shown ? "" : binding,
    1892             :                 binding_shown ? "" : " ");
    1893             : 
    1894           0 :     xfree (binding);
    1895             : 
    1896             :     /* Find other user ids associated with this key and whether the
    1897             :        bindings are marked as good or bad.  */
    1898             :     {
    1899             :       struct db *db_key;
    1900             : 
    1901           0 :       if (opt.tofu_db_format == TOFU_DB_SPLIT)
    1902             :         /* In the split format, we need to search in the fingerprint
    1903             :            DB for all the emails associated with this key, not the
    1904             :            email DB.  */
    1905           0 :         db_key = getdb (dbs, fingerprint, DB_KEY);
    1906             :       else
    1907           0 :         db_key = db;
    1908             : 
    1909           0 :       if (db_key)
    1910             :         {
    1911           0 :           rc = sqlite3_stepx
    1912             :             (db_key->db, &db_key->s.get_trust_gather_other_user_ids,
    1913             :              strings_collect_cb2, &other_user_ids, &err,
    1914           0 :              opt.tofu_db_format == TOFU_DB_SPLIT
    1915             :              ? "select user_id, email from bindings where fingerprint = ?;"
    1916             :              : "select user_id, policy from bindings where fingerprint = ?;",
    1917             :              SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END);
    1918           0 :           if (rc)
    1919             :             {
    1920           0 :               log_error (_("error gathering other user ids: %s.\n"), err);
    1921           0 :               sqlite3_free (err);
    1922           0 :               err = NULL;
    1923             :             }
    1924             :         }
    1925             :     }
    1926             : 
    1927           0 :     if (other_user_ids)
    1928             :       {
    1929             :         strlist_t strlist_iter;
    1930             : 
    1931           0 :         es_fprintf (fp, _("Known user ids associated with this key:\n"));
    1932           0 :         for (strlist_iter = other_user_ids;
    1933             :              strlist_iter;
    1934           0 :              strlist_iter = strlist_iter->next)
    1935             :           {
    1936           0 :             char *other_user_id = strlist_iter->d;
    1937             :             char *other_thing;
    1938             :             enum tofu_policy other_policy;
    1939             : 
    1940           0 :             assert (strlist_iter->next);
    1941           0 :             strlist_iter = strlist_iter->next;
    1942           0 :             other_thing = strlist_iter->d;
    1943             : 
    1944           0 :             if (opt.tofu_db_format == TOFU_DB_SPLIT)
    1945           0 :               other_policy = get_policy (dbs, fingerprint, other_thing, NULL);
    1946             :             else
    1947           0 :               other_policy = atoi (other_thing);
    1948             : 
    1949           0 :             es_fprintf (fp, _("  %s (policy: %s)\n"),
    1950             :                         other_user_id,
    1951             :                         tofu_policy_str (other_policy));
    1952             :           }
    1953           0 :         es_fprintf (fp, "\n");
    1954             : 
    1955           0 :         free_strlist (other_user_ids);
    1956             :       }
    1957             : 
    1958             :     /* Find other keys associated with this email address.  */
    1959             :     /* XXX: When generating the statistics, do we want the time
    1960             :        embedded in the signature (column 'sig_time') or the time that
    1961             :        we first verified the signature (column 'time').  */
    1962           0 :     rc = sqlite3_stepx
    1963             :       (db->db, &db->s.get_trust_gather_other_keys,
    1964             :        signature_stats_collect_cb, &stats, &err,
    1965             :        "select fingerprint, policy, time_ago, count(*)\n"
    1966             :        " from (select bindings.*,\n"
    1967             :        "        case\n"
    1968             :        /* From the future (but if its just a couple of hours in the
    1969             :           future don't turn it into a warning)?  Or should we use
    1970             :           small, medium or large units?  (Note: whatever we do, we
    1971             :           keep the value in seconds.  Then when we group, everything
    1972             :           that rounds to the same number of seconds is grouped.)  */
    1973             :        "         when delta < -("STRINGIFY (TIME_AGO_FUTURE_IGNORE)") then -1\n"
    1974             :        "         when delta < ("STRINGIFY (TIME_AGO_MEDIUM_THRESHOLD)")\n"
    1975             :        "          then max(0,\n"
    1976             :        "                   round(delta / ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
    1977             :        "               * ("STRINGIFY (TIME_AGO_UNIT_SMALL)"))\n"
    1978             :        "         when delta < ("STRINGIFY (TIME_AGO_LARGE_THRESHOLD)")\n"
    1979             :        "          then round(delta / ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)"))\n"
    1980             :        "               * ("STRINGIFY (TIME_AGO_UNIT_MEDIUM)")\n"
    1981             :        "         else round(delta / ("STRINGIFY (TIME_AGO_UNIT_LARGE)"))\n"
    1982             :        "              * ("STRINGIFY (TIME_AGO_UNIT_LARGE)")\n"
    1983             :        "        end time_ago,\n"
    1984             :        "        delta time_ago_raw\n"
    1985             :        "       from bindings\n"
    1986             :        "       left join\n"
    1987             :        "         (select *,\n"
    1988             :        "            cast(strftime('%s','now') - sig_time as real) delta\n"
    1989             :        "           from signatures) ss\n"
    1990             :        "        on ss.binding = bindings.oid)\n"
    1991             :        " where email = ?\n"
    1992             :        " group by fingerprint, time_ago\n"
    1993             :        /* Make sure the current key is first.  */
    1994             :        " order by fingerprint = ? asc, fingerprint desc, time_ago desc;\n",
    1995             :        SQLITE_ARG_STRING, email, SQLITE_ARG_STRING, fingerprint,
    1996             :        SQLITE_ARG_END);
    1997           0 :     if (rc)
    1998             :       {
    1999             :         strlist_t strlist_iter;
    2000             : 
    2001           0 :         log_error (_("error gathering signature stats: %s.\n"),
    2002             :                    err);
    2003           0 :         sqlite3_free (err);
    2004           0 :         err = NULL;
    2005             : 
    2006           0 :         es_fprintf
    2007           0 :           (fp, _("The email address (%s) is associated with %d keys:\n"),
    2008             :            email, bindings_with_this_email_count);
    2009           0 :         for (strlist_iter = bindings_with_this_email;
    2010             :              strlist_iter;
    2011           0 :              strlist_iter = strlist_iter->next)
    2012           0 :           es_fprintf (fp, _("  %s\n"), strlist_iter->d);
    2013             :       }
    2014             :     else
    2015             :       {
    2016           0 :         char *key = NULL;
    2017             : 
    2018           0 :         if (! stats || strcmp (stats->fingerprint, fingerprint) != 0)
    2019             :           /* If we have already added this key to the DB, then it will
    2020             :              be first (see the above select).  Since the first key on
    2021             :              the list is not this key, we must not yet have verified
    2022             :              any messages signed by this key.  Add a dummy entry.  */
    2023           0 :           signature_stats_prepend (&stats, fingerprint, TOFU_POLICY_AUTO, 0, 0);
    2024             : 
    2025           0 :         es_fprintf (fp, _("Statistics for keys with the email '%s':\n"),
    2026             :                     email);
    2027           0 :         for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next)
    2028             :           {
    2029           0 :             if (! key || strcmp (key, stats_iter->fingerprint) != 0)
    2030             :               {
    2031             :                 int this_key;
    2032             :                 char *key_pp;
    2033           0 :                 key = stats_iter->fingerprint;
    2034           0 :                 this_key = strcmp (key, fingerprint) == 0;
    2035           0 :                 key_pp = fingerprint_format (key);
    2036           0 :                 if (this_key)
    2037           0 :                   es_fprintf (fp, _("  %s (this key):"), key_pp);
    2038             :                 else
    2039           0 :                   es_fprintf (fp, _("  %s (policy: %s):"),
    2040             :                               key_pp, tofu_policy_str (stats_iter->policy));
    2041           0 :                 xfree (key_pp);
    2042           0 :                 es_fprintf (fp, "\n");
    2043             :               }
    2044             : 
    2045           0 :             if (stats_iter->time_ago == -1)
    2046           0 :               es_fprintf (fp, _("    %ld %s signed in the future.\n"),
    2047             :                           stats_iter->count,
    2048           0 :                           stats_iter->count == 1
    2049             :                           ? _("message") : _("messages"));
    2050           0 :             else if (stats_iter->count == 0)
    2051           0 :               es_fprintf (fp, _("    0 signed messages.\n"));
    2052             :             else
    2053           0 :               es_fprintf (fp, _("    %ld %s signed over the past %ld %s.\n"),
    2054             :                           stats_iter->count,
    2055           0 :                           stats_iter->count == 1
    2056             :                           ? _("message") : _("messages"),
    2057             :                           time_ago_scale (stats_iter->time_ago),
    2058             :                           time_ago_unit (stats_iter->time_ago));
    2059             :           }
    2060             :       }
    2061             : 
    2062           0 :     if (is_conflict)
    2063             :       {
    2064             :         /* TRANSLATORS: translate the below text.  We don't directly
    2065             :            internationalize that text so that we can tweak it without
    2066             :            breaking translations.  */
    2067           0 :         char *text = _("TOFU detected a binding conflict");
    2068           0 :         if (strcmp (text, "TOFU detected a binding conflict") == 0)
    2069             :           /* No translation.  Use the English text.  */
    2070           0 :           text =
    2071             :             "Normally, there is only a single key associated with an email "
    2072             :             "address.  However, people sometimes generate a new key if "
    2073             :             "their key is too old or they think it might be compromised.  "
    2074             :             "Alternatively, a new key may indicate a man-in-the-middle "
    2075             :             "attack!  Before accepting this key, you should talk to or "
    2076             :             "call the person to make sure this new key is legitimate.";
    2077           0 :         es_fprintf (fp, "\n%s\n", text);
    2078             :       }
    2079             : 
    2080           0 :     es_fputc ('\n', fp);
    2081             :     /* TRANSLATORS: Two letters (normally the lower and upper case
    2082             :        version of the hotkey) for each of the five choices.  If there
    2083             :        is only one choice in your language, repeat it.  */
    2084           0 :     choices = _("gG" "aA" "uU" "rR" "bB");
    2085           0 :     es_fprintf (fp, _("(G)ood/(A)ccept once/(U)nknown/(R)eject once/(B)ad? "));
    2086             : 
    2087             :     /* Add a NUL terminator.  */
    2088           0 :     es_fputc (0, fp);
    2089           0 :     if (es_fclose_snatch (fp, (void **) &prompt, NULL))
    2090           0 :       log_fatal ("error snatching memory stream\n");
    2091             : 
    2092             :     while (1)
    2093             :       {
    2094             :         char *response;
    2095             : 
    2096           0 :         if (strlen (choices) != 10)
    2097           0 :           log_bug ("Bad TOFU conflict translation!  Please report.");
    2098             : 
    2099           0 :         response = cpr_get ("tofu conflict", prompt);
    2100           0 :         trim_spaces (response);
    2101           0 :         cpr_kill_prompt ();
    2102           0 :         if (strlen (response) == 1)
    2103             :           {
    2104           0 :             char *choice = strchr (choices, *response);
    2105           0 :             if (choice)
    2106             :               {
    2107           0 :                 int c = ((size_t) choice - (size_t) choices) / 2;
    2108           0 :                 assert (0 <= c && c <= 4);
    2109             : 
    2110           0 :                 switch (c)
    2111             :                   {
    2112             :                   case 0: /* Good.  */
    2113           0 :                     policy = TOFU_POLICY_GOOD;
    2114           0 :                     trust_level = tofu_policy_to_trust_level (policy);
    2115           0 :                     break;
    2116             :                   case 1: /* Accept once.  */
    2117           0 :                     policy = TOFU_POLICY_ASK;
    2118           0 :                     trust_level =
    2119             :                       tofu_policy_to_trust_level (TOFU_POLICY_GOOD);
    2120           0 :                     break;
    2121             :                   case 2: /* Unknown.  */
    2122           0 :                     policy = TOFU_POLICY_UNKNOWN;
    2123           0 :                     trust_level = tofu_policy_to_trust_level (policy);
    2124           0 :                     break;
    2125             :                   case 3: /* Reject once.  */
    2126           0 :                     policy = TOFU_POLICY_ASK;
    2127           0 :                     trust_level =
    2128             :                       tofu_policy_to_trust_level (TOFU_POLICY_BAD);
    2129           0 :                     break;
    2130             :                   case 4: /* Bad.  */
    2131           0 :                     policy = TOFU_POLICY_BAD;
    2132           0 :                     trust_level = tofu_policy_to_trust_level (policy);
    2133           0 :                     break;
    2134             :                   default:
    2135           0 :                     log_bug ("c should be between 0 and 4 but it is %d!", c);
    2136             :                   }
    2137             : 
    2138           0 :                 if (record_binding (dbs, fingerprint, email, user_id,
    2139             :                                     policy, 0) != 0)
    2140             :                   /* If there's an error registering the
    2141             :                      binding, don't save the signature.  */
    2142           0 :                   trust_level = _tofu_GET_TRUST_ERROR;
    2143             : 
    2144           0 :                 break;
    2145             :               }
    2146             :           }
    2147           0 :         xfree (response);
    2148           0 :       }
    2149             : 
    2150           0 :     xfree (prompt);
    2151             : 
    2152           0 :     signature_stats_free (stats);
    2153             :   }
    2154             : 
    2155             :  out:
    2156         176 :   if (change_conflicting_to_ask)
    2157             :     {
    2158           4 :       if (! may_ask)
    2159             :         /* If we weren't allowed to ask, also update this key as
    2160             :            conflicting with itself.  */
    2161           4 :         rc = sqlite3_exec_printf
    2162             :           (db->db, NULL, NULL, &err,
    2163             :            "update bindings set policy = %d, conflict = %Q"
    2164             :            " where email = %Q"
    2165             :            "  and (policy = %d or (policy = %d and fingerprint = %Q));",
    2166             :            TOFU_POLICY_ASK, fingerprint, email, TOFU_POLICY_AUTO,
    2167             :            TOFU_POLICY_ASK, fingerprint);
    2168             :       else
    2169           0 :         rc = sqlite3_exec_printf
    2170             :           (db->db, NULL, NULL, &err,
    2171             :            "update bindings set policy = %d, conflict = %Q"
    2172             :            " where email = %Q and fingerprint != %Q and policy = %d;",
    2173             :            TOFU_POLICY_ASK, fingerprint, email, fingerprint, TOFU_POLICY_AUTO);
    2174           4 :       if (rc)
    2175             :         {
    2176           0 :           log_error (_("error changing TOFU policy: %s\n"), err);
    2177           0 :           sqlite3_free (err);
    2178           0 :           goto out;
    2179             :         }
    2180             :     }
    2181             : 
    2182         176 :   xfree (conflict);
    2183         176 :   free_strlist (bindings_with_this_email);
    2184         176 :   xfree (fingerprint_pp);
    2185             : 
    2186         176 :   return trust_level;
    2187             : }
    2188             : 
    2189             : static char *
    2190           0 : time_ago_str (long long int t)
    2191             : {
    2192             :   estream_t fp;
    2193           0 :   int years = 0;
    2194           0 :   int months = 0;
    2195           0 :   int days = 0;
    2196           0 :   int hours = 0;
    2197           0 :   int minutes = 0;
    2198           0 :   int seconds = 0;
    2199             : 
    2200             :   /* The number of units that we've printed so far.  */
    2201           0 :   int count = 0;
    2202             :   /* The first unit that we printed (year = 0, month = 1,
    2203             :      etc.).  */
    2204           0 :   int first = -1;
    2205             :   /* The current unit.  */
    2206           0 :   int i = 0;
    2207             : 
    2208             :   char *str;
    2209             : 
    2210             :   /* It would be nice to use a macro to do this, but gettext
    2211             :      works on the unpreprocessed code.  */
    2212             : #define MIN_SECS (60)
    2213             : #define HOUR_SECS (60 * MIN_SECS)
    2214             : #define DAY_SECS (24 * HOUR_SECS)
    2215             : #define MONTH_SECS (30 * DAY_SECS)
    2216             : #define YEAR_SECS (365 * DAY_SECS)
    2217             : 
    2218           0 :   if (t > YEAR_SECS)
    2219             :     {
    2220           0 :       years = t / YEAR_SECS;
    2221           0 :       t -= years * YEAR_SECS;
    2222             :     }
    2223           0 :   if (t > MONTH_SECS)
    2224             :     {
    2225           0 :       months = t / MONTH_SECS;
    2226           0 :       t -= months * MONTH_SECS;
    2227             :     }
    2228           0 :   if (t > DAY_SECS)
    2229             :     {
    2230           0 :       days = t / DAY_SECS;
    2231           0 :       t -= days * DAY_SECS;
    2232             :     }
    2233           0 :   if (t > HOUR_SECS)
    2234             :     {
    2235           0 :       hours = t / HOUR_SECS;
    2236           0 :       t -= hours * HOUR_SECS;
    2237             :     }
    2238           0 :   if (t > MIN_SECS)
    2239             :     {
    2240           0 :       minutes = t / MIN_SECS;
    2241           0 :       t -= minutes * MIN_SECS;
    2242             :     }
    2243           0 :   seconds = t;
    2244             : 
    2245             : #undef MIN_SECS
    2246             : #undef HOUR_SECS
    2247             : #undef DAY_SECS
    2248             : #undef MONTH_SECS
    2249             : #undef YEAR_SECS
    2250             : 
    2251           0 :   fp = es_fopenmem (0, "rw,samethread");
    2252           0 :   if (! fp)
    2253           0 :     log_fatal ("error creating memory stream: %s\n",
    2254             :                gpg_strerror (gpg_error_from_syserror()));
    2255             : 
    2256           0 :   if (years)
    2257             :     {
    2258           0 :       if (years > 1)
    2259           0 :         es_fprintf (fp, _("%d years"), years);
    2260             :       else
    2261           0 :         es_fprintf (fp, _("%d year"), years);
    2262           0 :       count ++;
    2263           0 :       first = i;
    2264             :     }
    2265           0 :   i ++;
    2266           0 :   if ((first == -1 || i - first <= 3) && months)
    2267             :     {
    2268           0 :       if (count)
    2269           0 :         es_fprintf (fp, ", ");
    2270             : 
    2271           0 :       if (months > 1)
    2272           0 :         es_fprintf (fp, _("%d months"), months);
    2273             :       else
    2274           0 :         es_fprintf (fp, _("%d month"), months);
    2275           0 :       count ++;
    2276           0 :       first = i;
    2277             :     }
    2278           0 :   i ++;
    2279           0 :   if ((first == -1 || i - first <= 3) && count < 2 && days)
    2280             :     {
    2281           0 :       if (count)
    2282           0 :         es_fprintf (fp, ", ");
    2283             : 
    2284           0 :       if (days > 1)
    2285           0 :         es_fprintf (fp, _("%d days"), days);
    2286             :       else
    2287           0 :         es_fprintf (fp, _("%d day"), days);
    2288           0 :       count ++;
    2289           0 :       first = i;
    2290             :     }
    2291           0 :   i ++;
    2292           0 :   if ((first == -1 || i - first <= 3) && count < 2 && hours)
    2293             :     {
    2294           0 :       if (count)
    2295           0 :         es_fprintf (fp, ", ");
    2296             : 
    2297           0 :       if (hours > 1)
    2298           0 :         es_fprintf (fp, _("%d hours"), hours);
    2299             :       else
    2300           0 :         es_fprintf (fp, _("%d hour"), hours);
    2301           0 :       count ++;
    2302           0 :       first = i;
    2303             :     }
    2304           0 :   i ++;
    2305           0 :   if ((first == -1 || i - first <= 3) && count < 2 && minutes)
    2306             :     {
    2307           0 :       if (count)
    2308           0 :         es_fprintf (fp, ", ");
    2309             : 
    2310           0 :       if (minutes > 1)
    2311           0 :         es_fprintf (fp, _("%d minutes"), minutes);
    2312             :       else
    2313           0 :         es_fprintf (fp, _("%d minute"), minutes);
    2314           0 :       count ++;
    2315           0 :       first = i;
    2316             :     }
    2317           0 :   i ++;
    2318           0 :   if ((first == -1 || i - first <= 3) && count < 2)
    2319             :     {
    2320           0 :       if (count)
    2321           0 :         es_fprintf (fp, ", ");
    2322             : 
    2323           0 :       if (seconds > 1)
    2324           0 :         es_fprintf (fp, _("%d seconds"), seconds);
    2325             :       else
    2326           0 :         es_fprintf (fp, _("%d second"), seconds);
    2327             :     }
    2328             : 
    2329           0 :   es_fputc (0, fp);
    2330           0 :   if (es_fclose_snatch (fp, (void **) &str, NULL))
    2331           0 :     log_fatal ("error snatching memory stream\n");
    2332             : 
    2333           0 :   return str;
    2334             : }
    2335             : 
    2336             : static void
    2337           6 : show_statistics (struct dbs *dbs, const char *fingerprint,
    2338             :                  const char *email, const char *user_id,
    2339             :                  const char *sig_exclude)
    2340             : {
    2341             :   struct db *db;
    2342             :   char *fingerprint_pp;
    2343             :   int rc;
    2344           6 :   strlist_t strlist = NULL;
    2345           6 :   char *err = NULL;
    2346             : 
    2347           6 :   db = getdb (dbs, email, DB_EMAIL);
    2348           6 :   if (! db)
    2349           0 :     return;
    2350             : 
    2351           6 :   fingerprint_pp = fingerprint_format (fingerprint);
    2352             : 
    2353           6 :   rc = sqlite3_exec_printf
    2354             :     (db->db, strings_collect_cb, &strlist, &err,
    2355             :      "select count (*), strftime('%%s','now') - min (signatures.time),\n"
    2356             :      "  strftime('%%s','now') - max (signatures.time)\n"
    2357             :      " from signatures\n"
    2358             :      " left join bindings on signatures.binding = bindings.oid\n"
    2359             :      " where fingerprint = %Q and email = %Q and sig_digest %s%s%s;",
    2360             :      fingerprint, email,
    2361             :      /* We want either: sig_digest != 'SIG_EXCLUDE' or sig_digest is
    2362             :         not NULL.  */
    2363             :      sig_exclude ? "!= '" : "is not NULL",
    2364             :      sig_exclude ? sig_exclude : "",
    2365             :      sig_exclude ? "'" : "");
    2366           6 :   if (rc)
    2367             :     {
    2368           0 :       log_error (_("error reading from TOFU database"
    2369             :                    " (getting statistics): %s\n"),
    2370             :                  err);
    2371           0 :       sqlite3_free (err);
    2372           0 :       goto out;
    2373             :     }
    2374             : 
    2375           6 :   if (! strlist)
    2376           0 :     log_info (_("Have never verified a message signed by key %s!\n"),
    2377             :               fingerprint_pp);
    2378             :   else
    2379             :     {
    2380           6 :       char *tail = NULL;
    2381             :       signed long messages;
    2382             :       signed long first_seen_ago;
    2383             :       signed long most_recent_seen_ago;
    2384             : 
    2385           6 :       assert (strlist_length (strlist) == 3);
    2386             : 
    2387           6 :       errno = 0;
    2388           6 :       messages = strtol (strlist->d, &tail, 0);
    2389           6 :       if (errno || *tail != '\0')
    2390             :         /* Abort.  */
    2391             :         {
    2392           0 :           log_debug ("%s:%d: Couldn't convert %s (messages) to an int: %s.\n",
    2393           0 :                      __func__, __LINE__, strlist->d, strerror (errno));
    2394           0 :           messages = -1;
    2395             :         }
    2396             : 
    2397           6 :       if (messages == 0 && *strlist->next->d == '\0')
    2398             :         /* min(NULL) => NULL => "".  */
    2399             :         {
    2400           6 :           first_seen_ago = -1;
    2401           6 :           most_recent_seen_ago = -1;
    2402             :         }
    2403             :       else
    2404             :         {
    2405           0 :           errno = 0;
    2406           0 :           first_seen_ago = strtol (strlist->next->d, &tail, 0);
    2407           0 :           if (errno || *tail != '\0')
    2408             :             /* Abort.  */
    2409             :             {
    2410           0 :               log_debug ("%s:%d: Couldn't convert %s (first_seen) to an int: %s.\n",
    2411             :                          __func__, __LINE__,
    2412           0 :                          strlist->next->d, strerror (errno));
    2413           0 :               first_seen_ago = 0;
    2414             :             }
    2415             : 
    2416           0 :           errno = 0;
    2417           0 :           most_recent_seen_ago = strtol (strlist->next->next->d, &tail, 0);
    2418           0 :           if (errno || *tail != '\0')
    2419             :             /* Abort.  */
    2420             :             {
    2421           0 :               log_debug ("%s:%d: Couldn't convert %s (most_recent_seen) to an int: %s.\n",
    2422             :                          __func__, __LINE__,
    2423           0 :                          strlist->next->next->d, strerror (errno));
    2424           0 :               most_recent_seen_ago = 0;
    2425             :             }
    2426             :         }
    2427             : 
    2428           6 :       if (messages == -1 || first_seen_ago == 0)
    2429           0 :         log_info (_("Failed to collect signature statistics"
    2430             :                     " for \"%s\" (key %s)\n"),
    2431             :                   user_id, fingerprint_pp);
    2432             :       else
    2433             :         {
    2434           6 :           enum tofu_policy policy = get_policy (dbs, fingerprint, email, NULL);
    2435             :           estream_t fp;
    2436             :           char *msg;
    2437             : 
    2438           6 :           fp = es_fopenmem (0, "rw,samethread");
    2439           6 :           if (! fp)
    2440           0 :             log_fatal ("error creating memory stream\n");
    2441             : 
    2442           6 :           if (messages == 0)
    2443          12 :             es_fprintf (fp,
    2444           6 :                         _("Verified 0 messages signed by \"%s\""
    2445             :                           " (key: %s, policy %s)."),
    2446             :                         user_id, fingerprint_pp, tofu_policy_str (policy));
    2447             :           else
    2448             :             {
    2449           0 :               char *first_seen_ago_str = time_ago_str (first_seen_ago);
    2450           0 :               char *most_recent_seen_ago_str =
    2451             :                 time_ago_str (most_recent_seen_ago);
    2452             : 
    2453           0 :               es_fprintf (fp,
    2454           0 :                           _("Verified %ld messages signed by \"%s\""
    2455             :                             " (key: %s, policy: %s) in the past %s."),
    2456             :                           messages, user_id,
    2457             :                           fingerprint_pp, tofu_policy_str (policy),
    2458             :                           first_seen_ago_str);
    2459             : 
    2460           0 :               if (messages > 1)
    2461           0 :                 es_fprintf (fp,
    2462           0 :                             _("  The most recent message was verified %s ago."),
    2463             :                             most_recent_seen_ago_str);
    2464             : 
    2465           0 :               xfree (first_seen_ago_str);
    2466           0 :               xfree (most_recent_seen_ago_str);
    2467             :             }
    2468             : 
    2469           6 :           es_fputc (0, fp);
    2470           6 :           if (es_fclose_snatch (fp, (void **) &msg, NULL))
    2471           0 :             log_fatal ("error snatching memory stream\n");
    2472             : 
    2473           6 :           log_info ("%s\n", msg);
    2474           6 :           xfree (msg);
    2475             : 
    2476           6 :           if (policy == TOFU_POLICY_AUTO && messages < 10)
    2477             :             {
    2478             :               char *set_policy_command;
    2479             :               const char *text;
    2480             : 
    2481           2 :               if (messages == 0)
    2482           2 :                 log_info (_("Warning: we've have yet to see"
    2483             :                             " a message signed by this key!\n"));
    2484           0 :               else if (messages == 1)
    2485           0 :                 log_info (_("Warning: we've only seen a"
    2486             :                             " single message signed by this key!\n"));
    2487             : 
    2488           2 :               set_policy_command =
    2489             :                 xasprintf ("gpg --tofu-policy bad \"%s\"", fingerprint);
    2490             :               /* TRANSLATORS: translate the below text.  We don't
    2491             :                  directly internationalize that text so that we can
    2492             :                  tweak it without breaking translations.  */
    2493           2 :               text = _("TOFU: few signatures %d %s %s");
    2494           2 :               if (strcmp (text, "TOFU: few signatures %d %s %s") == 0)
    2495           2 :                 text =
    2496             :                   "Warning: if you think you've seen more than %d %s "
    2497             :                   "signed by this key, then this key might be a forgery!  "
    2498             :                   "Carefully examine the email address for small variations "
    2499             :                   "(e.g., additional white space).  If the key is suspect, "
    2500             :                   "then use '%s' to mark it as being bad.\n";
    2501           2 :               log_info (text,
    2502             :                         messages, messages == 1 ? _("message") : _("message"),
    2503             :                         set_policy_command);
    2504           2 :               free (set_policy_command);
    2505             :             }
    2506             :         }
    2507             :     }
    2508             : 
    2509             :  out:
    2510           6 :   free_strlist (strlist);
    2511           6 :   xfree (fingerprint_pp);
    2512             : 
    2513           6 :   return;
    2514             : }
    2515             : 
    2516             : /* Extract the email address from a user id and normalize it.  If the
    2517             :    user id doesn't contain an email address, then we use the whole
    2518             :    user_id and normalize that.  The returned string must be freed.  */
    2519             : static char *
    2520         266 : email_from_user_id (const char *user_id)
    2521             : {
    2522         266 :   char *email = mailbox_from_userid (user_id);
    2523         266 :   if (! email)
    2524             :     {
    2525             :       /* Hmm, no email address was provided or we are out of core.  Just
    2526             :          take the lower-case version of the whole user id.  It could be
    2527             :          a hostname, for instance.  */
    2528         266 :       email = ascii_strlwr (xstrdup (user_id));
    2529             :     }
    2530             : 
    2531         266 :   return email;
    2532             : }
    2533             : 
    2534             : /* Register the signature with the binding <FINGERPRINT_BIN, USER_ID>.
    2535             :    FINGERPRINT must be MAX_FINGERPRINT_LEN bytes long.
    2536             : 
    2537             :    SIG_DIGEST_BIN is the binary representation of the message's
    2538             :    digest.  SIG_DIGEST_BIN_LEN is its length.
    2539             : 
    2540             :    SIG_TIME is the time that the signature was generated.
    2541             : 
    2542             :    ORIGIN is a free-formed string describing the origin of the
    2543             :    signature.  If this was from an email and the Claws MUA was used,
    2544             :    then this should be something like: "email:claws".  If this is
    2545             :    NULL, the default is simply "unknown".
    2546             : 
    2547             :    If MAY_ASK is 1, then this function may interact with the user.
    2548             :    This is necessary if there is a conflict or the binding's policy is
    2549             :    TOFU_POLICY_ASK.
    2550             : 
    2551             :    This function returns the binding's trust level on return.  If an
    2552             :    error occurs, this function returns TRUST_UNKNOWN.  */
    2553             : int
    2554           6 : tofu_register (const byte *fingerprint_bin, const char *user_id,
    2555             :                const byte *sig_digest_bin, int sig_digest_bin_len,
    2556             :                time_t sig_time, const char *origin, int may_ask)
    2557             : {
    2558             :   struct dbs *dbs;
    2559             :   struct db *db;
    2560           6 :   char *fingerprint = NULL;
    2561           6 :   char *fingerprint_pp = NULL;
    2562           6 :   char *email = NULL;
    2563           6 :   char *err = NULL;
    2564             :   int rc;
    2565           6 :   int trust_level = TRUST_UNKNOWN;
    2566             :   char *sig_digest;
    2567             :   unsigned long c;
    2568           6 :   int already_verified = 0;
    2569             : 
    2570           6 :   sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len);
    2571             : 
    2572           6 :   dbs = opendbs ();
    2573           6 :   if (! dbs)
    2574             :     {
    2575           0 :       log_error (_("error opening TOFU DB.\n"));
    2576           0 :       goto die;
    2577             :     }
    2578             : 
    2579           6 :   fingerprint = fingerprint_str (fingerprint_bin);
    2580           6 :   fingerprint_pp = fingerprint_format (fingerprint);
    2581             : 
    2582           6 :   if (! *user_id)
    2583             :     {
    2584           0 :       log_debug ("TOFU: user id is empty.  Can't continue.\n");
    2585           0 :       goto die;
    2586             :     }
    2587             : 
    2588           6 :   email = email_from_user_id (user_id);
    2589             : 
    2590           6 :   if (! origin)
    2591             :     /* The default origin is simply "unknown".  */
    2592           0 :     origin = "unknown";
    2593             : 
    2594             :   /* It's necessary to get the trust so that we are certain that the
    2595             :      binding has been registered.  */
    2596           6 :   trust_level = get_trust (dbs, fingerprint, email, user_id, may_ask);
    2597           6 :   if (trust_level == _tofu_GET_TRUST_ERROR)
    2598             :     /* An error.  */
    2599             :     {
    2600           0 :       trust_level = TRUST_UNKNOWN;
    2601           0 :       goto die;
    2602             :     }
    2603             : 
    2604             :   /* Save the observed signature in the DB.  */
    2605           6 :   db = getdb (dbs, email, DB_EMAIL);
    2606           6 :   if (! db)
    2607             :     {
    2608           0 :       log_error (_("error opening TOFU DB.\n"));
    2609           0 :       goto die;
    2610             :     }
    2611             : 
    2612             :   /* We do a query and then an insert.  Make sure they are atomic
    2613             :      by wrapping them in a transaction.  */
    2614           6 :   rc = begin_transaction (db, 0);
    2615           6 :   if (rc)
    2616           0 :     goto die;
    2617             : 
    2618             :   /* If we've already seen this signature before, then don't add
    2619             :      it again.  */
    2620           6 :   rc = sqlite3_stepx
    2621             :     (db->db, &db->s.register_already_seen,
    2622             :      get_single_unsigned_long_cb2, &c, &err,
    2623             :      "select count (*)\n"
    2624             :      " from signatures left join bindings\n"
    2625             :      "  on signatures.binding = bindings.oid\n"
    2626             :      " where fingerprint = ? and email = ? and sig_time = ?\n"
    2627             :      "  and sig_digest = ?",
    2628             :      SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    2629             :      SQLITE_ARG_LONG_LONG, (long long) sig_time,
    2630             :      SQLITE_ARG_STRING, sig_digest,
    2631             :      SQLITE_ARG_END);
    2632           6 :   if (rc)
    2633             :     {
    2634           0 :       log_error (_("error reading from signatures database"
    2635             :                    " (checking existence): %s\n"),
    2636             :                  err);
    2637           0 :       sqlite3_free (err);
    2638             :     }
    2639           6 :   else if (c > 1)
    2640             :     /* Duplicates!  This should not happen.  In particular,
    2641             :        because <fingerprint, email, sig_time, sig_digest> is the
    2642             :        primary key!  */
    2643           0 :     log_debug ("SIGNATURES DB contains duplicate records"
    2644             :                " <key: %s, %s, time: 0x%lx, sig: %s, %s>."
    2645             :                "  Please report.\n",
    2646             :                fingerprint_pp, email, (unsigned long) sig_time,
    2647             :                sig_digest, origin);
    2648           6 :   else if (c == 1)
    2649             :     {
    2650           0 :       already_verified = 1;
    2651           0 :       if (DBG_TRUST)
    2652           0 :         log_debug ("Already observed the signature"
    2653             :                    " <key: %s, %s, time: 0x%lx, sig: %s, %s>\n",
    2654             :                    fingerprint_pp, email, (unsigned long) sig_time,
    2655             :                    sig_digest, origin);
    2656             :     }
    2657             :   else
    2658             :     /* This is the first time that we've seen this signature.
    2659             :        Record it.  */
    2660             :     {
    2661           6 :       if (DBG_TRUST)
    2662           0 :         log_debug ("TOFU: Saving signature <%s, %s, %s>\n",
    2663             :                    fingerprint_pp, email, sig_digest);
    2664             : 
    2665           6 :       assert (c == 0);
    2666             : 
    2667           6 :       rc = sqlite3_stepx
    2668             :         (db->db, &db->s.register_insert, NULL, NULL, &err,
    2669             :          "insert into signatures\n"
    2670             :          " (binding, sig_digest, origin, sig_time, time)\n"
    2671             :          " values\n"
    2672             :          " ((select oid from bindings\n"
    2673             :          "    where fingerprint = ? and email = ?),\n"
    2674             :          "  ?, ?, ?, strftime('%s', 'now'));",
    2675             :          SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
    2676             :          SQLITE_ARG_STRING, sig_digest, SQLITE_ARG_STRING, origin,
    2677             :          SQLITE_ARG_LONG_LONG, (long long) sig_time,
    2678             :          SQLITE_ARG_END);
    2679           6 :       if (rc)
    2680             :         {
    2681           0 :           log_error (_("error updating TOFU DB"
    2682             :                        " (inserting into signatures table): %s\n"),
    2683             :                      err);
    2684           0 :           sqlite3_free (err);
    2685             :         }
    2686             :     }
    2687             : 
    2688             :   /* It only matters whether we abort or commit the transaction
    2689             :      (so long as we do something) if we execute the insert.  */
    2690           6 :   if (rc)
    2691           0 :     rc = rollback_transaction (db);
    2692             :   else
    2693           6 :     rc = end_transaction (db, 0);
    2694           6 :   if (rc)
    2695             :     {
    2696           0 :       log_error (_("error ending transaction on TOFU database: %s\n"), err);
    2697           0 :       sqlite3_free (err);
    2698           0 :       goto die;
    2699             :     }
    2700             : 
    2701             :  die:
    2702           6 :   if (may_ask && trust_level != TRUST_ULTIMATE)
    2703             :     /* It's only appropriate to show the statistics in an interactive
    2704             :        context.  */
    2705           6 :     show_statistics (dbs, fingerprint, email, user_id,
    2706             :                      already_verified ? NULL : sig_digest);
    2707             : 
    2708           6 :   xfree (email);
    2709           6 :   xfree (fingerprint_pp);
    2710           6 :   xfree (fingerprint);
    2711           6 :   if (dbs)
    2712           6 :     closedbs (dbs);
    2713           6 :   xfree (sig_digest);
    2714             : 
    2715           6 :   return trust_level;
    2716             : }
    2717             : 
    2718             : /* Combine a trust level returned from the TOFU trust model with a
    2719             :    trust level returned by the PGP trust model.  This is primarily of
    2720             :    interest when the trust model is tofu+pgp (TM_TOFU_PGP).
    2721             : 
    2722             :    This function ors together the upper bits (the values not covered
    2723             :    by TRUST_MASK, i.e., TRUST_FLAG_REVOKED, etc.).  */
    2724             : int
    2725         864 : tofu_wot_trust_combine (int tofu_base, int wot_base)
    2726             : {
    2727         864 :   int tofu = tofu_base & TRUST_MASK;
    2728         864 :   int wot = wot_base & TRUST_MASK;
    2729         864 :   int upper = (tofu_base & ~TRUST_MASK) | (wot_base & ~TRUST_MASK);
    2730             : 
    2731         864 :   assert (tofu == TRUST_UNKNOWN
    2732             :           || tofu == TRUST_EXPIRED
    2733             :           || tofu == TRUST_UNDEFINED
    2734             :           || tofu == TRUST_NEVER
    2735             :           || tofu == TRUST_MARGINAL
    2736             :           || tofu == TRUST_FULLY
    2737             :           || tofu == TRUST_ULTIMATE);
    2738         864 :   assert (wot == TRUST_UNKNOWN
    2739             :           || wot == TRUST_EXPIRED
    2740             :           || wot == TRUST_UNDEFINED
    2741             :           || wot == TRUST_NEVER
    2742             :           || wot == TRUST_MARGINAL
    2743             :           || wot == TRUST_FULLY
    2744             :           || wot == TRUST_ULTIMATE);
    2745             : 
    2746             :   /* We first consider negative trust policys.  These trump positive
    2747             :      trust policies.  */
    2748         864 :   if (tofu == TRUST_NEVER || wot == TRUST_NEVER)
    2749             :     /* TRUST_NEVER trumps everything else.  */
    2750          52 :     return upper | TRUST_NEVER;
    2751         812 :   if (tofu == TRUST_EXPIRED || wot == TRUST_EXPIRED)
    2752             :     /* TRUST_EXPIRED trumps everything but TRUST_NEVER.  */
    2753           0 :     return upper | TRUST_EXPIRED;
    2754             : 
    2755             :   /* Now we only have positive or neutral trust policies.  We take
    2756             :      the max.  */
    2757         812 :   if (tofu == TRUST_ULTIMATE || wot == TRUST_ULTIMATE)
    2758           0 :     return upper | TRUST_ULTIMATE;
    2759         812 :   if (tofu == TRUST_FULLY || wot == TRUST_FULLY)
    2760          44 :     return upper | TRUST_FULLY;
    2761         768 :   if (tofu == TRUST_MARGINAL || wot == TRUST_MARGINAL)
    2762          16 :     return upper | TRUST_MARGINAL;
    2763         752 :   if (tofu == TRUST_UNDEFINED || wot == TRUST_UNDEFINED)
    2764           0 :     return upper | TRUST_UNDEFINED;
    2765         752 :   return upper | TRUST_UNKNOWN;
    2766             : }
    2767             : 
    2768             : /* Return the validity (TRUST_NEVER, etc.) of the binding
    2769             :    <FINGERPRINT, USER_ID>.
    2770             : 
    2771             :    FINGERPRINT must be a MAX_FINGERPRINT_LEN-byte fingerprint.
    2772             : 
    2773             :    If MAY_ASK is 1 and the policy is TOFU_POLICY_ASK, then the user
    2774             :    will be prompted to choose a different policy.  If MAY_ASK is 0 and
    2775             :    the policy is TOFU_POLICY_ASK, then TRUST_UNKNOWN is returned.
    2776             : 
    2777             :    Returns TRUST_UNDEFINED if an error occurs.  */
    2778             : int
    2779         170 : tofu_get_validity (const byte *fingerprint_bin, const char *user_id,
    2780             :                    int may_ask)
    2781             : {
    2782             :   struct dbs *dbs;
    2783         170 :   char *fingerprint = NULL;
    2784         170 :   char *email = NULL;
    2785         170 :   int trust_level = TRUST_UNDEFINED;
    2786             : 
    2787         170 :   dbs = opendbs ();
    2788         170 :   if (! dbs)
    2789             :     {
    2790           0 :       log_error (_("error opening TOFU DB.\n"));
    2791           0 :       goto die;
    2792             :     }
    2793             : 
    2794         170 :   fingerprint = fingerprint_str (fingerprint_bin);
    2795             : 
    2796         170 :   if (! *user_id)
    2797             :     {
    2798           0 :       log_debug ("user id is empty."
    2799             :                  "  Can't get TOFU validity for this binding.\n");
    2800           0 :       goto die;
    2801             :     }
    2802             : 
    2803         170 :   email = email_from_user_id (user_id);
    2804             : 
    2805         170 :   trust_level = get_trust (dbs, fingerprint, email, user_id, may_ask);
    2806         170 :   if (trust_level == _tofu_GET_TRUST_ERROR)
    2807             :     /* An error.  */
    2808           0 :     trust_level = TRUST_UNDEFINED;
    2809             : 
    2810         170 :   if (may_ask && trust_level != TRUST_ULTIMATE)
    2811           0 :     show_statistics (dbs, fingerprint, email, user_id, NULL);
    2812             : 
    2813             :  die:
    2814         170 :   xfree (email);
    2815         170 :   xfree (fingerprint);
    2816         170 :   if (dbs)
    2817         170 :     closedbs (dbs);
    2818             : 
    2819         170 :   return trust_level;
    2820             : }
    2821             : 
    2822             : /* Set the policy for all non-revoked user ids in the keyblock KB to
    2823             :    POLICY.
    2824             : 
    2825             :    If no key is available with the specified key id, then this
    2826             :    function returns GPG_ERR_NO_PUBKEY.
    2827             : 
    2828             :    Returns 0 on success and an error code otherwise.  */
    2829             : gpg_error_t
    2830           8 : tofu_set_policy (kbnode_t kb, enum tofu_policy policy)
    2831             : {
    2832             :   struct dbs *dbs;
    2833             :   PKT_public_key *pk;
    2834             :   char fingerprint_bin[MAX_FINGERPRINT_LEN];
    2835           8 :   size_t fingerprint_bin_len = sizeof (fingerprint_bin);
    2836           8 :   char *fingerprint = NULL;
    2837             : 
    2838           8 :   assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
    2839           8 :   pk = kb->pkt->pkt.public_key;
    2840             : 
    2841           8 :   dbs = opendbs ();
    2842           8 :   if (! dbs)
    2843             :     {
    2844           0 :       log_error (_("error opening TOFU DB.\n"));
    2845           0 :       return gpg_error (GPG_ERR_GENERAL);
    2846             :     }
    2847             : 
    2848           8 :   if (DBG_TRUST)
    2849           0 :     log_debug ("Setting TOFU policy for %s to %s\n",
    2850           0 :                keystr (pk->keyid), tofu_policy_str (policy));
    2851          16 :   if (! (pk->main_keyid[0] == pk->keyid[0]
    2852           8 :          && pk->main_keyid[1] == pk->keyid[1]))
    2853           0 :     log_bug ("%s: Passed a subkey, but expecting a primary key.\n", __func__);
    2854             : 
    2855           8 :   fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len);
    2856           8 :   assert (fingerprint_bin_len == sizeof (fingerprint_bin));
    2857             : 
    2858           8 :   fingerprint = fingerprint_str (fingerprint_bin);
    2859             : 
    2860          48 :   for (; kb; kb = kb->next)
    2861             :     {
    2862             :       PKT_user_id *user_id;
    2863             :       char *email;
    2864             : 
    2865          40 :       if (kb->pkt->pkttype != PKT_USER_ID)
    2866          32 :         continue;
    2867             : 
    2868           8 :       user_id = kb->pkt->pkt.user_id;
    2869           8 :       if (user_id->is_revoked)
    2870             :         /* Skip revoked user ids.  (Don't skip expired user ids, the
    2871             :            expiry can be changed.)  */
    2872           0 :         continue;
    2873             : 
    2874           8 :       email = email_from_user_id (user_id->name);
    2875             : 
    2876           8 :       record_binding (dbs, fingerprint, email, user_id->name, policy, 1);
    2877             : 
    2878           8 :       xfree (email);
    2879             :     }
    2880             : 
    2881           8 :   xfree (fingerprint);
    2882           8 :   closedbs (dbs);
    2883             : 
    2884           8 :   return 0;
    2885             : }
    2886             : 
    2887             : /* Set the TOFU policy for all non-revoked user ids in the KEY with
    2888             :    the key id KEYID to POLICY.
    2889             : 
    2890             :    If no key is available with the specified key id, then this
    2891             :    function returns GPG_ERR_NO_PUBKEY.
    2892             : 
    2893             :    Returns 0 on success and an error code otherwise.  */
    2894             : gpg_error_t
    2895           0 : tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy)
    2896             : {
    2897           0 :   kbnode_t keyblock = get_pubkeyblock (keyid);
    2898           0 :   if (! keyblock)
    2899           0 :     return gpg_error (GPG_ERR_NO_PUBKEY);
    2900             : 
    2901           0 :   return tofu_set_policy (keyblock, policy);
    2902             : }
    2903             : 
    2904             : /* Return the TOFU policy for the specified binding in *POLICY.  If no
    2905             :    policy has been set for the binding, sets *POLICY to
    2906             :    TOFU_POLICY_NONE.
    2907             : 
    2908             :    PK is a primary public key and USER_ID is a user id.
    2909             : 
    2910             :    Returns 0 on success and an error code otherwise.  */
    2911             : gpg_error_t
    2912          82 : tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id,
    2913             :                  enum tofu_policy *policy)
    2914             : {
    2915             :   struct dbs *dbs;
    2916             :   char fingerprint_bin[MAX_FINGERPRINT_LEN];
    2917          82 :   size_t fingerprint_bin_len = sizeof (fingerprint_bin);
    2918             :   char *fingerprint;
    2919             :   char *email;
    2920             : 
    2921             :   /* Make sure PK is a primary key.  */
    2922          82 :   assert (pk->main_keyid[0] == pk->keyid[0]
    2923             :           && pk->main_keyid[1] == pk->keyid[1]);
    2924             : 
    2925          82 :   dbs = opendbs ();
    2926          82 :   if (! dbs)
    2927             :     {
    2928           0 :       log_error (_("error opening TOFU DB.\n"));
    2929           0 :       return gpg_error (GPG_ERR_GENERAL);
    2930             :     }
    2931             : 
    2932          82 :   fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len);
    2933          82 :   assert (fingerprint_bin_len == sizeof (fingerprint_bin));
    2934             : 
    2935          82 :   fingerprint = fingerprint_str (fingerprint_bin);
    2936             : 
    2937          82 :   email = email_from_user_id (user_id->name);
    2938             : 
    2939          82 :   *policy = get_policy (dbs, fingerprint, email, NULL);
    2940             : 
    2941          82 :   xfree (email);
    2942          82 :   xfree (fingerprint);
    2943          82 :   closedbs (dbs);
    2944             : 
    2945          82 :   if (*policy == _tofu_GET_POLICY_ERROR)
    2946           0 :     return gpg_error (GPG_ERR_GENERAL);
    2947          82 :   return 0;
    2948             : }

Generated by: LCOV version 1.11