2
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27
#include <sys/types.h>
43
#if defined(HAVE_DOSISH_SYSTEM)
44
#define ftruncate chsize
47
#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
48
#define MY_O_BINARY O_BINARY
55
* Yes, this is a very simple implementation. We should really
56
* use a page aligned buffer and read complete pages.
57
* To implement a simple trannsaction system, this is sufficient.
59
typedef struct cache_ctrl_struct *CACHE_CTRL;
60
struct cache_ctrl_struct {
67
char data[TRUST_RECORD_LEN];
70
#define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */
71
#define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */
72
static CACHE_CTRL cache_list;
73
static int cache_entries;
74
static int cache_is_dirty;
76
/* a type used to pass infomation to cmp_krec_fpr */
77
struct cmp_krec_fpr_struct {
83
/* a type used to pass infomation to cmp_[s]dir */
84
struct cmp_xdir_struct {
91
static DOTLOCK lockhandle;
93
static int db_fd = -1;
94
static int in_transaction;
96
static void open_db(void);
97
static void migrate_from_v2 (void);
101
/*************************************
102
************* record cache **********
103
*************************************/
106
* Get the data from therecord cache and return a
107
* pointer into that cache. Caller should copy
108
* the return data. NULL is returned on a cache miss.
111
get_record_from_cache( ulong recno )
115
for( r = cache_list; r; r = r->next ) {
116
if( r->flags.used && r->recno == recno )
124
write_cache_item( CACHE_CTRL r )
129
if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
130
rc = gpg_error_from_errno (errno);
131
log_error(_("trustdb rec %lu: lseek failed: %s\n"),
132
r->recno, strerror(errno) );
135
n = write( db_fd, r->data, TRUST_RECORD_LEN);
136
if( n != TRUST_RECORD_LEN ) {
137
rc = gpg_error_from_errno (errno);
138
log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
139
r->recno, n, strerror(errno) );
147
* Put data into the cache. This function may flush the
148
* some cache entries if there is not enough space available.
151
put_record_into_cache( ulong recno, const char *data )
153
CACHE_CTRL r, unused;
157
/* see whether we already cached this one */
158
for( unused = NULL, r = cache_list; r; r = r->next ) {
159
if( !r->flags.used ) {
163
else if( r->recno == recno ) {
164
if( !r->flags.dirty ) {
165
/* Hmmm: should we use a a copy and compare? */
166
if( memcmp(r->data, data, TRUST_RECORD_LEN ) ) {
171
memcpy( r->data, data, TRUST_RECORD_LEN );
174
if( r->flags.used ) {
181
/* not in the cache: add a new entry */
182
if( unused ) { /* reuse this entry */
186
memcpy( r->data, data, TRUST_RECORD_LEN );
192
/* see whether we reached the limit */
193
if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */
194
r = xmalloc ( sizeof *r );
197
memcpy( r->data, data, TRUST_RECORD_LEN );
199
r->next = cache_list;
205
/* cache is full: discard some clean entries */
207
int n = clean_count / 3; /* discard a third of the clean entries */
210
for( unused = NULL, r = cache_list; r; r = r->next ) {
211
if( r->flags.used && !r->flags.dirty ) {
224
memcpy( r->data, data, TRUST_RECORD_LEN );
230
/* no clean entries: have to flush some dirty entries */
231
if( in_transaction ) {
232
/* but we can't do this while in a transaction
233
* we increase the cache size instead */
234
if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */
235
if( opt.debug && !(cache_entries % 100) )
236
log_debug("increasing tdbio cache size\n");
237
r = xmalloc ( sizeof *r );
240
memcpy( r->data, data, TRUST_RECORD_LEN );
242
r->next = cache_list;
248
log_info(_("trustdb transaction too large\n"));
249
return GPG_ERR_RESOURCE_LIMIT;
252
int n = dirty_count / 5; /* discard some dirty entries */
256
if( make_dotlock( lockhandle, -1 ) )
257
log_fatal("can't acquire lock - giving up\n");
261
for( unused = NULL, r = cache_list; r; r = r->next ) {
262
if( r->flags.used && r->flags.dirty ) {
263
int rc = write_cache_item( r );
274
if( !opt.lock_once ) {
275
if( !release_dotlock( lockhandle ) )
282
memcpy( r->data, data, TRUST_RECORD_LEN );
295
return cache_is_dirty;
300
* Flush the cache. This cannot be used while in a transaction.
311
log_bug("tdbio: syncing while in transaction\n");
313
if( !cache_is_dirty )
317
if( make_dotlock( lockhandle, -1 ) )
318
log_fatal("can't acquire lock - giving up\n");
323
for( r = cache_list; r; r = r->next ) {
324
if( r->flags.used && r->flags.dirty ) {
325
int rc = write_cache_item( r );
331
if( did_lock && !opt.lock_once ) {
332
if( !release_dotlock( lockhandle ) )
341
/* The transaction code is disabled in the 1.2.x branch, as it is not
342
yet used. It will be enabled in 1.3.x. */
345
* Simple transactions system:
346
* Everything between begin_transaction and end/cancel_transaction
347
* is not immediatly written but at the time of end_transaction.
351
tdbio_begin_transaction()
356
log_bug("tdbio: nested transactions\n");
357
/* flush everything out */
366
tdbio_end_transaction()
370
if( !in_transaction )
371
log_bug("tdbio: no active transaction\n");
373
if( make_dotlock( lockhandle, -1 ) )
374
log_fatal("can't acquire lock - giving up\n");
378
#warning block_all_signals is not yet available in ../common/signals.c
379
/* block_all_signals(); */
382
/* unblock_all_signals(); */
383
if( !opt.lock_once ) {
384
if( !release_dotlock( lockhandle ) )
391
tdbio_cancel_transaction()
395
if( !in_transaction )
396
log_bug("tdbio: no active transaction\n");
398
/* remove all dirty marked entries, so that the original ones
399
* are read back the next time */
400
if( cache_is_dirty ) {
401
for( r = cache_list; r; r = r->next ) {
402
if( r->flags.used && r->flags.dirty ) {
414
#endif /* transaction code */
418
/********************************************************
419
**************** cached I/O functions ******************
420
********************************************************/
426
if( !release_dotlock(lockhandle) )
431
/* Caller must sync */
433
tdbio_update_version_record (void)
438
memset( &rec, 0, sizeof rec );
440
rc=tdbio_read_record( 0, &rec, RECTYPE_VER);
443
rec.r.ver.created = make_timestamp();
444
rec.r.ver.marginals = opt.marginals_needed;
445
rec.r.ver.completes = opt.completes_needed;
446
rec.r.ver.cert_depth = opt.max_cert_depth;
447
rec.r.ver.trust_model = opt.trust_model;
448
rc=tdbio_write_record(&rec);
455
create_version_record (void)
460
memset( &rec, 0, sizeof rec );
461
rec.r.ver.version = 3;
462
rec.r.ver.created = make_timestamp();
463
rec.r.ver.marginals = opt.marginals_needed;
464
rec.r.ver.completes = opt.completes_needed;
465
rec.r.ver.cert_depth = opt.max_cert_depth;
466
if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
467
rec.r.ver.trust_model = opt.trust_model;
469
rec.r.ver.trust_model = TM_PGP;
470
rec.rectype = RECTYPE_VER;
472
rc = tdbio_write_record( &rec );
481
tdbio_set_dbname( const char *new_dbname, int create )
484
static int initialized = 0;
492
fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL);
493
else if (*new_dbname != DIRSEP_C )
495
if (strchr(new_dbname, DIRSEP_C) )
496
fname = make_filename (new_dbname, NULL);
498
fname = make_filename (opt.homedir, new_dbname, NULL);
501
fname = xstrdup (new_dbname);
503
if( access( fname, R_OK ) ) {
504
if( errno != ENOENT ) {
505
log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
507
return GPG_ERR_TRUSTDB;
513
char *p = strrchr( fname, DIRSEP_C );
518
if( access( fname, F_OK ) ) {
519
try_make_homedir( fname );
520
log_fatal( _("%s: directory does not exist!\n"), fname );
528
lockhandle = create_dotlock( db_name );
530
log_fatal( _("%s: can't create lock\n"), db_name );
531
if( make_dotlock( lockhandle, -1 ) )
532
log_fatal( _("%s: can't make lock\n"), db_name );
533
#endif /* __riscos__ */
535
fp =fopen( fname, "wb" );
538
log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
540
db_fd = open( db_name, O_RDWR | MY_O_BINARY );
542
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
546
lockhandle = create_dotlock( db_name );
548
log_fatal( _("%s: can't create lock\n"), db_name );
549
#endif /* !__riscos__ */
551
rc = create_version_record ();
553
log_fatal( _("%s: failed to create version record: %s"),
554
fname, gpg_strerror (rc));
555
/* and read again to check that we are okay */
556
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
557
log_fatal( _("%s: invalid trustdb created\n"), db_name );
560
log_info(_("%s: trustdb created\n"), db_name);
586
assert( db_fd == -1 );
589
lockhandle = create_dotlock( db_name );
591
log_fatal( _("%s: can't create lock\n"), db_name );
593
if (make_dotlock( lockhandle, -1 ) )
594
log_fatal( _("%s: can't make lock\n"), db_name );
595
#endif /* __riscos__ */
596
db_fd = open (db_name, O_RDWR | MY_O_BINARY );
597
if (db_fd == -1 && errno == EACCES) {
598
db_fd = open (db_name, O_RDONLY | MY_O_BINARY );
600
log_info (_("NOTE: trustdb not writable\n"));
603
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
605
/* check whether we need to do a version migration */
607
n = read (db_fd, buf, 5);
608
while (n==-1 && errno == EINTR);
609
if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5))
614
/* read the version record */
615
if (tdbio_read_record (0, &rec, RECTYPE_VER ) )
616
log_fatal( _("%s: invalid trustdb\n"), db_name );
621
* Make a hashtable: type 0 = trust hash
624
create_hashtable( TRUSTREC *vr, int type )
631
offset = lseek( db_fd, 0, SEEK_END );
633
log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
634
recnum = offset / TRUST_RECORD_LEN;
635
assert(recnum); /* this is will never be the first record */
638
vr->r.ver.trusthashtbl = recnum;
640
/* Now write the records */
641
n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
642
for(i=0; i < n; i++, recnum++ ) {
643
memset( &rec, 0, sizeof rec );
644
rec.rectype = RECTYPE_HTBL;
646
rc = tdbio_write_record( &rec );
648
log_fatal( _("%s: failed to create hashtable: %s\n"),
649
db_name, gpg_strerror (rc));
651
/* update the version record */
652
rc = tdbio_write_record( vr );
656
log_fatal( _("%s: error updating version record: %s\n"),
657
db_name, gpg_strerror (rc));
662
tdbio_db_matches_options()
664
static int yes_no = -1;
671
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
673
log_fatal( _("%s: error reading version record: %s\n"),
674
db_name, gpg_strerror (rc) );
676
yes_no = vr.r.ver.marginals == opt.marginals_needed
677
&& vr.r.ver.completes == opt.completes_needed
678
&& vr.r.ver.cert_depth == opt.max_cert_depth
679
&& vr.r.ver.trust_model == opt.trust_model;
686
tdbio_read_model(void)
691
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
693
log_fatal( _("%s: error reading version record: %s\n"),
694
db_name, gpg_strerror (rc) );
695
return vr.r.ver.trust_model;
699
* Return the nextstamp value.
702
tdbio_read_nextcheck ()
707
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
709
log_fatal( _("%s: error reading version record: %s\n"),
710
db_name, gpg_strerror (rc) );
711
return vr.r.ver.nextcheck;
714
/* Return true when the stamp was actually changed. */
716
tdbio_write_nextcheck (ulong stamp)
721
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
723
log_fatal( _("%s: error reading version record: %s\n"),
724
db_name, gpg_strerror (rc) );
726
if (vr.r.ver.nextcheck == stamp)
729
vr.r.ver.nextcheck = stamp;
730
rc = tdbio_write_record( &vr );
732
log_fatal( _("%s: error writing version record: %s\n"),
733
db_name, gpg_strerror (rc) );
740
* Return the record number of the trusthash tbl or create a new one.
743
get_trusthashrec(void)
745
static ulong trusthashtbl; /* record number of the trust hashtable */
747
if( !trusthashtbl ) {
751
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
753
log_fatal( _("%s: error reading version record: %s\n"),
754
db_name, gpg_strerror (rc) );
755
if( !vr.r.ver.trusthashtbl )
756
create_hashtable( &vr, 0 );
758
trusthashtbl = vr.r.ver.trusthashtbl;
766
* Update a hashtable.
767
* table gives the start of the table, key and keylen is the key,
768
* newrecnum is the record number to insert.
771
upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
773
TRUSTREC lastrec, rec;
782
hashrec += msb / ITEMS_PER_HTBL_RECORD;
783
rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
785
log_error ("upd_hashtable in `%s': read failed: %s\n", db_name,
790
item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
791
if( !item ) { /* insert a new item into the hash table */
792
rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
793
rc = tdbio_write_record( &rec );
795
log_error ("upd_hashtable in `%s': write htbl failed: %s\n",
796
db_name, gpg_strerror (rc) );
800
else if( item != newrecnum ) { /* must do an update */
802
rc = tdbio_read_record( item, &rec, 0 );
804
log_error( "upd_hashtable: read item failed: %s\n",
809
if( rec.rectype == RECTYPE_HTBL ) {
812
if( level >= keylen ) {
813
log_error( "hashtable has invalid indirections.\n");
814
return GPG_ERR_TRUSTDB;
818
else if( rec.rectype == RECTYPE_HLST ) { /* extend list */
819
/* see whether the key is already in this list */
821
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
822
if( rec.r.hlst.rnum[i] == newrecnum ) {
823
return 0; /* okay, already in the list */
826
if( rec.r.hlst.next ) {
827
rc = tdbio_read_record( rec.r.hlst.next,
830
log_error( "upd_hashtable: read hlst failed: %s\n",
836
break; /* not there */
838
/* find the next free entry and put it in */
840
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
841
if( !rec.r.hlst.rnum[i] ) {
842
rec.r.hlst.rnum[i] = newrecnum;
843
rc = tdbio_write_record( &rec );
845
log_error( "upd_hashtable: write hlst failed: %s\n",
847
return rc; /* done */
850
if( rec.r.hlst.next ) {
851
rc = tdbio_read_record( rec.r.hlst.next,
852
&rec, RECTYPE_HLST );
854
log_error( "upd_hashtable: read hlst failed: %s\n",
859
else { /* add a new list record */
860
rec.r.hlst.next = item = tdbio_new_recnum();
861
rc = tdbio_write_record( &rec );
863
log_error( "upd_hashtable: write hlst failed: %s\n",
867
memset( &rec, 0, sizeof rec );
868
rec.rectype = RECTYPE_HLST;
870
rec.r.hlst.rnum[0] = newrecnum;
871
rc = tdbio_write_record( &rec );
873
log_error( "upd_hashtable: write ext hlst failed: %s\n",
875
return rc; /* done */
877
} /* end loop over hlst slots */
879
else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */
880
if( rec.recnum == newrecnum ) {
883
item = rec.recnum; /* save number of key record */
884
memset( &rec, 0, sizeof rec );
885
rec.rectype = RECTYPE_HLST;
886
rec.recnum = tdbio_new_recnum();
887
rec.r.hlst.rnum[0] = item; /* old keyrecord */
888
rec.r.hlst.rnum[1] = newrecnum; /* and new one */
889
rc = tdbio_write_record( &rec );
891
log_error( "upd_hashtable: write new hlst failed: %s\n",
895
/* update the hashtable record */
896
lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
897
rc = tdbio_write_record( &lastrec );
899
log_error( "upd_hashtable: update htbl failed: %s\n",
901
return rc; /* ready */
904
log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n",
905
table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
907
return GPG_ERR_TRUSTDB;
916
* Drop an entry from a hashtable
917
* table gives the start of the table, key and keylen is the key,
920
drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
931
hashrec += msb / ITEMS_PER_HTBL_RECORD;
932
rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
934
log_error ("drop_from_hashtable `%s': read failed: %s\n",
935
db_name, gpg_strerror (rc) );
939
item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
940
if( !item ) /* not found - forget about it */
943
if( item == recnum ) { /* tables points direct to the record */
944
rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
945
rc = tdbio_write_record( &rec );
947
log_error ("drop_from_hashtable `%s': write htbl failed: %s\n",
948
db_name, gpg_strerror (rc) );
952
rc = tdbio_read_record( item, &rec, 0 );
954
log_error( "drop_from_hashtable: read item failed: %s\n",
959
if( rec.rectype == RECTYPE_HTBL ) {
962
if( level >= keylen ) {
963
log_error( "hashtable has invalid indirections.\n");
964
return GPG_ERR_TRUSTDB;
969
if( rec.rectype == RECTYPE_HLST ) {
971
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
972
if( rec.r.hlst.rnum[i] == recnum ) {
973
rec.r.hlst.rnum[i] = 0; /* drop */
974
rc = tdbio_write_record( &rec );
976
log_error ("drop_from_hashtable `%s': "
977
"write htbl failed: %s\n",
978
db_name, gpg_strerror (rc) );
982
if( rec.r.hlst.next ) {
983
rc = tdbio_read_record( rec.r.hlst.next,
986
log_error( "drop_from_hashtable: read hlst failed: %s\n",
992
return 0; /* key not in table */
996
log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n",
997
table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
998
return GPG_ERR_TRUSTDB;
1004
* Lookup a record via the hashtable tablewith key/keylen and return the
1005
* result in rec. cmp() should return if the record is the desired one.
1006
* Returns -1 if not found, 0 if found or another errocode
1009
lookup_hashtable( ulong table, const byte *key, size_t keylen,
1010
int (*cmpfnc)(void*, const TRUSTREC *), void *cmpdata,
1014
ulong hashrec, item;
1021
hashrec += msb / ITEMS_PER_HTBL_RECORD;
1022
rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL );
1024
log_error ("lookup_hashtable in `%s' failed: %s\n",
1025
db_name, gpg_strerror (rc) );
1029
item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
1031
return -1; /* not found */
1033
rc = tdbio_read_record( item, rec, 0 );
1035
log_error ("hashtable `%s' read failed: %s\n",
1036
db_name, gpg_strerror (rc) );
1039
if( rec->rectype == RECTYPE_HTBL ) {
1042
if( level >= keylen ) {
1043
log_error ("hashtable `%s' has invalid indirections\n", db_name);
1044
return GPG_ERR_TRUSTDB;
1048
else if( rec->rectype == RECTYPE_HLST ) {
1052
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
1053
if( rec->r.hlst.rnum[i] ) {
1056
rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 );
1058
log_error( "lookup_hashtable: read item failed: %s\n",
1059
gpg_strerror (rc) );
1062
if( (*cmpfnc)( cmpdata, &tmp ) ) {
1068
if( rec->r.hlst.next ) {
1069
rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST );
1071
log_error( "lookup_hashtable: read hlst failed: %s\n",
1072
gpg_strerror (rc) );
1077
return -1; /* not found */
1082
if( (*cmpfnc)( cmpdata, rec ) )
1083
return 0; /* really found */
1085
return -1; /* no: not found */
1090
* Update the trust hashtbl or create the table if it does not exist
1093
update_trusthashtbl( TRUSTREC *tr )
1095
return upd_hashtable( get_trusthashrec(),
1096
tr->r.trust.fingerprint, 20, tr->recnum );
1102
tdbio_dump_record( TRUSTREC *rec, FILE *fp )
1105
ulong rnum = rec->recnum;
1107
fprintf(fp, "rec %5lu, ", rnum );
1109
switch( rec->rectype ) {
1110
case 0: fprintf(fp, "blank\n");
1112
case RECTYPE_VER: fprintf(fp,
1113
"version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d nc=%lu (%s)\n",
1114
rec->r.ver.trusthashtbl,
1115
rec->r.ver.firstfree,
1116
rec->r.ver.marginals,
1117
rec->r.ver.completes,
1118
rec->r.ver.cert_depth,
1119
rec->r.ver.trust_model,
1120
rec->r.ver.nextcheck,
1121
strtimestamp(rec->r.ver.nextcheck)
1124
case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next );
1127
fprintf(fp, "htbl,");
1128
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ )
1129
fprintf(fp, " %lu", rec->r.htbl.item[i] );
1133
fprintf(fp, "hlst, next=%lu,", rec->r.hlst.next );
1134
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ )
1135
fprintf(fp, " %lu", rec->r.hlst.rnum[i] );
1139
fprintf(fp, "trust ");
1140
for(i=0; i < 20; i++ )
1141
fprintf(fp, "%02X", rec->r.trust.fingerprint[i] );
1142
fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust,
1143
rec->r.trust.depth, rec->r.trust.validlist);
1146
fprintf(fp, "valid ");
1147
for(i=0; i < 20; i++ )
1148
fprintf(fp, "%02X", rec->r.valid.namehash[i] );
1149
fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity,
1153
fprintf(fp, "unknown type %d\n", rec->rectype );
1159
* read the record with number recnum
1160
* returns: -1 on error, 0 on success
1163
tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
1165
byte readbuf[TRUST_RECORD_LEN];
1166
const byte *buf, *p;
1172
buf = get_record_from_cache( recnum );
1174
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
1175
rc = gpg_error_from_errno (errno);
1176
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
1179
n = read( db_fd, readbuf, TRUST_RECORD_LEN);
1181
return -1; /* eof */
1183
else if( n != TRUST_RECORD_LEN ) {
1184
rc = gpg_error_from_errno (errno);
1185
log_error(_("trustdb: read failed (n=%d): %s\n"), n,
1191
rec->recnum = recnum;
1194
rec->rectype = *p++;
1195
if( expected && rec->rectype != expected ) {
1196
log_error("%lu: read expected rec type %d, got %d\n",
1197
recnum, expected, rec->rectype );
1198
return GPG_ERR_TRUSTDB;
1200
p++; /* skip reserved byte */
1201
switch( rec->rectype ) {
1202
case 0: /* unused (free) record */
1204
case RECTYPE_VER: /* version record */
1205
if( memcmp(buf+1, "gpg", 3 ) ) {
1206
log_error( _("%s: not a trustdb file\n"), db_name );
1207
rc = GPG_ERR_TRUSTDB;
1209
p += 2; /* skip "gpg" */
1210
rec->r.ver.version = *p++;
1211
rec->r.ver.marginals = *p++;
1212
rec->r.ver.completes = *p++;
1213
rec->r.ver.cert_depth = *p++;
1214
rec->r.ver.trust_model = *p++;
1216
rec->r.ver.created = buftoulong(p); p += 4;
1217
rec->r.ver.nextcheck = buftoulong(p); p += 4;
1220
rec->r.ver.firstfree =buftoulong(p); p += 4;
1222
rec->r.ver.trusthashtbl =buftoulong(p); p += 4;
1224
log_error( _("%s: version record with recnum %lu\n"), db_name,
1226
rc = GPG_ERR_TRUSTDB;
1228
else if( rec->r.ver.version != 3 ) {
1229
log_error( _("%s: invalid file version %d\n"), db_name,
1230
rec->r.ver.version );
1231
rc = GPG_ERR_TRUSTDB;
1235
rec->r.free.next = buftoulong(p); p += 4;
1238
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
1239
rec->r.htbl.item[i] = buftoulong(p); p += 4;
1243
rec->r.hlst.next = buftoulong(p); p += 4;
1244
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
1245
rec->r.hlst.rnum[i] = buftoulong(p); p += 4;
1249
memcpy( rec->r.trust.fingerprint, p, 20); p+=20;
1250
rec->r.trust.ownertrust = *p++;
1251
rec->r.trust.depth = *p++;
1252
rec->r.trust.min_ownertrust = *p++;
1254
rec->r.trust.validlist = buftoulong(p); p += 4;
1257
memcpy( rec->r.valid.namehash, p, 20); p+=20;
1258
rec->r.valid.validity = *p++;
1259
rec->r.valid.next = buftoulong(p); p += 4;
1260
rec->r.valid.full_count = *p++;
1261
rec->r.valid.marginal_count = *p++;
1264
log_error( "%s: invalid record type %d at recnum %lu\n",
1265
db_name, rec->rectype, (ulong)recnum );
1266
rc = GPG_ERR_TRUSTDB;
1274
* Write the record at RECNUM
1277
tdbio_write_record( TRUSTREC *rec )
1279
byte buf[TRUST_RECORD_LEN], *p;
1282
ulong recnum = rec->recnum;
1287
memset(buf, 0, TRUST_RECORD_LEN);
1289
*p++ = rec->rectype; p++;
1290
switch( rec->rectype ) {
1291
case 0: /* unused record */
1293
case RECTYPE_VER: /* version record */
1296
memcpy(p-1, "gpg", 3 ); p += 2;
1297
*p++ = rec->r.ver.version;
1298
*p++ = rec->r.ver.marginals;
1299
*p++ = rec->r.ver.completes;
1300
*p++ = rec->r.ver.cert_depth;
1301
*p++ = rec->r.ver.trust_model;
1303
ulongtobuf(p, rec->r.ver.created); p += 4;
1304
ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
1307
ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
1309
ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
1313
ulongtobuf(p, rec->r.free.next); p += 4;
1318
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
1319
ulongtobuf( p, rec->r.htbl.item[i]); p += 4;
1324
ulongtobuf( p, rec->r.hlst.next); p += 4;
1325
for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
1326
ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4;
1331
memcpy( p, rec->r.trust.fingerprint, 20); p += 20;
1332
*p++ = rec->r.trust.ownertrust;
1333
*p++ = rec->r.trust.depth;
1334
*p++ = rec->r.trust.min_ownertrust;
1336
ulongtobuf( p, rec->r.trust.validlist); p += 4;
1340
memcpy( p, rec->r.valid.namehash, 20); p += 20;
1341
*p++ = rec->r.valid.validity;
1342
ulongtobuf( p, rec->r.valid.next); p += 4;
1343
*p++ = rec->r.valid.full_count;
1344
*p++ = rec->r.valid.marginal_count;
1351
rc = put_record_into_cache( recnum, buf );
1354
else if( rec->rectype == RECTYPE_TRUST )
1355
rc = update_trusthashtbl( rec );
1361
tdbio_delete_record( ulong recnum )
1366
/* Must read the record fist, so we can drop it from the hash tables */
1367
rc = tdbio_read_record( recnum, &rec, 0 );
1370
else if( rec.rectype == RECTYPE_TRUST ) {
1371
rc = drop_from_hashtable( get_trusthashrec(),
1372
rec.r.trust.fingerprint, 20, rec.recnum );
1378
/* now we can chnage it to a free record */
1379
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
1381
log_fatal( _("%s: error reading version record: %s\n"),
1382
db_name, gpg_strerror (rc) );
1384
rec.recnum = recnum;
1385
rec.rectype = RECTYPE_FREE;
1386
rec.r.free.next = vr.r.ver.firstfree;
1387
vr.r.ver.firstfree = recnum;
1388
rc = tdbio_write_record( &rec );
1390
rc = tdbio_write_record( &vr );
1395
* create a new record and return its record number
1405
/* look for unused records */
1406
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
1408
log_fatal( _("%s: error reading version record: %s\n"),
1409
db_name, gpg_strerror (rc) );
1410
if( vr.r.ver.firstfree ) {
1411
recnum = vr.r.ver.firstfree;
1412
rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
1414
log_error( _("%s: error reading free record: %s\n"),
1415
db_name, gpg_strerror (rc) );
1418
/* update dir record */
1419
vr.r.ver.firstfree = rec.r.free.next;
1420
rc = tdbio_write_record( &vr );
1422
log_error( _("%s: error writing dir record: %s\n"),
1423
db_name, gpg_strerror (rc) );
1426
/*zero out the new record */
1427
memset( &rec, 0, sizeof rec );
1428
rec.rectype = 0; /* unused record */
1429
rec.recnum = recnum;
1430
rc = tdbio_write_record( &rec );
1432
log_fatal(_("%s: failed to zero a record: %s\n"),
1433
db_name, gpg_strerror (rc));
1435
else { /* not found, append a new record */
1436
offset = lseek( db_fd, 0, SEEK_END );
1438
log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
1439
recnum = offset / TRUST_RECORD_LEN;
1440
assert(recnum); /* this is will never be the first record */
1441
/* we must write a record, so that the next call to this function
1442
* returns another recnum */
1443
memset( &rec, 0, sizeof rec );
1444
rec.rectype = 0; /* unused record */
1445
rec.recnum = recnum;
1447
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
1448
rc = gpg_error_from_errno (errno);
1449
log_error(_("trustdb rec %lu: lseek failed: %s\n"),
1450
recnum, strerror(errno) );
1453
int n = write( db_fd, &rec, TRUST_RECORD_LEN);
1454
if( n != TRUST_RECORD_LEN ) {
1455
rc = gpg_error_from_errno (errno);
1456
log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
1457
recnum, n, strerror(errno) );
1462
log_fatal(_("%s: failed to append a record: %s\n"),
1463
db_name, gpg_strerror (rc));
1471
cmp_trec_fpr ( void *fpr, const TRUSTREC *rec )
1473
return rec->rectype == RECTYPE_TRUST
1474
&& !memcmp( rec->r.trust.fingerprint, fpr, 20);
1479
tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec )
1483
/* locate the trust record using the hash table */
1484
rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20,
1485
cmp_trec_fpr, (void*)fingerprint, rec );
1490
tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
1492
byte fingerprint[MAX_FINGERPRINT_LEN];
1495
fingerprint_from_pk( pk, fingerprint, &fingerlen );
1496
for (; fingerlen < 20; fingerlen++ )
1497
fingerprint[fingerlen] = 0;
1498
return tdbio_search_trust_byfpr (fingerprint, rec);
1507
"the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") );
1512
* Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
1513
* to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
1514
* only to scan the tdb and insert new the new trust records. The old ones are
1515
* obsolte from now on
1528
int ottable_size, ottable_used;
1534
ottable = xmalloc (ottable_size * sizeof *ottable);
1537
/* We have some restrictions here. We can't use the version record
1538
* and we can't use any of the old hashtables because we dropped the
1539
* code. So we first collect all ownertrusts and then use a second
1540
* pass fo find the associated keys. We have to do this all without using
1541
* the regular record read functions.
1544
/* get all the ownertrusts */
1545
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
1546
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
1547
for (recno=0;;recno++)
1550
n = read (db_fd, oldbuf, 40);
1551
while (n==-1 && errno == EINTR);
1555
log_fatal ("migrate_vfrom_v2: read error or short read\n");
1561
if (ottable_used == ottable_size)
1563
ottable_size += 1000;
1564
ottable = xrealloc (ottable, ottable_size * sizeof *ottable);
1566
ottable[ottable_used].keyrecno = buftoulong (oldbuf+6);
1567
ottable[ottable_used].ot = oldbuf[18];
1568
ottable[ottable_used].okay = 0;
1569
memset (ottable[ottable_used].fpr,0, 20);
1570
if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot)
1573
log_info ("found %d ownertrust records\n", ottable_used);
1575
/* Read again and find the fingerprints */
1576
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
1577
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
1578
for (recno=0;;recno++)
1581
n = read (db_fd, oldbuf, 40);
1582
while (n==-1 && errno == EINTR);
1586
log_fatal ("migrate_from_v2: read error or short read\n");
1592
for (i=0; i < ottable_used; i++)
1594
if (ottable[i].keyrecno == recno)
1596
memcpy (ottable[i].fpr, oldbuf+20, 20);
1597
ottable[i].okay = 1;
1603
/* got everything - create the v3 trustdb */
1604
if (ftruncate (db_fd, 0))
1605
log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) );
1606
if (create_version_record ())
1607
log_fatal ("failed to recreate version record of `%s'\n", db_name);
1609
/* access the hash table, so it is store just after the version record,
1610
* this is not needed put a dump is more pretty */
1611
get_trusthashrec ();
1613
/* And insert the old ownertrust values */
1615
for (i=0; i < ottable_used; i++)
1617
if (!ottable[i].okay)
1620
memset (&rec, 0, sizeof rec);
1621
rec.recnum = tdbio_new_recnum ();
1622
rec.rectype = RECTYPE_TRUST;
1623
memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20);
1624
rec.r.trust.ownertrust = ottable[i].ot;
1625
if (tdbio_write_record (&rec))
1626
log_fatal ("failed to write trust record of `%s'\n", db_name);
1630
revalidation_mark ();
1633
log_fatal ("failed to sync `%s'\n", db_name);
1634
log_info ("migrated %d version 2 ownertrusts\n", count);