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 : }
|