Coverage Report

Created: 2026-10-28 06:32

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