Coverage Report

Created: 2026-07-16 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/tdbio.c
Line
Count
Source
1
/* tdbio.c - trust database I/O operations
2
 * Copyright (C) 1998-2002, 2012 Free Software Foundation, Inc.
3
 * Copyright (C) 1998-2015 Werner Koch
4
 *
5
 * This file is part of GnuPG.
6
 *
7
 * GnuPG is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * GnuPG is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
#include <config.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <errno.h>
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <fcntl.h>
29
#include <unistd.h>
30
31
#include "gpg.h"
32
#include "../common/status.h"
33
#include "../common/iobuf.h"
34
#include "../common/util.h"
35
#include "options.h"
36
#include "main.h"
37
#include "../common/i18n.h"
38
#include "trustdb.h"
39
#include "tdbio.h"
40
41
#if defined(HAVE_DOSISH_SYSTEM) && !defined(ftruncate)
42
#define ftruncate chsize
43
#endif
44
45
#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
46
#define MY_O_BINARY  O_BINARY
47
#else
48
4
#define MY_O_BINARY  0
49
#endif
50
51
52
/*
53
 * Yes, this is a very simple implementation. We should really
54
 * use a page aligned buffer and read complete pages.
55
 * To implement a simple trannsaction system, this is sufficient.
56
 */
57
typedef struct cache_ctrl_struct *CACHE_CTRL;
58
struct cache_ctrl_struct
59
{
60
  CACHE_CTRL next;
61
  struct {
62
    unsigned used:1;
63
    unsigned dirty:1;
64
  } flags;
65
  ulong recno;
66
  char data[TRUST_RECORD_LEN];
67
};
68
69
/* Size of the cache.  The SOFT value is the general one.  While in a
70
   transaction this may not be sufficient and thus we may increase it
71
   then up to the HARD limit.  */
72
120
#define MAX_CACHE_ENTRIES_SOFT  200
73
#define MAX_CACHE_ENTRIES_HARD  10000
74
75
76
/* The cache is controlled by these variables.  */
77
static CACHE_CTRL cache_list;
78
static int cache_entries;
79
static int cache_is_dirty;
80
81
82
/* An object to pass information to cmp_krec_fpr. */
83
struct cmp_krec_fpr_struct
84
{
85
  int pubkey_algo;
86
  const char *fpr;
87
  int fprlen;
88
};
89
90
/* An object used to pass information to cmp_[s]dir. */
91
struct cmp_xdir_struct
92
{
93
  int pubkey_algo;
94
  u32 keyid[2];
95
};
96
97
98
/* The name of the trustdb file.  */
99
static char *db_name;
100
101
/* The handle for locking the trustdb file and a counter to record how
102
 * often this lock has been taken.  That counter is required because
103
 * dotlock does not implement recursive locks.  */
104
static dotlock_t lockhandle;
105
static unsigned int is_locked;
106
107
/* The file descriptor of the trustdb.  */
108
static int  db_fd = -1;
109
110
/* A flag indicating that a transaction is active.  */
111
/* static int in_transaction;   Not yet used. */
112
113
114

115
static void open_db (void);
116
static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type);
117
118
119

120
/*
121
 * Take a lock on the trustdb file name.  If a lock file can't be
122
 * created the function terminates the process.
123
 */
124
static void
125
take_write_lock (void)
126
830
{
127
830
  if (!lockhandle)
128
4
    lockhandle = dotlock_create (db_name, 0);
129
830
  if (!lockhandle)
130
830
    log_fatal ( _("can't create lock for '%s'\n"), db_name );
131
132
830
  if (!is_locked)
133
822
    {
134
822
      if (dotlock_take (lockhandle, -1) )
135
822
        log_fatal ( _("can't lock '%s'\n"), db_name );
136
822
    }
137
138
830
  if (opt.lock_once)
139
0
    is_locked = 1;
140
830
  else
141
830
    is_locked++;
142
830
}
143
144
145
/*
146
 * Release a lock from the trustdb file unless the global option
147
 * --lock-once has been used.
148
 */
149
static void
150
release_write_lock (void)
151
830
{
152
830
  if (opt.lock_once)
153
0
    return;  /* Don't care; here IS_LOCKED is fixed to 1.  */
154
155
830
  if (!is_locked)
156
0
    {
157
0
      log_error ("Ooops, tdbio:release_write_lock with no lock held\n");
158
0
      return;
159
0
    }
160
830
  if (--is_locked)
161
8
    return;
162
163
822
  if (dotlock_release (lockhandle))
164
822
    log_error ("Oops, tdbio:release_write_locked failed\n");
165
822
}
166
167
168

169
/*************************************
170
 ************* record cache **********
171
 *************************************/
172
173
/*
174
 * Get the data from the record cache and return a pointer into that
175
 * cache.  Caller should copy the returned data.  NULL is returned on
176
 * a cache miss.
177
 */
178
static const char *
179
get_record_from_cache (ulong recno)
180
58.3k
{
181
58.3k
  CACHE_CTRL r;
182
183
816k
  for (r = cache_list; r; r = r->next)
184
815k
    {
185
815k
      if (r->flags.used && r->recno == recno)
186
57.9k
        return r->data;
187
815k
    }
188
413
  return NULL;
189
58.3k
}
190
191
192
/*
193
 * Write a cached item back to the trustdb file.
194
 *
195
 * Returns: 0 on success or an error code.
196
 */
197
static int
198
write_cache_item (CACHE_CTRL r)
199
942
{
200
942
  gpg_error_t err;
201
942
  int n;
202
203
942
  if (lseek (db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET) == -1)
204
0
    {
205
0
      err = gpg_error_from_syserror ();
206
0
      log_error (_("trustdb rec %lu: lseek failed: %s\n"),
207
0
                 r->recno, strerror (errno));
208
0
      return err;
209
0
    }
210
942
  n = write (db_fd, r->data, TRUST_RECORD_LEN);
211
942
  if (n != TRUST_RECORD_LEN)
212
0
    {
213
0
      err = gpg_error_from_syserror ();
214
0
      log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"),
215
0
                 r->recno, n, strerror (errno) );
216
0
      return err;
217
0
    }
218
942
  r->flags.dirty = 0;
219
942
  return 0;
220
942
}
221
222
223
/*
224
 * Put data into the cache.  This function may flush
225
 * some cache entries if the cache is filled up.
226
 *
227
 * Returns: 0 on success or an error code.
228
 */
229
static int
230
put_record_into_cache (ulong recno, const char *data)
231
1.35k
{
232
1.35k
  CACHE_CTRL r, unused;
233
1.35k
  int dirty_count = 0;
234
1.35k
  int clean_count = 0;
235
236
  /* See whether we already cached this one.  */
237
38.7k
  for (unused = NULL, r = cache_list; r; r = r->next)
238
38.6k
    {
239
38.6k
      if (!r->flags.used)
240
0
        {
241
0
          if (!unused)
242
0
            unused = r;
243
0
  }
244
38.6k
      else if (r->recno == recno)
245
1.23k
        {
246
1.23k
          if (!r->flags.dirty)
247
822
            {
248
              /* Hmmm: should we use a copy and compare? */
249
822
              if (memcmp (r->data, data, TRUST_RECORD_LEN))
250
822
                {
251
822
                  r->flags.dirty = 1;
252
822
                  cache_is_dirty = 1;
253
822
    }
254
822
      }
255
1.23k
          memcpy (r->data, data, TRUST_RECORD_LEN);
256
1.23k
          return 0;
257
1.23k
  }
258
37.4k
      if (r->flags.used)
259
37.4k
        {
260
37.4k
          if (r->flags.dirty)
261
1.74k
            dirty_count++;
262
35.6k
          else
263
35.6k
            clean_count++;
264
37.4k
  }
265
37.4k
    }
266
267
  /* Not in the cache: add a new entry. */
268
120
  if (unused)
269
0
    {
270
      /* Reuse this entry. */
271
0
      r = unused;
272
0
      r->flags.used = 1;
273
0
      r->recno = recno;
274
0
      memcpy (r->data, data, TRUST_RECORD_LEN);
275
0
      r->flags.dirty = 1;
276
0
      cache_is_dirty = 1;
277
0
      cache_entries++;
278
0
      return 0;
279
0
    }
280
281
  /* See whether we reached the limit. */
282
120
  if (cache_entries < MAX_CACHE_ENTRIES_SOFT)
283
120
    {
284
      /* No: Put into cache.  */
285
120
      r = xmalloc (sizeof *r);
286
120
      r->flags.used = 1;
287
120
      r->recno = recno;
288
120
      memcpy (r->data, data, TRUST_RECORD_LEN);
289
120
      r->flags.dirty = 1;
290
120
      r->next = cache_list;
291
120
      cache_list = r;
292
120
      cache_is_dirty = 1;
293
120
      cache_entries++;
294
120
      return 0;
295
120
    }
296
297
  /* Cache is full: discard some clean entries.  */
298
0
  if (clean_count)
299
0
    {
300
0
      int n;
301
302
      /* We discard a third of the clean entries.  */
303
0
      n = clean_count / 3;
304
0
      if (!n)
305
0
        n = 1;
306
307
0
      for (unused = NULL, r = cache_list; r; r = r->next)
308
0
        {
309
0
          if (r->flags.used && !r->flags.dirty)
310
0
            {
311
0
              if (!unused)
312
0
                unused = r;
313
0
              r->flags.used = 0;
314
0
              cache_entries--;
315
0
              if (!--n)
316
0
                break;
317
0
      }
318
0
  }
319
320
      /* Now put into the cache.  */
321
0
      log_assert (unused);
322
0
      r = unused;
323
0
      r->flags.used = 1;
324
0
      r->recno = recno;
325
0
      memcpy (r->data, data, TRUST_RECORD_LEN);
326
0
      r->flags.dirty = 1;
327
0
      cache_is_dirty = 1;
328
0
      cache_entries++;
329
0
      return 0;
330
0
    }
331
332
  /* No clean entries: We have to flush some dirty entries.  */
333
#if 0 /* Transactions are not yet used.  */
334
  if (in_transaction)
335
    {
336
      /* But we can't do this while in a transaction.  Thus we
337
       * increase the cache size instead.  */
338
      if (cache_entries < MAX_CACHE_ENTRIES_HARD)
339
        {
340
          if (opt.debug && !(cache_entries % 100))
341
            log_debug ("increasing tdbio cache size\n");
342
          r = xmalloc (sizeof *r);
343
          r->flags.used = 1;
344
          r->recno = recno;
345
          memcpy (r->data, data, TRUST_RECORD_LEN);
346
          r->flags.dirty = 1;
347
          r->next = cache_list;
348
          cache_list = r;
349
          cache_is_dirty = 1;
350
          cache_entries++;
351
          return 0;
352
  }
353
      /* Hard limit for the cache size reached.  */
354
      log_info (_("trustdb transaction too large\n"));
355
      return GPG_ERR_RESOURCE_LIMIT;
356
    }
357
#endif
358
359
0
  if (dirty_count)
360
0
    {
361
0
      int n;
362
363
      /* Discard some dirty entries. */
364
0
      n = dirty_count / 5;
365
0
      if (!n)
366
0
        n = 1;
367
368
0
      take_write_lock ();
369
0
      for (unused = NULL, r = cache_list; r; r = r->next)
370
0
        {
371
0
          if (r->flags.used && r->flags.dirty)
372
0
            {
373
0
              int rc;
374
375
0
              rc = write_cache_item (r);
376
0
              if (rc)
377
0
                return rc;
378
0
              if (!unused)
379
0
                unused = r;
380
0
              r->flags.used = 0;
381
0
              cache_entries--;
382
0
              if (!--n)
383
0
                break;
384
0
      }
385
0
  }
386
0
      release_write_lock ();
387
388
      /* Now put into the cache.  */
389
0
      log_assert (unused);
390
0
      r = unused;
391
0
      r->flags.used = 1;
392
0
      r->recno = recno;
393
0
      memcpy (r->data, data, TRUST_RECORD_LEN);
394
0
      r->flags.dirty = 1;
395
0
      cache_is_dirty = 1;
396
0
      cache_entries++;
397
0
      return 0;
398
0
    }
399
400
  /* We should never reach this.  */
401
0
  BUG();
402
0
}
403
404
405
/* Return true if the cache is dirty.  */
406
int
407
tdbio_is_dirty (void)
408
0
{
409
0
  return cache_is_dirty;
410
0
}
411
412
413
/*
414
 * Flush the cache.  This cannot be used while in a transaction.
415
 */
416
int
417
tdbio_sync (void)
418
826
{
419
826
    CACHE_CTRL r;
420
421
826
    if( db_fd == -1 )
422
0
  open_db();
423
#if 0 /* Transactions are not yet used.  */
424
    if( in_transaction )
425
  log_bug("tdbio: syncing while in transaction\n");
426
#endif
427
428
826
    if( !cache_is_dirty )
429
0
  return 0;
430
431
826
    take_write_lock ();
432
25.4k
    for( r = cache_list; r; r = r->next ) {
433
24.6k
  if( r->flags.used && r->flags.dirty ) {
434
942
      int rc = write_cache_item( r );
435
942
      if( rc )
436
0
    return rc;
437
942
  }
438
24.6k
    }
439
826
    cache_is_dirty = 0;
440
826
    release_write_lock ();
441
442
826
    return 0;
443
826
}
444
445
446
#if 0  /* Not yet used.  */
447
/*
448
 * Simple transactions system:
449
 * Everything between begin_transaction and end/cancel_transaction
450
 * is not immediately written but at the time of end_transaction.
451
 *
452
 * NOTE: The transaction code is disabled in the 1.2 branch, as it is
453
 * not yet used.
454
 */
455
int
456
tdbio_begin_transaction ()  /* Not yet used.  */
457
{
458
  int rc;
459
460
  if (in_transaction)
461
    log_bug ("tdbio: nested transactions\n");
462
  /* Flush everything out. */
463
  rc = tdbio_sync();
464
  if (rc)
465
    return rc;
466
  in_transaction = 1;
467
  return 0;
468
}
469
470
int
471
tdbio_end_transaction ()  /* Not yet used.  */
472
{
473
  int rc;
474
475
  if (!in_transaction)
476
    log_bug ("tdbio: no active transaction\n");
477
  take_write_lock ();
478
  gnupg_block_all_signals ();
479
  in_transaction = 0;
480
  rc = tdbio_sync();
481
  gnupg_unblock_all_signals();
482
  release_write_lock ();
483
  return rc;
484
}
485
486
int
487
tdbio_cancel_transaction () /* Not yet used.  */
488
{
489
  CACHE_CTRL r;
490
491
  if (!in_transaction)
492
    log_bug ("tdbio: no active transaction\n");
493
494
  /* Remove all dirty marked entries, so that the original ones are
495
   * read back the next time.  */
496
  if (cache_is_dirty)
497
    {
498
      for (r = cache_list; r; r = r->next)
499
        {
500
          if (r->flags.used && r->flags.dirty)
501
            {
502
              r->flags.used = 0;
503
              cache_entries--;
504
      }
505
  }
506
      cache_is_dirty = 0;
507
    }
508
509
  in_transaction = 0;
510
  return 0;
511
}
512
#endif  /* Not yet used.  */
513
514
515

516
/********************************************************
517
 **************** cached I/O functions ******************
518
 ********************************************************/
519
520
/* The cleanup handler for this module.  */
521
static void
522
cleanup (void)
523
4
{
524
4
  if (is_locked)
525
0
    {
526
0
      if (!dotlock_release (lockhandle))
527
0
        is_locked = 0;
528
0
    }
529
4
}
530
531
532
/*
533
 * Update an existing trustdb record.  The caller must call
534
 * tdbio_sync.
535
 *
536
 * Returns: 0 on success or an error code.
537
 */
538
int
539
tdbio_update_version_record (ctrl_t ctrl)
540
409
{
541
409
  TRUSTREC rec;
542
409
  int rc;
543
409
  int opt_tm;
544
545
  /* Never store a TOFU trust model in the trustdb.  Use PGP instead.  */
546
409
  opt_tm = opt.trust_model;
547
409
  if (opt_tm == TM_TOFU || opt_tm == TM_TOFU_PGP)
548
0
    opt_tm = TM_PGP;
549
550
409
  memset (&rec, 0, sizeof rec);
551
552
409
  rc = tdbio_read_record (0, &rec, RECTYPE_VER);
553
409
  if (!rc)
554
409
    {
555
409
      rec.r.ver.created     = make_timestamp();
556
409
      rec.r.ver.marginals   = opt.marginals_needed;
557
409
      rec.r.ver.completes   = opt.completes_needed;
558
409
      rec.r.ver.cert_depth  = opt.max_cert_depth;
559
409
      rec.r.ver.trust_model = opt_tm;
560
409
      rec.r.ver.min_cert_level = opt.min_cert_level;
561
409
      rc = tdbio_write_record (ctrl, &rec);
562
409
    }
563
564
409
  return rc;
565
409
}
566
567
568
/*
569
 * Create and write the trustdb version record.
570
 * This is called with the writelock active.
571
 * Returns: 0 on success or an error code.
572
 */
573
static int
574
create_version_record (ctrl_t ctrl)
575
4
{
576
4
  TRUSTREC rec;
577
4
  int rc;
578
4
  int opt_tm;
579
580
  /* Never store a TOFU trust model in the trustdb.  Use PGP instead.  */
581
4
  opt_tm = opt.trust_model;
582
4
  if (opt_tm == TM_TOFU || opt_tm == TM_TOFU_PGP)
583
0
    opt_tm = TM_PGP;
584
585
4
  memset (&rec, 0, sizeof rec);
586
4
  rec.r.ver.version     = 3;
587
4
  rec.r.ver.created     = make_timestamp ();
588
4
  rec.r.ver.marginals   = opt.marginals_needed;
589
4
  rec.r.ver.completes   = opt.completes_needed;
590
4
  rec.r.ver.cert_depth  = opt.max_cert_depth;
591
4
  if (opt_tm == TM_PGP || opt_tm == TM_CLASSIC)
592
4
    rec.r.ver.trust_model = opt_tm;
593
0
  else
594
0
    rec.r.ver.trust_model = TM_PGP;
595
4
  rec.r.ver.min_cert_level = opt.min_cert_level;
596
4
  rec.rectype = RECTYPE_VER;
597
4
  rec.recnum = 0;
598
4
  rc = tdbio_write_record (ctrl, &rec);
599
600
4
  if (!rc)
601
4
    tdbio_sync ();
602
603
4
  if (!rc)
604
4
    create_hashtable (ctrl, &rec, 0);
605
606
4
  return rc;
607
4
}
608
609
610
/*
611
 * Set the file name for the trustdb to NEW_DBNAME and if CREATE is
612
 * true create that file.  If NEW_DBNAME is NULL a default name is
613
 * used, if the it does not contain a path component separator ('/')
614
 * the global GnuPG home directory is used.
615
 *
616
 * Returns: 0 on success or an error code.
617
 *
618
 * On the first call this function registers an atexit handler.
619
 *
620
 */
621
int
622
tdbio_set_dbname (ctrl_t ctrl, const char *new_dbname,
623
                  int create, int *r_nofile)
624
4
{
625
4
  char *fname, *p;
626
4
  struct stat statbuf;
627
4
  static int initialized = 0;
628
4
  int save_slash;
629
630
4
  if (!initialized)
631
4
    {
632
4
      atexit (cleanup);
633
4
      initialized = 1;
634
4
    }
635
636
4
  *r_nofile = 0;
637
638
4
  if (!new_dbname)
639
4
    {
640
4
      fname = make_filename (gnupg_homedir (),
641
4
                             "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
642
4
    }
643
0
  else if (*new_dbname != DIRSEP_C )
644
0
    {
645
0
      if (strchr (new_dbname, DIRSEP_C))
646
0
        fname = make_filename (new_dbname, NULL);
647
0
      else
648
0
        fname = make_filename (gnupg_homedir (), new_dbname, NULL);
649
0
    }
650
0
  else
651
0
    {
652
0
      fname = xstrdup (new_dbname);
653
0
    }
654
655
4
  xfree (db_name);
656
4
  db_name = fname;
657
658
  /* Quick check for (likely) case where there already is a
659
   * trustdb.gpg.  This check is not required in theory, but it helps
660
   * in practice avoiding costly operations of preparing and taking
661
   * the lock.  */
662
4
  if (!gnupg_stat (fname, &statbuf) && statbuf.st_size > 0)
663
0
    {
664
      /* OK, we have the valid trustdb.gpg already.  */
665
0
      return 0;
666
0
    }
667
4
  else if (!create)
668
0
    {
669
0
      *r_nofile = 1;
670
0
      return 0;
671
0
    }
672
673
  /* Here comes: No valid trustdb.gpg AND CREATE==1 */
674
675
  /*
676
   * Make sure the directory exists.  This should be done before
677
   * acquiring the lock, which assumes the existence of the directory.
678
   */
679
4
  p = strrchr (fname, DIRSEP_C);
680
#if HAVE_W32_SYSTEM
681
  {
682
    /* Windows may either have a slash or a backslash.  Take
683
       care of it.  */
684
    char *pp = strrchr (fname, '/');
685
    if (!p || pp > p)
686
      p = pp;
687
  }
688
#endif /*HAVE_W32_SYSTEM*/
689
4
  log_assert (p);
690
4
  save_slash = *p;
691
4
  *p = 0;
692
4
  if (gnupg_access (fname, F_OK))
693
0
    {
694
0
      try_make_homedir (fname);
695
0
      if (gnupg_access (fname, F_OK))
696
0
        log_fatal (_("%s: directory does not exist!\n"), fname);
697
0
    }
698
4
  *p = save_slash;
699
700
4
  take_write_lock ();
701
702
4
  if (gnupg_access (fname, R_OK)
703
0
      || gnupg_stat (fname, &statbuf)
704
0
      || statbuf.st_size == 0)
705
4
    {
706
4
      estream_t fp;
707
4
      TRUSTREC rec;
708
4
      int rc;
709
4
      mode_t oldmask;
710
711
4
      if (errno && errno != ENOENT)
712
4
        log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno));
713
714
4
      oldmask = umask (077);
715
4
      if (is_secured_filename (fname))
716
0
        {
717
0
          fp = NULL;
718
0
          gpg_err_set_errno (EPERM);
719
0
        }
720
4
      else
721
4
        fp = es_fopen (fname, "wb");
722
4
      umask(oldmask);
723
4
      if (!fp)
724
4
        log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno));
725
4
      es_fclose (fp);
726
727
4
      db_fd = gnupg_open (db_name, O_RDWR | MY_O_BINARY, 0);
728
4
      if (db_fd == -1)
729
4
        log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno));
730
731
4
      rc = create_version_record (ctrl);
732
4
      if (rc)
733
4
        log_fatal (_("%s: failed to create version record: %s"),
734
0
                   fname, gpg_strerror (rc));
735
736
      /* Read again to check that we are okay. */
737
4
      if (tdbio_read_record (0, &rec, RECTYPE_VER))
738
4
        log_fatal (_("%s: invalid trustdb created\n"), db_name);
739
740
4
      if (!opt.quiet)
741
4
        log_info (_("%s: trustdb created\n"), db_name);
742
4
    }
743
744
4
  release_write_lock ();
745
4
  return 0;
746
4
}
747
748
749
/*
750
 * Return the full name of the trustdb.
751
 */
752
const char *
753
tdbio_get_dbname (void)
754
0
{
755
0
  return db_name;
756
0
}
757
758
759
/*
760
 * Open the trustdb.  This may only be called if it has not yet been
761
 * opened and after a successful call to tdbio_set_dbname.  On return
762
 * the trustdb handle (DB_FD) is guaranteed to be open.
763
 */
764
static void
765
open_db (void)
766
0
{
767
0
  TRUSTREC rec;
768
769
0
  log_assert( db_fd == -1 );
770
771
0
  db_fd = gnupg_open (db_name, O_RDWR | MY_O_BINARY, 0);
772
0
  if (db_fd == -1 && (errno == EACCES
773
0
#ifdef EROFS
774
0
                      || errno == EROFS
775
0
#endif
776
0
                      )
777
0
      ) {
778
      /* Take care of read-only trustdbs.  */
779
0
      db_fd = gnupg_open (db_name, O_RDONLY | MY_O_BINARY, 0);
780
0
      if (db_fd != -1 && !opt.quiet)
781
0
          log_info (_("Note: trustdb not writable\n"));
782
0
  }
783
0
  if ( db_fd == -1 )
784
0
    log_fatal( _("can't open '%s': %s\n"), db_name, strerror(errno) );
785
786
0
  register_secured_file (db_name);
787
788
  /* Read the version record. */
789
0
  if (tdbio_read_record (0, &rec, RECTYPE_VER ) )
790
0
    log_fatal( _("%s: invalid trustdb\n"), db_name );
791
0
}
792
793
794
/*
795
 * Append a new empty hashtable to the trustdb.  TYPE gives the type
796
 * of the hash table.  The only defined type is 0 for a trust hash.
797
 * On return the hashtable has been created, written, the version
798
 * record update, and the data flushed to the disk.  On a fatal error
799
 * the function terminates the process.
800
 */
801
static void
802
create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type)
803
4
{
804
4
  TRUSTREC rec;
805
4
  off_t offset;
806
4
  ulong recnum;
807
4
  int i, n, rc;
808
809
4
  offset = lseek (db_fd, 0, SEEK_END);
810
4
  if (offset == -1)
811
4
    log_fatal ("trustdb: lseek to end failed: %s\n", strerror(errno));
812
4
  recnum = offset / TRUST_RECORD_LEN;
813
4
  log_assert (recnum); /* This is will never be the first record. */
814
815
4
  if (!type)
816
4
    vr->r.ver.trusthashtbl = recnum;
817
818
  /* Now write the records making up the hash table. */
819
4
  n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
820
120
  for (i=0; i < n; i++, recnum++)
821
116
    {
822
116
      memset (&rec, 0, sizeof rec);
823
116
      rec.rectype = RECTYPE_HTBL;
824
116
      rec.recnum = recnum;
825
116
      rc = tdbio_write_record (ctrl, &rec);
826
116
      if (rc)
827
116
        log_fatal (_("%s: failed to create hashtable: %s\n"),
828
0
                   db_name, gpg_strerror (rc));
829
116
    }
830
  /* Update the version record and flush. */
831
4
  rc = tdbio_write_record (ctrl, vr);
832
4
  if (!rc)
833
4
    rc = tdbio_sync ();
834
4
  if (rc)
835
4
    log_fatal (_("%s: error updating version record: %s\n"),
836
0
               db_name, gpg_strerror (rc));
837
4
}
838
839
840
/*
841
 * Check whether open trustdb matches the global trust options given
842
 * for this process.  On a read problem the process is terminated.
843
 *
844
 * Return: 1 for yes, 0 for no.
845
 */
846
int
847
tdbio_db_matches_options (void)
848
4
{
849
4
  static int yes_no = -1;
850
851
4
  if (yes_no == -1)
852
4
    {
853
4
      TRUSTREC vr;
854
4
      int rc;
855
4
      int opt_tm, tm;
856
857
4
      rc = tdbio_read_record (0, &vr, RECTYPE_VER);
858
4
      if( rc )
859
4
  log_fatal( _("%s: error reading version record: %s\n"),
860
0
       db_name, gpg_strerror (rc) );
861
862
      /* Consider tofu and pgp the same.  */
863
4
      tm = vr.r.ver.trust_model;
864
4
      if (tm == TM_TOFU || tm == TM_TOFU_PGP)
865
0
        tm = TM_PGP;
866
4
      opt_tm  = opt.trust_model;
867
4
      if (opt_tm == TM_TOFU || opt_tm == TM_TOFU_PGP)
868
0
        opt_tm = TM_PGP;
869
870
4
      yes_no = vr.r.ver.marginals == opt.marginals_needed
871
4
  && vr.r.ver.completes == opt.completes_needed
872
4
  && vr.r.ver.cert_depth == opt.max_cert_depth
873
4
  && tm == opt_tm
874
4
  && vr.r.ver.min_cert_level == opt.min_cert_level;
875
4
    }
876
877
4
  return yes_no;
878
4
}
879
880
881
/*
882
 * Read and return the trust model identifier from the trustdb.  On a
883
 * read problem the process is terminated.
884
 */
885
byte
886
tdbio_read_model (void)
887
0
{
888
0
  TRUSTREC vr;
889
0
  int rc;
890
891
0
  rc = tdbio_read_record (0, &vr, RECTYPE_VER );
892
0
  if (rc)
893
0
    log_fatal (_("%s: error reading version record: %s\n"),
894
0
         db_name, gpg_strerror (rc) );
895
0
  return vr.r.ver.trust_model;
896
0
}
897
898
899
/*
900
 * Read and return the nextstamp value from the trustdb.  On a read
901
 * problem the process is terminated.
902
 */
903
ulong
904
tdbio_read_nextcheck (void)
905
4
{
906
4
  TRUSTREC vr;
907
4
  int rc;
908
909
4
  rc = tdbio_read_record (0, &vr, RECTYPE_VER);
910
4
  if (rc)
911
4
    log_fatal (_("%s: error reading version record: %s\n"),
912
0
               db_name, gpg_strerror (rc));
913
4
  return vr.r.ver.nextcheck;
914
4
}
915
916
917
/*
918
 * Write the STAMP nextstamp timestamp to the trustdb.  On a read or
919
 * write problem the process is terminated.
920
 *
921
 * Return: True if the stamp actually changed.
922
 */
923
int
924
tdbio_write_nextcheck (ctrl_t ctrl, ulong stamp)
925
1.93k
{
926
1.93k
  TRUSTREC vr;
927
1.93k
  int rc;
928
929
1.93k
  rc = tdbio_read_record (0, &vr, RECTYPE_VER);
930
1.93k
  if (rc)
931
1.93k
    log_fatal (_("%s: error reading version record: %s\n"),
932
0
               db_name, gpg_strerror (rc));
933
934
1.93k
  if (vr.r.ver.nextcheck == stamp)
935
1.11k
    return 0;
936
937
818
  vr.r.ver.nextcheck = stamp;
938
818
  rc = tdbio_write_record (ctrl, &vr);
939
818
  if (rc)
940
818
    log_fatal (_("%s: error writing version record: %s\n"),
941
0
               db_name, gpg_strerror (rc));
942
818
  return 1;
943
818
}
944
945
946
947
/*
948
 * Return the record number of the trusthash table or create one if it
949
 * does not yet exist.  On a read or write problem the process is
950
 * terminated.
951
 *
952
 * Return: record number
953
 */
954
static ulong
955
get_trusthashrec (ctrl_t ctrl)
956
43.6k
{
957
43.6k
  static ulong trusthashtbl; /* Record number of the trust hashtable.  */
958
959
43.6k
  (void)ctrl;
960
961
43.6k
  if (!trusthashtbl)
962
3
    {
963
3
      TRUSTREC vr;
964
3
      int rc;
965
966
3
      rc = tdbio_read_record (0, &vr, RECTYPE_VER );
967
3
      if (rc)
968
3
        log_fatal (_("%s: error reading version record: %s\n"),
969
0
                   db_name, gpg_strerror (rc) );
970
971
3
      if (!vr.r.ver.trusthashtbl)
972
0
        {
973
          /* Oops: the trustdb is corrupt because the hashtable is
974
           * always created along with the version record.  However,
975
           * if something went initially wrong it may happen that
976
           * there is just the version record.  We try to fix it here.
977
           * If we can't do that we return 0 - this is the version
978
           * record and thus the actual read will detect the mismatch
979
           * and bail out.  Note that create_hashtable updates VR.  */
980
0
          take_write_lock ();
981
0
          if (lseek (db_fd, 0, SEEK_END) == TRUST_RECORD_LEN)
982
0
            create_hashtable (ctrl, &vr, 0);
983
0
          release_write_lock ();
984
0
        }
985
3
      trusthashtbl = vr.r.ver.trusthashtbl;
986
3
    }
987
988
43.6k
  return trusthashtbl;
989
43.6k
}
990
991
992
993
/*
994
 * Update a hashtable in the trustdb.  TABLE gives the start of the
995
 * table, KEY and KEYLEN are the key, NEWRECNUM is the record number
996
 * to insert into the table.
997
 *
998
 * Return: 0 on success or an error code.
999
 */
1000
static int
1001
upd_hashtable (ctrl_t ctrl, ulong table, byte *key, int keylen, ulong newrecnum)
1002
0
{
1003
0
  TRUSTREC lastrec, rec;
1004
0
  ulong hashrec, item;
1005
0
  int msb;
1006
0
  int level = 0;
1007
0
  int rc, i;
1008
1009
0
  hashrec = table;
1010
0
 next_level:
1011
0
  msb = key[level];
1012
0
  hashrec += msb / ITEMS_PER_HTBL_RECORD;
1013
0
  rc = tdbio_read_record (hashrec, &rec, RECTYPE_HTBL);
1014
0
  if (rc)
1015
0
    {
1016
0
      log_error ("upd_hashtable: read failed: %s\n", gpg_strerror (rc));
1017
0
      return rc;
1018
0
    }
1019
1020
0
  item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
1021
0
  if (!item)  /* Insert a new item into the hash table.  */
1022
0
    {
1023
0
      rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
1024
0
      rc = tdbio_write_record (ctrl, &rec);
1025
0
      if (rc)
1026
0
        {
1027
0
          log_error ("upd_hashtable: write htbl failed: %s\n",
1028
0
                     gpg_strerror (rc));
1029
0
          return rc;
1030
0
  }
1031
0
    }
1032
0
  else if (item != newrecnum) /* Must do an update.  */
1033
0
    {
1034
0
      lastrec = rec;
1035
0
      rc = tdbio_read_record (item, &rec, 0);
1036
0
      if (rc)
1037
0
        {
1038
0
          log_error ("upd_hashtable: read item failed: %s\n",
1039
0
                     gpg_strerror (rc));
1040
0
          return rc;
1041
0
  }
1042
1043
0
      if (rec.rectype == RECTYPE_HTBL)
1044
0
        {
1045
0
          hashrec = item;
1046
0
          level++;
1047
0
          if (level >= keylen)
1048
0
            {
1049
0
              log_error ("hashtable has invalid indirections.\n");
1050
0
              return GPG_ERR_TRUSTDB;
1051
0
      }
1052
0
          goto next_level;
1053
0
  }
1054
0
      else if (rec.rectype == RECTYPE_HLST) /* Extend the list.  */
1055
0
        {
1056
          /* Check whether the key is already in this list. */
1057
0
          for (;;)
1058
0
            {
1059
0
              for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1060
0
                {
1061
0
                  if (rec.r.hlst.rnum[i] == newrecnum)
1062
0
                    {
1063
0
                      return 0; /* Okay, already in the list.  */
1064
0
        }
1065
0
    }
1066
0
              if (rec.r.hlst.next)
1067
0
                {
1068
0
                  rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
1069
0
                  if (rc)
1070
0
                    {
1071
0
                      log_error ("upd_hashtable: read hlst failed: %s\n",
1072
0
                                 gpg_strerror (rc) );
1073
0
                      return rc;
1074
0
        }
1075
0
    }
1076
0
              else
1077
0
                break; /* key is not in the list */
1078
0
      }
1079
1080
          /* Find the next free entry and put it in.  */
1081
0
          for (;;)
1082
0
            {
1083
0
              for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1084
0
                {
1085
0
                  if (!rec.r.hlst.rnum[i])
1086
0
                    {
1087
                      /* Empty slot found.  */
1088
0
                      rec.r.hlst.rnum[i] = newrecnum;
1089
0
                      rc = tdbio_write_record (ctrl, &rec);
1090
0
                      if (rc)
1091
0
                        log_error ("upd_hashtable: write hlst failed: %s\n",
1092
0
                                   gpg_strerror (rc));
1093
0
                      return rc; /* Done.  */
1094
0
        }
1095
0
    }
1096
1097
0
              if (rec.r.hlst.next)
1098
0
                {
1099
                  /* read the next record of the list.  */
1100
0
                  rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
1101
0
                  if (rc)
1102
0
                    {
1103
0
                      log_error ("upd_hashtable: read hlst failed: %s\n",
1104
0
                                 gpg_strerror (rc));
1105
0
                      return rc;
1106
0
        }
1107
0
    }
1108
0
              else
1109
0
                {
1110
                  /* Append a new record to the list.  */
1111
0
                  rec.r.hlst.next = item = tdbio_new_recnum (ctrl);
1112
0
                  rc = tdbio_write_record (ctrl, &rec);
1113
0
                  if (rc)
1114
0
                    {
1115
0
                      log_error ("upd_hashtable: write hlst failed: %s\n",
1116
0
                                 gpg_strerror (rc));
1117
0
                      return rc;
1118
0
        }
1119
0
                  memset (&rec, 0, sizeof rec);
1120
0
                  rec.rectype = RECTYPE_HLST;
1121
0
                  rec.recnum = item;
1122
0
                  rec.r.hlst.rnum[0] = newrecnum;
1123
0
                  rc = tdbio_write_record (ctrl, &rec);
1124
0
                  if (rc)
1125
0
                    log_error ("upd_hashtable: write ext hlst failed: %s\n",
1126
0
                               gpg_strerror (rc));
1127
0
                  return rc; /* Done.  */
1128
0
    }
1129
0
      } /* end loop over list slots */
1130
1131
0
  }
1132
0
      else if (rec.rectype == RECTYPE_TRUST) /* Insert a list record.  */
1133
0
        {
1134
0
          if (rec.recnum == newrecnum)
1135
0
            {
1136
0
              return 0;
1137
0
            }
1138
0
          item = rec.recnum; /* Save number of key record.  */
1139
0
          memset (&rec, 0, sizeof rec);
1140
0
          rec.rectype = RECTYPE_HLST;
1141
0
          rec.recnum = tdbio_new_recnum (ctrl);
1142
0
          rec.r.hlst.rnum[0] = item;      /* Old key record */
1143
0
          rec.r.hlst.rnum[1] = newrecnum; /* and new key record */
1144
0
          rc = tdbio_write_record (ctrl, &rec);
1145
0
          if (rc)
1146
0
            {
1147
0
              log_error( "upd_hashtable: write new hlst failed: %s\n",
1148
0
                           gpg_strerror (rc) );
1149
0
              return rc;
1150
0
            }
1151
          /* Update the hashtable record.  */
1152
0
          lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
1153
0
          rc = tdbio_write_record (ctrl, &lastrec);
1154
0
          if (rc)
1155
0
            log_error ("upd_hashtable: update htbl failed: %s\n",
1156
0
                       gpg_strerror (rc));
1157
0
          return rc; /* Ready.  */
1158
0
        }
1159
0
      else
1160
0
        {
1161
0
          log_error ("hashtbl %lu: %lu/%d points to an invalid record %lu\n",
1162
0
                     table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
1163
0
          if (opt.verbose > 1)
1164
0
            list_trustdb (ctrl, es_stderr, NULL);
1165
0
          return GPG_ERR_TRUSTDB;
1166
0
  }
1167
0
    }
1168
1169
0
  return 0;
1170
0
}
1171
1172
1173
/*
1174
 * Drop an entry from a hashtable.  TABLE gives the start of the
1175
 * table, KEY and KEYLEN are the key.
1176
 *
1177
 * Return: 0 on success or an error code.
1178
 */
1179
static int
1180
drop_from_hashtable (ctrl_t ctrl, ulong table,
1181
                     byte *key, int keylen, ulong recnum)
1182
0
{
1183
0
  TRUSTREC rec;
1184
0
  ulong hashrec, item;
1185
0
  int msb;
1186
0
  int level = 0;
1187
0
  int rc, i;
1188
1189
0
  hashrec = table;
1190
0
 next_level:
1191
0
  msb = key[level];
1192
0
  hashrec += msb / ITEMS_PER_HTBL_RECORD;
1193
0
  rc = tdbio_read_record (hashrec, &rec, RECTYPE_HTBL );
1194
0
  if (rc)
1195
0
    {
1196
0
      log_error ("drop_from_hashtable: read failed: %s\n", gpg_strerror (rc));
1197
0
      return rc;
1198
0
    }
1199
1200
0
  item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
1201
0
  if (!item)
1202
0
    return 0;   /* Not found - forget about it.  */
1203
1204
0
  if (item == recnum) /* Table points direct to the record.  */
1205
0
    {
1206
0
      rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
1207
0
      rc = tdbio_write_record (ctrl, &rec);
1208
0
      if (rc)
1209
0
        log_error ("drop_from_hashtable: write htbl failed: %s\n",
1210
0
                   gpg_strerror (rc));
1211
0
      return rc;
1212
0
    }
1213
1214
0
  rc = tdbio_read_record (item, &rec, 0);
1215
0
  if (rc)
1216
0
    {
1217
0
      log_error ("drop_from_hashtable: read item failed: %s\n",
1218
0
                 gpg_strerror (rc));
1219
0
      return rc;
1220
0
    }
1221
1222
0
  if (rec.rectype == RECTYPE_HTBL)
1223
0
    {
1224
0
      hashrec = item;
1225
0
      level++;
1226
0
      if (level >= keylen)
1227
0
        {
1228
0
          log_error ("hashtable has invalid indirections.\n");
1229
0
          return GPG_ERR_TRUSTDB;
1230
0
  }
1231
0
      goto next_level;
1232
0
    }
1233
1234
0
  if (rec.rectype == RECTYPE_HLST)
1235
0
    {
1236
0
      for (;;)
1237
0
        {
1238
0
          for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1239
0
            {
1240
0
              if (rec.r.hlst.rnum[i] == recnum)
1241
0
                {
1242
0
                  rec.r.hlst.rnum[i] = 0; /* Mark as free.  */
1243
0
                  rc = tdbio_write_record (ctrl, &rec);
1244
0
                  if (rc)
1245
0
                    log_error("drop_from_hashtable: write htbl failed: %s\n",
1246
0
                              gpg_strerror (rc));
1247
0
                  return rc;
1248
0
    }
1249
0
      }
1250
0
          if (rec.r.hlst.next)
1251
0
            {
1252
0
              rc = tdbio_read_record (rec.r.hlst.next, &rec, RECTYPE_HLST);
1253
0
              if (rc)
1254
0
                {
1255
0
                  log_error ("drop_from_hashtable: read hlst failed: %s\n",
1256
0
                             gpg_strerror (rc));
1257
0
                  return rc;
1258
0
    }
1259
0
      }
1260
0
          else
1261
0
            return 0; /* Key not in table.  */
1262
0
  }
1263
0
    }
1264
1265
0
  log_error ("hashtbl %lu: %lu/%d points to wrong record %lu\n",
1266
0
             table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
1267
0
  return GPG_ERR_TRUSTDB;
1268
0
}
1269
1270
1271
1272
/*
1273
 * Lookup a record via the hashtable TABLE by (KEY,KEYLEN) and return
1274
 * the result in REC.  The return value of CMP() should be True if the
1275
 * record is the desired one.
1276
 *
1277
 * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
1278
 */
1279
static gpg_error_t
1280
lookup_hashtable (ulong table, const byte *key, size_t keylen,
1281
      int (*cmpfnc)(const void*, const TRUSTREC *),
1282
                  const void *cmpdata, TRUSTREC *rec )
1283
43.6k
{
1284
43.6k
  int rc;
1285
43.6k
  ulong hashrec, item;
1286
43.6k
  int msb;
1287
43.6k
  int level = 0;
1288
1289
43.6k
  if (!table)
1290
0
    {
1291
0
      rc = gpg_error (GPG_ERR_INV_RECORD);
1292
0
      log_error("lookup_hashtable failed: %s\n", "request for record 0");
1293
0
      return rc;
1294
0
    }
1295
1296
43.6k
  hashrec = table;
1297
43.6k
 next_level:
1298
43.6k
  msb = key[level];
1299
43.6k
  hashrec += msb / ITEMS_PER_HTBL_RECORD;
1300
43.6k
  rc = tdbio_read_record (hashrec, rec, RECTYPE_HTBL);
1301
43.6k
  if (rc)
1302
0
    {
1303
0
      log_error("lookup_hashtable failed: %s\n", gpg_strerror (rc) );
1304
0
      return rc;
1305
0
    }
1306
1307
43.6k
  item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
1308
43.6k
  if (!item)
1309
43.6k
    return gpg_error (GPG_ERR_NOT_FOUND);
1310
1311
0
  rc = tdbio_read_record (item, rec, 0);
1312
0
  if (rc)
1313
0
    {
1314
0
      log_error( "hashtable read failed: %s\n", gpg_strerror (rc) );
1315
0
      return rc;
1316
0
    }
1317
0
  if (rec->rectype == RECTYPE_HTBL)
1318
0
    {
1319
0
      hashrec = item;
1320
0
      level++;
1321
0
      if (level >= keylen)
1322
0
        {
1323
0
          log_error ("hashtable has invalid indirections\n");
1324
0
          return GPG_ERR_TRUSTDB;
1325
0
  }
1326
0
      goto next_level;
1327
0
    }
1328
0
  else if (rec->rectype == RECTYPE_HLST)
1329
0
    {
1330
0
      for (;;)
1331
0
        {
1332
0
          int i;
1333
1334
0
          for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1335
0
            {
1336
0
              if (rec->r.hlst.rnum[i])
1337
0
                {
1338
0
                  TRUSTREC tmp;
1339
1340
0
                  rc = tdbio_read_record (rec->r.hlst.rnum[i], &tmp, 0);
1341
0
                  if (rc)
1342
0
                    {
1343
0
                      log_error ("lookup_hashtable: read item failed: %s\n",
1344
0
                                 gpg_strerror (rc));
1345
0
                      return rc;
1346
0
        }
1347
0
                  if ((*cmpfnc)(cmpdata, &tmp))
1348
0
                    {
1349
0
                      *rec = tmp;
1350
0
                      return 0;
1351
0
        }
1352
0
    }
1353
0
      }
1354
0
          if (rec->r.hlst.next)
1355
0
            {
1356
0
              rc = tdbio_read_record (rec->r.hlst.next, rec, RECTYPE_HLST);
1357
0
              if (rc)
1358
0
                {
1359
0
                  log_error ("lookup_hashtable: read hlst failed: %s\n",
1360
0
                             gpg_strerror (rc) );
1361
0
                  return rc;
1362
0
    }
1363
0
      }
1364
0
          else
1365
0
            return gpg_error (GPG_ERR_NOT_FOUND);
1366
0
  }
1367
0
    }
1368
1369
0
  if ((*cmpfnc)(cmpdata, rec))
1370
0
    return 0; /* really found */
1371
1372
0
  return gpg_error (GPG_ERR_NOT_FOUND); /* no: not found */
1373
0
}
1374
1375
1376
/*
1377
 * Update the trust hash table TR or create the table if it does not
1378
 * exist.
1379
 *
1380
 * Return: 0 on success or an error code.
1381
 */
1382
static int
1383
update_trusthashtbl (ctrl_t ctrl, TRUSTREC *tr)
1384
0
{
1385
0
  return upd_hashtable (ctrl, get_trusthashrec (ctrl),
1386
0
                        tr->r.trust.fingerprint, 20, tr->recnum);
1387
0
}
1388
1389
1390
/*
1391
 * Dump the trustdb record REC to stream FP.
1392
 */
1393
void
1394
tdbio_dump_record (TRUSTREC *rec, estream_t fp)
1395
0
{
1396
0
  int i;
1397
0
  ulong rnum = rec->recnum;
1398
1399
0
  es_fprintf (fp, "rec %5lu, ", rnum);
1400
1401
0
  switch (rec->rectype)
1402
0
    {
1403
0
    case 0:
1404
0
      es_fprintf (fp, "blank\n");
1405
0
      break;
1406
1407
0
    case RECTYPE_VER:
1408
0
      es_fprintf (fp,
1409
0
         "version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d mcl=%d nc=%lu (%s)\n",
1410
0
                  rec->r.ver.trusthashtbl,
1411
0
                  rec->r.ver.firstfree,
1412
0
                  rec->r.ver.marginals,
1413
0
                  rec->r.ver.completes,
1414
0
                  rec->r.ver.cert_depth,
1415
0
                  rec->r.ver.trust_model,
1416
0
                  rec->r.ver.min_cert_level,
1417
0
                  rec->r.ver.nextcheck,
1418
0
                  strtimestamp(rec->r.ver.nextcheck)
1419
0
                  );
1420
0
      break;
1421
1422
0
    case RECTYPE_FREE:
1423
0
      es_fprintf (fp, "free, next=%lu\n", rec->r.free.next);
1424
0
      break;
1425
1426
0
    case RECTYPE_HTBL:
1427
0
      es_fprintf (fp, "htbl,");
1428
0
      for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
1429
0
        es_fprintf (fp, " %lu", rec->r.htbl.item[i]);
1430
0
      es_putc ('\n', fp);
1431
0
      break;
1432
1433
0
    case RECTYPE_HLST:
1434
0
      es_fprintf (fp, "hlst, next=%lu,", rec->r.hlst.next);
1435
0
      for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1436
0
        es_fprintf (fp, " %lu", rec->r.hlst.rnum[i]);
1437
0
      es_putc ('\n', fp);
1438
0
      break;
1439
1440
0
    case RECTYPE_TRUST:
1441
0
      es_fprintf (fp, "trust ");
1442
0
      for (i=0; i < 20; i++)
1443
0
        es_fprintf (fp, "%02X", rec->r.trust.fingerprint[i]);
1444
0
      es_fprintf (fp, ", ot=%d, d=%d, vl=%lu, mo=%d, f=%02x\n",
1445
0
                  rec->r.trust.ownertrust,
1446
0
                  rec->r.trust.depth, rec->r.trust.validlist,
1447
0
                  rec->r.trust.min_ownertrust, rec->r.trust.flags);
1448
0
      break;
1449
1450
0
    case RECTYPE_VALID:
1451
0
      es_fprintf (fp, "valid ");
1452
0
      for (i=0; i < 20; i++)
1453
0
        es_fprintf(fp, "%02X", rec->r.valid.namehash[i]);
1454
0
      es_fprintf (fp, ", v=%d, next=%lu, f=%d, m=%d\n",
1455
0
                  rec->r.valid.validity, rec->r.valid.next,
1456
0
                  rec->r.valid.full_count, rec->r.valid.marginal_count);
1457
0
      break;
1458
1459
0
    default:
1460
0
      es_fprintf (fp, "unknown type %d\n", rec->rectype );
1461
0
      break;
1462
0
    }
1463
0
}
1464
1465
1466
/*
1467
 * Read the record with number RECNUM into the structure REC.  If
1468
 * EXPECTED is not 0 reading any other record type will return an
1469
 * error.
1470
 *
1471
 * Return: 0 on success or an error code.
1472
 */
1473
int
1474
tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
1475
58.3k
{
1476
58.3k
  byte readbuf[TRUST_RECORD_LEN];
1477
58.3k
  const byte *buf, *p;
1478
58.3k
  gpg_error_t err = 0;
1479
58.3k
  int n, i;
1480
1481
58.3k
  if (db_fd == -1)
1482
0
    open_db ();
1483
1484
58.3k
  buf = get_record_from_cache( recnum );
1485
58.3k
  if (!buf)
1486
413
    {
1487
413
      if (lseek (db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET) == -1)
1488
0
        {
1489
0
          err = gpg_error_from_syserror ();
1490
0
          log_error (_("trustdb: lseek failed: %s\n"), strerror (errno));
1491
0
          return err;
1492
0
  }
1493
413
      n = read (db_fd, readbuf, TRUST_RECORD_LEN);
1494
413
      if (!n)
1495
413
        {
1496
413
          return gpg_error (GPG_ERR_EOF);
1497
413
  }
1498
0
      else if (n != TRUST_RECORD_LEN)
1499
0
        {
1500
0
          err = gpg_error_from_syserror ();
1501
0
          log_error (_("trustdb: read failed (n=%d): %s\n"),
1502
0
                     n, strerror(errno));
1503
0
          return err;
1504
0
  }
1505
0
      buf = readbuf;
1506
0
    }
1507
57.9k
  rec->recnum = recnum;
1508
57.9k
  rec->dirty = 0;
1509
57.9k
  p = buf;
1510
57.9k
  rec->rectype = *p++;
1511
57.9k
  if (expected && rec->rectype != expected)
1512
0
    {
1513
0
      log_error ("%lu: read expected rec type %d, got %d\n",
1514
0
                 recnum, expected, rec->rectype);
1515
0
      return gpg_error (GPG_ERR_TRUSTDB);
1516
0
    }
1517
57.9k
  p++;    /* Skip reserved byte.  */
1518
57.9k
  switch (rec->rectype)
1519
57.9k
    {
1520
0
    case 0:  /* unused (free) record */
1521
0
      break;
1522
1523
2.35k
    case RECTYPE_VER: /* version record */
1524
2.35k
      if (memcmp(buf+1, GPGEXT_GPG, 3))
1525
0
        {
1526
0
          log_error (_("%s: not a trustdb file\n"), db_name );
1527
0
          err = gpg_error (GPG_ERR_TRUSTDB);
1528
0
        }
1529
2.35k
      else
1530
2.35k
        {
1531
2.35k
          p += 2; /* skip "gpg" */
1532
2.35k
          rec->r.ver.version  = *p++;
1533
2.35k
          rec->r.ver.marginals = *p++;
1534
2.35k
          rec->r.ver.completes = *p++;
1535
2.35k
          rec->r.ver.cert_depth = *p++;
1536
2.35k
          rec->r.ver.trust_model = *p++;
1537
2.35k
          rec->r.ver.min_cert_level = *p++;
1538
2.35k
          p += 2;
1539
2.35k
          rec->r.ver.created  = buf32_to_ulong(p);
1540
2.35k
          p += 4;
1541
2.35k
          rec->r.ver.nextcheck = buf32_to_ulong(p);
1542
2.35k
          p += 4;
1543
2.35k
          p += 4;
1544
2.35k
          p += 4;
1545
2.35k
          rec->r.ver.firstfree = buf32_to_ulong(p);
1546
2.35k
          p += 4;
1547
2.35k
          p += 4;
1548
2.35k
          rec->r.ver.trusthashtbl = buf32_to_ulong(p);
1549
2.35k
          if (recnum)
1550
0
            {
1551
0
              log_error( _("%s: version record with recnum %lu\n"), db_name,
1552
0
                         (ulong)recnum );
1553
0
              err = gpg_error (GPG_ERR_TRUSTDB);
1554
0
            }
1555
2.35k
          else if (rec->r.ver.version != 3)
1556
0
            {
1557
0
              log_error( _("%s: invalid file version %d\n"), db_name,
1558
0
                         rec->r.ver.version );
1559
0
              err = gpg_error (GPG_ERR_TRUSTDB);
1560
0
            }
1561
2.35k
        }
1562
2.35k
      break;
1563
1564
0
    case RECTYPE_FREE:
1565
0
      rec->r.free.next  = buf32_to_ulong(p);
1566
0
      break;
1567
1568
55.6k
    case RECTYPE_HTBL:
1569
556k
      for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
1570
500k
        {
1571
500k
          rec->r.htbl.item[i] = buf32_to_ulong(p);
1572
500k
          p += 4;
1573
500k
  }
1574
55.6k
      break;
1575
1576
0
    case RECTYPE_HLST:
1577
0
      rec->r.hlst.next = buf32_to_ulong(p);
1578
0
      p += 4;
1579
0
      for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
1580
0
        {
1581
0
          rec->r.hlst.rnum[i] = buf32_to_ulong(p);
1582
0
          p += 4;
1583
0
  }
1584
0
      break;
1585
1586
0
    case RECTYPE_TRUST:
1587
0
      memcpy (rec->r.trust.fingerprint, p, 20);
1588
0
      p+=20;
1589
0
      rec->r.trust.ownertrust = *p++;
1590
0
      rec->r.trust.depth = *p++;
1591
0
      rec->r.trust.min_ownertrust = *p++;
1592
0
      rec->r.trust.flags = *p++;
1593
0
      rec->r.trust.validlist = buf32_to_ulong(p);
1594
0
      break;
1595
1596
0
    case RECTYPE_VALID:
1597
0
      memcpy (rec->r.valid.namehash, p, 20);
1598
0
      p+=20;
1599
0
      rec->r.valid.validity = *p++;
1600
0
      rec->r.valid.next = buf32_to_ulong(p);
1601
0
      p += 4;
1602
0
      rec->r.valid.full_count = *p++;
1603
0
      rec->r.valid.marginal_count = *p++;
1604
0
      break;
1605
1606
0
    default:
1607
0
      log_error ("%s: invalid record type %d at recnum %lu\n",
1608
0
                 db_name, rec->rectype, (ulong)recnum);
1609
0
      err = gpg_error (GPG_ERR_TRUSTDB);
1610
0
      break;
1611
57.9k
    }
1612
1613
57.9k
  return err;
1614
57.9k
}
1615
1616
1617
/*
1618
 * Write the record from the struct REC.
1619
 *
1620
 * Return: 0 on success or an error code.
1621
 */
1622
int
1623
tdbio_write_record (ctrl_t ctrl, TRUSTREC *rec)
1624
1.35k
{
1625
1.35k
  byte buf[TRUST_RECORD_LEN];
1626
1.35k
  byte *p;
1627
1.35k
  int rc = 0;
1628
1.35k
  int i;
1629
1.35k
  ulong recnum = rec->recnum;
1630
1631
1.35k
  if (db_fd == -1)
1632
0
    open_db ();
1633
1634
1.35k
  memset (buf, 0, TRUST_RECORD_LEN);
1635
1.35k
  p = buf;
1636
1.35k
  *p++ = rec->rectype; p++;
1637
1638
1.35k
  switch (rec->rectype)
1639
1.35k
    {
1640
0
    case 0:  /* unused record */
1641
0
      break;
1642
1643
1.23k
    case RECTYPE_VER: /* version record */
1644
1.23k
      if (recnum)
1645
0
        BUG ();
1646
1.23k
      memcpy(p-1, GPGEXT_GPG, 3 ); p += 2;
1647
1.23k
      *p++ = rec->r.ver.version;
1648
1.23k
      *p++ = rec->r.ver.marginals;
1649
1.23k
      *p++ = rec->r.ver.completes;
1650
1.23k
      *p++ = rec->r.ver.cert_depth;
1651
1.23k
      *p++ = rec->r.ver.trust_model;
1652
1.23k
      *p++ = rec->r.ver.min_cert_level;
1653
1.23k
      p += 2;
1654
1.23k
      ulongtobuf(p, rec->r.ver.created); p += 4;
1655
1.23k
      ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
1656
1.23k
      p += 4;
1657
1.23k
      p += 4;
1658
1.23k
      ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
1659
1.23k
      p += 4;
1660
1.23k
      ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
1661
1.23k
      break;
1662
1663
0
    case RECTYPE_FREE:
1664
0
      ulongtobuf(p, rec->r.free.next); p += 4;
1665
0
      break;
1666
1667
116
    case RECTYPE_HTBL:
1668
1.16k
      for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
1669
1.04k
        {
1670
1.04k
          ulongtobuf( p, rec->r.htbl.item[i]); p += 4;
1671
1.04k
        }
1672
116
      break;
1673
1674
0
    case RECTYPE_HLST:
1675
0
      ulongtobuf( p, rec->r.hlst.next); p += 4;
1676
0
      for (i=0; i < ITEMS_PER_HLST_RECORD; i++ )
1677
0
        {
1678
0
          ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4;
1679
0
  }
1680
0
      break;
1681
1682
0
    case RECTYPE_TRUST:
1683
0
      memcpy (p, rec->r.trust.fingerprint, 20); p += 20;
1684
0
      *p++ = rec->r.trust.ownertrust;
1685
0
      *p++ = rec->r.trust.depth;
1686
0
      *p++ = rec->r.trust.min_ownertrust;
1687
0
      *p++ = rec->r.trust.flags;
1688
0
      ulongtobuf( p, rec->r.trust.validlist); p += 4;
1689
0
      break;
1690
1691
0
    case RECTYPE_VALID:
1692
0
      memcpy (p, rec->r.valid.namehash, 20); p += 20;
1693
0
      *p++ = rec->r.valid.validity;
1694
0
      ulongtobuf( p, rec->r.valid.next); p += 4;
1695
0
      *p++ = rec->r.valid.full_count;
1696
0
      *p++ = rec->r.valid.marginal_count;
1697
0
      break;
1698
1699
0
    default:
1700
0
      BUG();
1701
1.35k
    }
1702
1703
1.35k
  rc = put_record_into_cache (recnum, buf);
1704
1.35k
  if (rc)
1705
0
    ;
1706
1.35k
  else if (rec->rectype == RECTYPE_TRUST)
1707
0
    rc = update_trusthashtbl (ctrl, rec);
1708
1709
1.35k
  return rc;
1710
1.35k
}
1711
1712
1713
/*
1714
 * Delete the record at record number RECNUm from the trustdb.
1715
 *
1716
 * Return: 0 on success or an error code.
1717
 */
1718
int
1719
tdbio_delete_record (ctrl_t ctrl, ulong recnum)
1720
0
{
1721
0
  TRUSTREC vr, rec;
1722
0
  int rc;
1723
1724
  /* Must read the record fist, so we can drop it from the hash tables */
1725
0
  rc = tdbio_read_record (recnum, &rec, 0);
1726
0
  if (rc)
1727
0
    ;
1728
0
  else if (rec.rectype == RECTYPE_TRUST)
1729
0
    {
1730
0
      rc = drop_from_hashtable (ctrl, get_trusthashrec (ctrl),
1731
0
                                rec.r.trust.fingerprint, 20, rec.recnum);
1732
0
    }
1733
1734
0
  if (rc)
1735
0
    return rc;
1736
1737
  /* Now we can change it to a free record.  */
1738
0
  rc = tdbio_read_record (0, &vr, RECTYPE_VER);
1739
0
  if (rc)
1740
0
    log_fatal (_("%s: error reading version record: %s\n"),
1741
0
               db_name, gpg_strerror (rc));
1742
1743
0
  rec.recnum = recnum;
1744
0
  rec.rectype = RECTYPE_FREE;
1745
0
  rec.r.free.next = vr.r.ver.firstfree;
1746
0
  vr.r.ver.firstfree = recnum;
1747
0
  rc = tdbio_write_record (ctrl, &rec);
1748
0
  if (!rc)
1749
0
    rc = tdbio_write_record (ctrl, &vr);
1750
1751
0
  return rc;
1752
0
}
1753
1754
1755
/*
1756
 * Create a new record and return its record number.
1757
 */
1758
ulong
1759
tdbio_new_recnum (ctrl_t ctrl)
1760
0
{
1761
0
  off_t offset;
1762
0
  ulong recnum;
1763
0
  TRUSTREC vr, rec;
1764
0
  int rc;
1765
1766
  /* Look for unused records.  */
1767
0
  rc = tdbio_read_record (0, &vr, RECTYPE_VER);
1768
0
  if (rc)
1769
0
    log_fatal( _("%s: error reading version record: %s\n"),
1770
0
               db_name, gpg_strerror (rc));
1771
0
  if (vr.r.ver.firstfree)
1772
0
    {
1773
0
      recnum = vr.r.ver.firstfree;
1774
0
      rc = tdbio_read_record (recnum, &rec, RECTYPE_FREE);
1775
0
      if (rc)
1776
0
        log_fatal (_("%s: error reading free record: %s\n"),
1777
0
                   db_name, gpg_strerror (rc));
1778
      /* Update dir record.  */
1779
0
      vr.r.ver.firstfree = rec.r.free.next;
1780
0
      rc = tdbio_write_record (ctrl, &vr);
1781
0
      if (rc)
1782
0
        log_fatal (_("%s: error writing dir record: %s\n"),
1783
0
                   db_name, gpg_strerror (rc));
1784
      /* Zero out the new record.  */
1785
0
      memset (&rec, 0, sizeof rec);
1786
0
      rec.rectype = 0; /* Mark as unused record (actually already done
1787
                          my the memset).  */
1788
0
      rec.recnum = recnum;
1789
0
      rc = tdbio_write_record (ctrl, &rec);
1790
0
      if (rc)
1791
0
        log_fatal (_("%s: failed to zero a record: %s\n"),
1792
0
                   db_name, gpg_strerror (rc));
1793
0
    }
1794
0
  else /* Not found - append a new record.  */
1795
0
    {
1796
0
      offset = lseek (db_fd, 0, SEEK_END);
1797
0
      if (offset == (off_t)(-1))
1798
0
        log_fatal ("trustdb: lseek to end failed: %s\n", strerror (errno));
1799
0
      recnum = offset / TRUST_RECORD_LEN;
1800
0
      log_assert (recnum); /* This will never be the first record */
1801
      /* We must write a record, so that the next call to this
1802
       * function returns another recnum.  */
1803
0
      memset (&rec, 0, sizeof rec);
1804
0
      rec.rectype = 0; /* unused record */
1805
0
      rec.recnum = recnum;
1806
0
      rc = 0;
1807
0
      if (lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET) == -1)
1808
0
        {
1809
0
          rc = gpg_error_from_syserror ();
1810
0
          log_error (_("trustdb rec %lu: lseek failed: %s\n"),
1811
0
                     recnum, strerror (errno));
1812
0
  }
1813
0
      else
1814
0
        {
1815
0
          int n;
1816
1817
0
          n = write (db_fd, &rec, TRUST_RECORD_LEN);
1818
0
          if (n != TRUST_RECORD_LEN)
1819
0
            {
1820
0
              rc = gpg_error_from_syserror ();
1821
0
              log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"),
1822
0
                         recnum, n, gpg_strerror (rc));
1823
0
      }
1824
0
  }
1825
1826
0
      if (rc)
1827
0
        log_fatal (_("%s: failed to append a record: %s\n"),
1828
0
                   db_name, gpg_strerror (rc));
1829
0
    }
1830
1831
0
  return recnum ;
1832
0
}
1833
1834
1835
1836
/* Helper function for tdbio_search_trust_byfpr.  */
1837
static int
1838
cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec )
1839
0
{
1840
0
  return (rec->rectype == RECTYPE_TRUST
1841
0
          && !memcmp (rec->r.trust.fingerprint, fpr, 20));
1842
0
}
1843
1844
1845
/*
1846
 * Given a 20 byte FINGERPRINT search its trust record and return
1847
 * that at REC.
1848
 *
1849
 * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
1850
 */
1851
gpg_error_t
1852
tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fpr, unsigned int fprlen,
1853
                          TRUSTREC *rec)
1854
43.6k
{
1855
43.6k
  int rc;
1856
43.6k
  byte fingerprint[20];
1857
1858
43.6k
  if (fprlen != 20)
1859
0
    {
1860
0
      fpr20_from_fpr (fpr, fprlen, fingerprint);
1861
0
      fpr = fingerprint;
1862
0
    }
1863
1864
  /* Locate the trust record using the hash table */
1865
43.6k
  rc = lookup_hashtable (get_trusthashrec (ctrl), fpr, 20,
1866
43.6k
                         cmp_trec_fpr, fpr, rec);
1867
43.6k
  return rc;
1868
43.6k
}
1869
1870
1871
/*
1872
 * Given a primary public key object PK search its trust record and
1873
 * return that at REC.
1874
 *
1875
 * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
1876
 */
1877
gpg_error_t
1878
tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
1879
43.6k
{
1880
43.6k
  byte fingerprint[20];
1881
1882
43.6k
  fpr20_from_pk (pk, fingerprint);
1883
43.6k
  return tdbio_search_trust_byfpr (ctrl, fingerprint, 20, rec);
1884
43.6k
}
1885
1886
1887
/*
1888
 * Terminate the process with a message about a corrupted trustdb.
1889
 */
1890
void
1891
tdbio_invalid (void)
1892
0
{
1893
0
  log_error (_("Error: The trustdb is corrupted.\n"));
1894
0
  how_to_fix_the_trustdb ();
1895
0
  g10_exit (2);
1896
0
}