1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00
This commit is contained in:
Werner Koch 1998-07-14 17:10:28 +00:00
parent c5b6f97767
commit 0a76a4465b
41 changed files with 708 additions and 456 deletions

View file

@ -147,7 +147,7 @@ create_db( const char *fname )
fp =fopen( fname, "w" );
if( !fp )
log_fatal_f( fname, _("can't create %s: %s\n"), strerror(errno) );
fwrite_8( fp, 1 );
fwrite_8( fp, 2 );
fwrite_8( fp, 'g' );
fwrite_8( fp, 'p' );
fwrite_8( fp, 'g' );
@ -195,55 +195,67 @@ tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
case RECTYPE_VER: fprintf(fp, "version\n");
break;
case RECTYPE_DIR:
fprintf(fp, "dir keyid=%08lX, key=%lu, ctl=%lu, sig=%lu",
(ulong)rec->r.dir.keyid[1],
rec->r.dir.keyrec, rec->r.dir.ctlrec, rec->r.dir.sigrec );
if( rec->r.dir.no_sigs == 1 )
fprintf(fp, "dir %lu, keys=%lu, uids=%lu, cach=%lu, ot=%02x",
rec->r.dir.lid,
rec->r.dir.keylist,
rec->r.dir.uidlist,
rec->r.dir.cacherec,
rec->r.dir.ownertrust );
if( rec->r.dir.sigflag == 1 )
fputs(", (none)", fp );
else if( rec->r.dir.no_sigs == 2 )
else if( rec->r.dir.sigflag == 2 )
fputs(", (invalid)", fp );
else if( rec->r.dir.no_sigs == 3 )
else if( rec->r.dir.sigflag == 3 )
fputs(", (revoked)", fp );
else if( rec->r.dir.no_sigs )
else if( rec->r.dir.sigflag )
fputs(", (??)", fp );
putc('\n', fp);
break;
case RECTYPE_KEY: fprintf(fp,
"key %08lX, own=%lu, ownertrust=%02x, fl=%d\n",
(ulong)rec->r.key.keyid[1],
rec->r.key.owner, rec->r.key.ownertrust,
case RECTYPE_KEY:
fprintf(fp, "key %lu, next=%lu, algo=%d, flen=%d\n",
rec->r.key.lid,
rec->r.key.next,
rec->r.key.pubkey_algo,
rec->r.key.fingerprint_len );
break;
case RECTYPE_UID:
if( !rec->r.uid.subtype )
fprintf(fp,
"uid %02x%02x, owner=%lu, chain=%lu, pref=%lu, otr=%02x\n",
rec->r.uid.namehash[18], rec->r.uid.namehash[19],
rec->r.uid.owner, rec->r.uid.chain, (ulong)rec->r.uid.prefrec,
rec->r.uid.ownertrust );
else
fprintf(fp,
"uid subtype%d, owner=%lu, chain=%lu\n",
rec->r.uid.subtype, rec->r.uid.owner, rec->r.uid.chain);
fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X\n",
rec->r.uid.lid,
rec->r.uid.next,
rec->r.uid.prefrec,
rec->r.uid.siglist,
rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
break;
case RECTYPE_CTL: fprintf(fp, "ctl\n");
case RECTYPE_PREF:
fprintf(fp, "pref %lu, next=%lu\n",
rec->r.uid.lid,
rec->r.uid.next);
break;
case RECTYPE_SIG:
fprintf(fp, "sigrec, owner=%lu, chain=%lu\n",
rec->r.sig.owner, rec->r.sig.chain );
fprintf(fp, "sig %lu, next=%lu\n",
rec->r.sig.lid, rec->r.sig.next );
for(i=any=0; i < SIGS_PER_RECORD; i++ ) {
if( rec->r.sig.sig[i].local_id ) {
if( rec->r.sig.sig[i].lid ) {
if( !any ) {
putc('\t', fp);
any++;
}
fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].local_id,
rec->r.sig.sig[i].flag );
fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].lid,
rec->r.sig.sig[i].flag );
}
}
if( any )
putc('\n', fp);
break;
case RECTYPE_CACH:
fprintf(fp, "cach\n");
break;
case RECTYPE_HTBL:
fprintf(fp, "htbl\n");
break;
case RECTYPE_HTBL:
fprintf(fp, "hlst\n");
break;
default:
fprintf(fp, "%d (unknown)\n", rec->rectype );
break;
@ -287,8 +299,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
case 0: /* unused record */
break;
case RECTYPE_VER: /* version record */
/* g10 was the original name */
if( memcmp(buf+1, "gpg", 3 ) && memcmp(buf+1, "g10", 3 ) ) {
if( memcmp(buf+1, "gpg", 3 ) ) {
log_error_f( db_name, _("not a trustdb file\n") );
rc = G10ERR_TRUSTDB;
}
@ -306,51 +317,60 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
(ulong)recnum );
rc = G10ERR_TRUSTDB;
}
if( rec->r.ver.version != 1 ) {
if( rec->r.ver.version != 2 ) {
log_error_f( db_name, "invalid file version %d\n",
rec->r.ver.version );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_DIR: /*directory record */
rec->r.dir.local_id = buftoulong(p); p += 4;
rec->r.dir.keyid[0] = buftou32(p); p += 4;
rec->r.dir.keyid[1] = buftou32(p); p += 4;
rec->r.dir.keyrec = buftoulong(p); p += 4;
rec->r.dir.ctlrec = buftoulong(p); p += 4;
rec->r.dir.sigrec = buftoulong(p); p += 4;
rec->r.dir.no_sigs = *p++;
if( rec->r.dir.local_id != recnum ) {
log_error_f( db_name, "dir local_id != recnum (%lu,%lu)\n",
(ulong)rec->r.dir.local_id,
(ulong)recnum );
rec->r.dir.lid = buftoulong(p); p += 4;
rec->r.dir.keylist = buftoulong(p); p += 4;
rec->r.dir.uidlist = buftoulong(p); p += 4;
rec->r.dir.cacherec = buftoulong(p); p += 4;
rec->r.dir.ownertrust = *p++;
rec->r.dir.sigflag = *p++;
if( rec->r.dir.lid != recnum ) {
log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
rec->r.dir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_KEY: /* public key record */
rec->r.key.owner = buftoulong(p); p += 4;
rec->r.dir.keyid[0] = buftou32(p); p += 4;
rec->r.dir.keyid[1] = buftou32(p); p += 4;
rec->r.key.lid = buftoulong(p); p += 4;
rec->r.key.next = buftoulong(p); p += 4;
p += 8;
rec->r.key.pubkey_algo = *p++;
rec->r.key.fingerprint_len = *p++;
if( rec->r.key.fingerprint_len < 1 || rec->r.key.fingerprint_len > 20 )
rec->r.key.fingerprint_len = 20;
memcpy( rec->r.key.fingerprint, p, 20); p += 20;
rec->r.key.ownertrust = *p++;
memcpy( rec->r.key.fingerprint, p, 20);
break;
case RECTYPE_CTL: /* control record */
rec->r.ctl.owner = buftoulong(p); p += 4;
memcpy(rec->r.ctl.blockhash, p, 20); p += 20;
rec->r.ctl.trustlevel = *p++;
case RECTYPE_UID: /* user id record */
rec->r.uid.lid = buftoulong(p); p += 4;
rec->r.uid.next = buftoulong(p); p += 4;
rec->r.uid.prefrec = buftoulong(p); p += 4;
rec->r.uid.siglist = buftoulong(p); p += 4;
p += 2;
memcpy( rec->r.uid.namehash, p, 20);
break;
case RECTYPE_PREF: /* preference record */
rec->r.pref.lid = buftoulong(p); p += 4;
rec->r.pref.next = buftoulong(p); p += 4;
break;
case RECTYPE_SIG:
rec->r.sig.owner = buftoulong(p); p += 4;
rec->r.sig.chain = buftoulong(p); p += 4;
rec->r.sig.lid = buftoulong(p); p += 4;
rec->r.sig.next = buftoulong(p); p += 4;
for(i=0; i < SIGS_PER_RECORD; i++ ) {
rec->r.sig.sig[i].local_id = buftoulong(p); p += 4;
rec->r.sig.sig[i].lid = buftoulong(p); p += 4;
rec->r.sig.sig[i].flag = *p++;
}
break;
case RECTYPE_CACH: /* cache record (FIXME)*/
rec->r.cache.lid = buftoulong(p); p += 4;
memcpy(rec->r.cache.blockhash, p, 20); p += 20;
rec->r.cache.trustlevel = *p++;
break;
default:
log_error_f( db_name, "invalid record type %d at recnum %lu\n",
rec->rectype, (ulong)recnum );
@ -385,40 +405,53 @@ tdbio_write_record( ulong recnum, TRUSTREC *rec )
break;
case RECTYPE_DIR: /*directory record */
ulongtobuf(p, rec->r.dir.local_id); p += 4;
u32tobuf(p, rec->r.key.keyid[0]); p += 4;
u32tobuf(p, rec->r.key.keyid[1]); p += 4;
ulongtobuf(p, rec->r.dir.keyrec); p += 4;
ulongtobuf(p, rec->r.dir.ctlrec); p += 4;
ulongtobuf(p, rec->r.dir.sigrec); p += 4;
*p++ = rec->r.dir.no_sigs;
assert( rec->r.dir.local_id == recnum );
ulongtobuf(p, rec->r.dir.lid); p += 4;
ulongtobuf(p, rec->r.dir.keylist); p += 4;
ulongtobuf(p, rec->r.dir.uidlist); p += 4;
ulongtobuf(p, rec->r.dir.cacherec); p += 4;
*p++ = rec->r.dir.ownertrust;
*p++ = rec->r.dir.sigflag;
assert( rec->r.dir.lid == recnum );
break;
case RECTYPE_KEY:
ulongtobuf(p, rec->r.key.owner); p += 4;
u32tobuf(p, rec->r.key.keyid[0]); p += 4;
u32tobuf(p, rec->r.key.keyid[1]); p += 4;
ulongtobuf(p, rec->r.key.lid); p += 4;
ulongtobuf(p, rec->r.key.next); p += 4;
p += 8;
*p++ = rec->r.key.pubkey_algo;
*p++ = rec->r.key.fingerprint_len;
memcpy( p, rec->r.key.fingerprint, 20); p += 20;
*p++ = rec->r.key.ownertrust;
break;
case RECTYPE_CTL: /* control record */
ulongtobuf(p, rec->r.ctl.owner); p += 4;
memcpy(p, rec->r.ctl.blockhash, 20); p += 20;
*p++ = rec->r.ctl.trustlevel;
case RECTYPE_UID: /* user id record */
ulongtobuf(p, rec->r.uid.lid); p += 4;
ulongtobuf(p, rec->r.uid.next); p += 4;
ulongtobuf(p, rec->r.uid.prefrec); p += 4;
ulongtobuf(p, rec->r.uid.siglist); p += 4;
p += 2;
memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
break;
case RECTYPE_PREF:
ulongtobuf(p, rec->r.pref.lid); p += 4;
ulongtobuf(p, rec->r.pref.next); p += 4;
break;
case RECTYPE_SIG:
ulongtobuf(p, rec->r.sig.owner); p += 4;
ulongtobuf(p, rec->r.sig.chain); p += 4;
ulongtobuf(p, rec->r.sig.lid); p += 4;
ulongtobuf(p, rec->r.sig.next); p += 4;
for(i=0; i < SIGS_PER_RECORD; i++ ) {
ulongtobuf(p, rec->r.sig.sig[i].local_id); p += 4;
ulongtobuf(p, rec->r.sig.sig[i].lid); p += 4;
*p++ = rec->r.sig.sig[i].flag;
}
break;
case RECTYPE_CACH: /* FIXME*/
ulongtobuf(p, rec->r.cache.lid); p += 4;
memcpy(p, rec->r.cache.blockhash, 20); p += 20;
*p++ = rec->r.cache.trustlevel;
break;
default:
BUG();
}
@ -475,7 +508,7 @@ tdbio_new_recnum()
* Note: To increase performance, we could use a index search here.
*/
int
tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec )
{
ulong recnum;
u32 keyid[2];
@ -484,30 +517,26 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
int rc;
keyid_from_pk( pk, keyid );
fingerprint = fingerprint_from_pk( pk, &fingerlen );
fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen );
assert( fingerlen == 20 || fingerlen == 16 );
for(recnum=1; !(rc=tdbio_read_record( recnum, rec, 0)); recnum++ ) {
if( rec->rectype != RECTYPE_DIR )
if( rec->rectype != RECTYPE_KEY )
continue;
if( rec->r.dir.keyid[0] == keyid[0]
&& rec->r.dir.keyid[1] == keyid[1]){
TRUSTREC keyrec;
if( tdbio_read_record( rec->r.dir.keyrec, &keyrec, RECTYPE_KEY ) ) {
log_error("%lu: ooops: invalid key record\n", recnum );
if( rec->r.key.pubkey_algo == pk->pubkey_algo
&& !memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) {
/* found: read the dir record for this key */
rc = tdbio_read_record( rec->r.key.lid, rec, RECTYPE_DIR);
if( rc )
break;
}
if( keyrec.r.key.pubkey_algo == pk->pubkey_algo
&& !memcmp(keyrec.r.key.fingerprint, fingerprint, fingerlen) ){
if( pk->local_id && pk->local_id != recnum )
log_error_f(db_name,
"found record, but local_id from memory does "
"not match recnum (%lu,%lu)\n",
(ulong)pk->local_id, (ulong)recnum );
pk->local_id = recnum;
return 0;
}
if( pk->local_id && pk->local_id != recnum )
log_error_f(db_name,
"found record, but LID from memory does "
"not match recnum (%lu,%lu)\n",
pk->local_id, recnum );
pk->local_id = recnum;
return 0;
}
}
if( rc != -1 )
@ -516,3 +545,22 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
}
int
tdbio_update_sigflag( ulong lid, int sigflag )
{
TRUSTREC rec;
if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
log_error("update_sigflag: read failed\n");
return G10ERR_TRUSTDB;
}
rec.r.dir.sigflag = sigflag;
if( tdbio_write_record( lid, &rec ) ) {
log_error("update_sigflag: write failed\n");
return G10ERR_TRUSTDB;
}
return 0;
}