Coverage Report

Created: 2026-01-09 06:46

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