1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-02 16:43:03 +01:00

Revamped the trustDB

This commit is contained in:
Werner Koch 2001-09-24 16:03:14 +00:00
parent abdd248af9
commit a3af543617
24 changed files with 1682 additions and 3756 deletions

11
TODO
View File

@ -17,9 +17,6 @@
* Check that no secret temporary results are stored in the result parameter * Check that no secret temporary results are stored in the result parameter
of the mpi functions. We have already done this for mpi-mul.c of the mpi functions. We have already done this for mpi-mul.c
* check whether we can remove all the expire stuff in trustdb because this
is now done in getkey.
* We need another special packet at the end of a clearsign message to mark * We need another special packet at the end of a clearsign message to mark
it's end and allow for multiple signature for one message. And it's end and allow for multiple signature for one message. And
add a real grammar to the code in mainproc.c add a real grammar to the code in mainproc.c
@ -35,16 +32,8 @@
* add some minor things vor VMS. * add some minor things vor VMS.
* Don't get the ultimately trusted keys from the secring but store
it permanently in the trustdb. This way we don't need a secring at all.
[ currently solved by re-introducing --trusted-key ] Eventually we
will have commands --{add,remove}-trusted-key which keeps them in
special trustdb records.
* Use DSA keys with the test suite (partly done) * Use DSA keys with the test suite (partly done)
* g10/trustdb.c (make_sig_records): fix the fixme.
* Fix the bug in the mips assembler code * Fix the bug in the mips assembler code
* Add a way to show the fingerprint of an key signator's keys * Add a way to show the fingerprint of an key signator's keys

View File

@ -1,3 +1,7 @@
2001-09-24 Werner Koch <wk@gnupg.org>
* gpg.sgml: Described --{update,check}-trustdb.
2001-09-03 Werner Koch <wk@gnupg.org> 2001-09-03 Werner Koch <wk@gnupg.org>
* gpg.sgml, gpgv.sgml: Removed GDBM stuff. * gpg.sgml, gpgv.sgml: Removed GDBM stuff.

View File

@ -469,7 +469,7 @@ the DB is always of type 1 and this is the only record of this type.
1 u32 record number of shadow directory hash table 1 u32 record number of shadow directory hash table
It does not make sense to combine this table with the key table It does not make sense to combine this table with the key table
because the keyid is not in every case a part of the fingerprint. because the keyid is not in every case a part of the fingerprint.
4 bytes reserved for version extension record 1 u32 record number of the trusthashtbale
Record type 2: (directory record) Record type 2: (directory record)

View File

@ -505,7 +505,7 @@ not be expected to successfully import such a key.
<listitem><para> <listitem><para>
Import/merge keys. This adds the given keys to the Import/merge keys. This adds the given keys to the
keyring. keyring.
The fast version does not build The fast version does not update
the trustdb; this can be done at any time with the the trustdb; this can be done at any time with the
command --update-trustdb. command --update-trustdb.
</para> </para>
@ -527,10 +527,34 @@ give the name of this keyserver.
<varlistentry> <varlistentry>
<term>--export-ownertrust</term> <term>--recv-keys &ParmKeyIDs;</term>
<listitem><para> <listitem><para>
List the assigned ownertrust values in ASCII format Import the keys with the given key IDs from a HKP
for backup purposes. keyserver. Option --keyserver must be used to
give the name of this keyserver.
</para></listitem></varlistentry>
<varlistentry>
<term>--update-trustdb</term>
<listitem><para>
Do trust DB maintenance. This command goes over all keys and builds
the Web-of-Trust. This is an intercative command because it may has to
ask for the "ownertrust" values of keys. The user has to give an
estimation in how far she trusts the owner of the displayed key to
correctly certify (sign) other keys. It does only ask for that value
if it has not yet been assigned to a key. Using the edit menu, that
value can be changed at any time later.
</para></listitem></varlistentry>
<varlistentry>
<term>--check-trustdb</term>
<listitem><para>
Do trust DB maintenance without user interaction. Form time to time
the trust database must be updated so that expired keys and resulting
changes in the Web-of_trust can be tracked. GnuPG tries to figure
when this is required and then does it implicitly; this command can be
used to force such a check. The processing is identically to that of
--update-trustdb but it skips keys with a not yet defined "ownertrust".
</para></listitem></varlistentry> </para></listitem></varlistentry>
@ -1164,6 +1188,14 @@ However, due to the fact that the signature creation needs manual
interaction, this performance penalty does not matter in most settings. interaction, this performance penalty does not matter in most settings.
</para></listitem></varlistentry> </para></listitem></varlistentry>
<term>--no-auto-check-trustdb</term>
<listitem><para>
If GnuPG feels that its information about the Web-of-Trust has to be
updated, it automatically runs the --check-trustdb command
internally. As this is a time consuming process, this option allow to
disable the automatic invocation.
</para></listitem></varlistentry>
<varlistentry> <varlistentry>
<term>--throw-keyid</term> <term>--throw-keyid</term>
<listitem><para> <listitem><para>

View File

@ -1,4 +1,29 @@
2001-09-20 Werner Koch <wk@gnupg.org> 2001-09-24 Werner Koch <wk@gnupg.org>
* g10.c, options.h: New option --no-auto-check-trustdb.
* keygen.c (do_generate_keypair): Set newly created keys to
ultimately trusted.
* tdbio.h, tdbio.c: Removed all support for records DIR, KEY, UID,
PREF, SIG, SDIR and CACH. Changed migration function to work
direct on the file.
(tdbio_read_nextcheck): New.
(tdbio_write_nextcheck): New.
2001-09-21 Werner Koch <wk@gnupg.org>
Revamped the entire key validation system.
* trustdb.c: Complete rewrite. No more validation on demand,
removed some functions, adjusted to all callers to use the new
and much simpler interface. Does not use the LID anymore.
* tdbio.c, tdbio.h: Add new record types trust and valid. Wrote a
migration function to convert to the new trustdb layout.
* getkey.c (classify_user_id2): Do not allow the use of the "#"
prefix.
* keydb.h: Removed the TDBIDX mode add a skipfnc to the
descriptor.
* keyring.c (keyring_search): Implemented skipfnc.
* passphrase.c (agent_open): Add missing bracket. Include windows.h. * passphrase.c (agent_open): Add missing bracket. Include windows.h.

View File

@ -224,6 +224,7 @@ enum cmd_and_opt_values { aNull = 0,
oFixedListMode, oFixedListMode,
oNoSigCache, oNoSigCache,
oNoSigCreateCheck, oNoSigCreateCheck,
oNoAutoCheckTrustDB,
oPreservePermissions, oPreservePermissions,
oPreferenceList, oPreferenceList,
oEmu3DESS2KBug, /* will be removed in 1.1 */ oEmu3DESS2KBug, /* will be removed in 1.1 */
@ -276,7 +277,7 @@ static ARGPARSE_OPTS opts[] = {
{ aUpdateTrustDB, { aUpdateTrustDB,
"update-trustdb",0 , N_("update the trust database")}, "update-trustdb",0 , N_("update the trust database")},
{ aCheckTrustDB, { aCheckTrustDB,
"check-trustdb",0 , N_("|[NAMES]|check the trust database")}, "check-trustdb",0 , N_("unattended trust database update")},
{ aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")}, { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
{ aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") }, { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
{ aDeArmor, "dearmour", 256, "@" }, { aDeArmor, "dearmour", 256, "@" },
@ -433,6 +434,7 @@ static ARGPARSE_OPTS opts[] = {
{ oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" }, { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
{ oNoSigCache, "no-sig-cache", 0, "@" }, { oNoSigCache, "no-sig-cache", 0, "@" },
{ oNoSigCreateCheck, "no-sig-create-check", 0, "@" }, { oNoSigCreateCheck, "no-sig-create-check", 0, "@" },
{ oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
{ oMergeOnly, "merge-only", 0, "@" }, { oMergeOnly, "merge-only", 0, "@" },
{ oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" }, { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
{ oTryAllSecrets, "try-all-secrets", 0, "@" }, { oTryAllSecrets, "try-all-secrets", 0, "@" },
@ -1083,6 +1085,7 @@ main( int argc, char **argv )
iobuf_enable_special_filenames (1); iobuf_enable_special_filenames (1);
break; break;
case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
case oPreservePermissions: opt.preserve_permissions=1; break; case oPreservePermissions: opt.preserve_permissions=1; break;
case oPreferenceList: preference_list = pargs.r.ret_str; break; case oPreferenceList: preference_list = pargs.r.ret_str; break;
default : pargs.err = configfp? 1:2; break; default : pargs.err = configfp? 1:2; break;
@ -1648,15 +1651,8 @@ main( int argc, char **argv )
break; break;
case aCheckTrustDB: case aCheckTrustDB:
if( !argc ) /* Old versions allowed for arguments - ignore them */
check_trustdb(NULL); check_trustdb();
else {
for( ; argc; argc--, argv++ ) {
username = make_username( *argv );
check_trustdb( username );
m_free(username);
}
}
break; break;
case aFixTrustDB: case aFixTrustDB:

View File

@ -528,6 +528,7 @@ hextobyte( const byte *s )
/**************** /****************
* Return the type of the user id: * Return the type of the user id:
* *
* Please use the constants KEYDB_SERCH_MODE_xxx
* 0 = Invalid user ID * 0 = Invalid user ID
* 1 = exact match * 1 = exact match
* 2 = match a substring * 2 = match a substring
@ -625,11 +626,7 @@ classify_user_id2( const char *name,
break; break;
case '#': /* local user id */ case '#': /* local user id */
mode = KEYDB_SEARCH_MODE_TDBIDX; return 0; /* This is now obsolete and van't not be used anymore*/
s++;
if (keyid_from_lid(strtoul(s, NULL, 10), desc->u.kid))
desc->u.kid[0] = desc->u.kid[1] = 0;
break;
case ':': /*Unified fingerprint */ case ':': /*Unified fingerprint */
{ {
@ -955,37 +952,6 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
} }
/****************
* Search for a key with the given lid and return the entire keyblock
*/
int
get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid )
{
int rc;
struct getkey_ctx_s ctx;
u32 kid[2];
if( keyid_from_lid( lid, kid ) )
kid[0] = kid[1] = 0;
memset( &ctx, 0, sizeof ctx );
ctx.exact = 1;
ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (0);
ctx.nitems = 1;
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
ctx.items[0].u.kid[0] = kid[0];
ctx.items[0].u.kid[1] = kid[1];
rc = lookup( &ctx, ret_keyblock, 0 );
get_pubkey_end( &ctx );
return rc;
}
/**************** /****************
* Get a secret key by name and store it into sk * Get a secret key by name and store it into sk
* If NAME is NULL use the default key * If NAME is NULL use the default key

View File

@ -229,21 +229,14 @@ check_signatures_trust( PKT_signature *sig )
* instead * instead
*/ */
int int
keyid_from_lid( ulong lid, u32 *keyid ) get_validity_info (PKT_public_key *pk, const byte *namehash )
{
return G10ERR_TRUSTDB;
}
/* Stub: */
int
query_trust_info( PKT_public_key *pk, const byte *namehash )
{ {
return '?'; return '?';
} }
/* Stub: */ /* Stub: */
int int
get_ownertrust_info( ulong lid ) get_ownertrust_info (PKT_public_key *pk)
{ {
return '?'; return '?';
} }

View File

@ -203,11 +203,18 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"self-signatures fill be advanced by one second.\n" "self-signatures fill be advanced by one second.\n"
)}, )},
{ "keyedit.trust.set_ultimate.okay", N_(
"To build the Web-of-Trust, GnuPG needs to know which keys are\n"
"ultimately trusted - those are usually the keys for which you have\n"
"access to the secret key. Answer \"yes\" to set this key to\n"
"ultimately trusted; if you choose not to do so, you will then be\n"
"taken to the regular ownertrust menu.\n"
)},
{ "passphrase.enter", N_( { "passphrase.enter", N_(
"" ""
"Please enter the passhrase; this is a secret sentence \n" "Please enter the passhrase; this is a secret sentence \n"
" Blurb, blurb,.... "
)}, )},

View File

@ -158,8 +158,7 @@ import_keys( char **fnames, int nnames, int fast, void *stats_handle )
import_print_stats (stats); import_print_stats (stats);
import_release_stats_handle (stats); import_release_stats_handle (stats);
} }
if( !fast )
sync_trustdb();
} }
int int
@ -177,8 +176,7 @@ import_keys_stream( IOBUF inp, int fast, void *stats_handle )
import_print_stats (stats); import_print_stats (stats);
import_release_stats_handle (stats); import_release_stats_handle (stats);
} }
if( !fast )
sync_trustdb();
return rc; return rc;
} }
@ -591,21 +589,8 @@ import_one( const char *fname, KBNODE keyblock, int fast,
} }
keydb_release (hd); hd = NULL; keydb_release (hd); hd = NULL;
} }
if( !rc && !fast ) { if (!rc)
rc = query_trust_record( new_key? pk : pk_orig ); revalidation_mark ();
if( rc && rc != -1 )
log_error("trustdb error: %s\n", g10_errstr(rc) );
else if( rc == -1 ) { /* not found trustdb */
rc = insert_trust_record( new_key? keyblock : keyblock_orig );
if( rc )
log_error("key %08lX: trustdb insert failed: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
}
else if( mod_key )
rc = update_trust_record( keyblock_orig, 1, NULL );
else
rc = clear_trust_checked_flag( new_key? pk : pk_orig );
}
leave: leave:
release_kbnode( keyblock_orig ); release_kbnode( keyblock_orig );
@ -793,15 +778,7 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
log_info( _("key %08lX: revocation certificate imported\n"), log_info( _("key %08lX: revocation certificate imported\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
stats->n_revoc++; stats->n_revoc++;
if( clear_trust_checked_flag( pk ) ) { revalidation_mark ();
/* seems that we have to insert the record first */
rc = insert_trust_record( keyblock );
if( rc )
log_error("key %08lX: trustdb insert failed: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
else
rc = clear_trust_checked_flag( pk );
}
leave: leave:
keydb_release (hd); keydb_release (hd);

View File

@ -120,7 +120,6 @@ typedef enum {
KEYDB_SEARCH_MODE_WORDS, KEYDB_SEARCH_MODE_WORDS,
KEYDB_SEARCH_MODE_SHORT_KID, KEYDB_SEARCH_MODE_SHORT_KID,
KEYDB_SEARCH_MODE_LONG_KID, KEYDB_SEARCH_MODE_LONG_KID,
KEYDB_SEARCH_MODE_TDBIDX,
KEYDB_SEARCH_MODE_FPR16, KEYDB_SEARCH_MODE_FPR16,
KEYDB_SEARCH_MODE_FPR20, KEYDB_SEARCH_MODE_FPR20,
KEYDB_SEARCH_MODE_FPR, KEYDB_SEARCH_MODE_FPR,
@ -130,6 +129,8 @@ typedef enum {
struct keydb_search_desc { struct keydb_search_desc {
KeydbSearchMode mode; KeydbSearchMode mode;
int (*skipfnc)(void *,u32*);
void *skipfncvalue;
union { union {
const char *name; const char *name;
char fpr[MAX_FINGERPRINT_LEN]; char fpr[MAX_FINGERPRINT_LEN];

View File

@ -373,7 +373,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
} }
} /* end loop over signators */ } /* end loop over signators */
if( upd_trust && primary_pk ) { if( upd_trust && primary_pk ) {
rc = clear_trust_checked_flag( primary_pk ); revalidation_mark ();
} }
@ -793,11 +793,6 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
if( !sign_uids( keyblock, locusr, &modified, cmd == cmdLSIGN ) if( !sign_uids( keyblock, locusr, &modified, cmd == cmdLSIGN )
&& sign_mode ) && sign_mode )
goto do_cmd_save; goto do_cmd_save;
/* Actually we should do a update_trust_record() here so that
* the trust gets displayed correctly. however this is not possible
* because we would have to save the keyblock first - something
* we don't want to do without an explicit save command.
*/
break; break;
case cmdDEBUG: case cmdDEBUG:
@ -933,11 +928,22 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
case cmdTRUST: case cmdTRUST:
show_key_with_all_names( keyblock, 0, 0, 1, 0 ); show_key_with_all_names( keyblock, 0, 0, 1, 0 );
tty_printf("\n"); tty_printf("\n");
if( edit_ownertrust( find_kbnode( keyblock, if ( sec_keyblock
PKT_PUBLIC_KEY )->pkt->pkt.public_key->local_id, 1 ) ) && cpr_get_answer_is_yes(
"keyedit.trust.set_ultimate.okay",
_("Do you want to set this key to ultimately trusted? "))) {
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
update_ownertrust (pk,
((get_ownertrust (pk) & ~TRUST_MASK)
| TRUST_ULTIMATE ));
redisplay = 1;
break;
}
if( edit_ownertrust( find_kbnode( keyblock,
PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) )
redisplay = 1; redisplay = 1;
/* we don't need to set modified here, as the trustvalues
* are updated immediately */
break; break;
case cmdPREF: case cmdPREF:
@ -1028,13 +1034,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
/* TODO: we should keep track whether we have changed /* TODO: we should keep track whether we have changed
* something relevant to the trustdb */ * something relevant to the trustdb */
if( !modified && sign_mode ) if( !(!modified && sign_mode) )
rc = 0; /* we can skip at least in this case */ revalidation_mark ();
else
rc = update_trust_record( keyblock, 0, NULL );
if( rc )
log_error(_("update of trustdb failed: %s\n"),
g10_errstr(rc) );
goto leave; goto leave;
case cmdINVCMD: case cmdINVCMD:
@ -1143,8 +1144,9 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
/* do it here, so that debug messages don't clutter the /* do it here, so that debug messages don't clutter the
* output */ * output */
trust = query_trust_info(pk, NULL);
otrust = get_ownertrust_info( pk->local_id ); trust = get_validity_info (pk, NULL);
otrust = get_ownertrust_info (pk);
} }
tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"), tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
@ -1158,7 +1160,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
tty_printf(_(" trust: %c/%c"), otrust, trust ); tty_printf(_(" trust: %c/%c"), otrust, trust );
if( node->pkt->pkttype == PKT_PUBLIC_KEY if( node->pkt->pkttype == PKT_PUBLIC_KEY
&& (get_ownertrust( pk->local_id )&TRUST_FLAG_DISABLED)) { && (get_ownertrust (pk)&TRUST_FLAG_DISABLED)) {
tty_printf("\n*** "); tty_printf("\n*** ");
tty_printf(_("This key has been disabled")); tty_printf(_("This key has been disabled"));
} }
@ -2127,7 +2129,7 @@ menu_revsig( KBNODE keyblock )
} }
if( upd_trust ) if( upd_trust )
clear_trust_checked_flag( primary_pk ); revalidation_mark ();
release_revocation_reason_info( reason ); release_revocation_reason_info( reason );
return changed; return changed;
} }
@ -2192,7 +2194,7 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
/*commit_kbnode( &sec_keyblock );*/ /*commit_kbnode( &sec_keyblock );*/
if( upd_trust ) if( upd_trust )
clear_trust_checked_flag( mainpk ); revalidation_mark ();
release_revocation_reason_info( reason ); release_revocation_reason_info( reason );
return changed; return changed;
@ -2202,20 +2204,17 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
static int static int
enable_disable_key( KBNODE keyblock, int disable ) enable_disable_key( KBNODE keyblock, int disable )
{ {
ulong lid = find_kbnode( keyblock, PKT_PUBLIC_KEY ) PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
->pkt->pkt.public_key->local_id; ->pkt->pkt.public_key;
unsigned int trust, newtrust; unsigned int trust, newtrust;
/* Note: Because the keys have beed displayed, we have trust = newtrust = get_ownertrust (pk);
* ensured that local_id has been set */
trust = newtrust = get_ownertrust( lid );
newtrust &= ~TRUST_FLAG_DISABLED; newtrust &= ~TRUST_FLAG_DISABLED;
if( disable ) if( disable )
newtrust |= TRUST_FLAG_DISABLED; newtrust |= TRUST_FLAG_DISABLED;
if( trust == newtrust ) if( trust == newtrust )
return 0; /* already in that state */ return 0; /* already in that state */
if( !update_ownertrust( lid, newtrust ) ) update_ownertrust(pk, newtrust );
return 1;
return 0; return 0;
} }

View File

@ -32,6 +32,7 @@
#include "ttyio.h" #include "ttyio.h"
#include "options.h" #include "options.h"
#include "keydb.h" #include "keydb.h"
#include "trustdb.h"
#include "status.h" #include "status.h"
#include "i18n.h" #include "i18n.h"
@ -1934,9 +1935,19 @@ do_generate_keypair( struct para_data_s *para,
get_parameter_algo(para, pKEYTYPE) == PUBKEY_ALGO_RSA get_parameter_algo(para, pKEYTYPE) == PUBKEY_ALGO_RSA
&& get_parameter_uint( para, pKEYUSAGE ) && get_parameter_uint( para, pKEYUSAGE )
&& !(get_parameter_uint( para,pKEYUSAGE) & PUBKEY_USAGE_ENC); && !(get_parameter_uint( para,pKEYUSAGE) & PUBKEY_USAGE_ENC);
PKT_public_key *pk = find_kbnode (pub_root,
PKT_PUBLIC_KEY)->pkt->pkt.public_key;
if( !opt.batch ) update_ownertrust (pk,
((get_ownertrust (pk) & ~TRUST_MASK)
| TRUST_ULTIMATE ));
if (!opt.batch) {
tty_printf(_("public and secret key created and signed.\n") ); tty_printf(_("public and secret key created and signed.\n") );
tty_printf(_("key marked as ultimately trusted.\n") );
}
if( !opt.batch if( !opt.batch
&& ( get_parameter_algo( para, pKEYTYPE ) == PUBKEY_ALGO_DSA && ( get_parameter_algo( para, pKEYTYPE ) == PUBKEY_ALGO_DSA
|| no_enc_rsa ) || no_enc_rsa )

View File

@ -433,7 +433,7 @@ list_keyblock_colon( KBNODE keyblock, int secret )
else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
; ;
else { else {
trustletter = query_trust_info( pk, NULL ); trustletter = get_validity_info ( pk, NULL );
if( trustletter == 'u' ) if( trustletter == 'u' )
ulti_hack = 1; ulti_hack = 1;
putchar(trustletter); putchar(trustletter);
@ -449,7 +449,7 @@ list_keyblock_colon( KBNODE keyblock, int secret )
putchar(':'); putchar(':');
if( pk->local_id && !opt.fast_list_mode if( pk->local_id && !opt.fast_list_mode
&& !opt.no_expensive_trust_checks ) && !opt.no_expensive_trust_checks )
putchar( get_ownertrust_info( pk->local_id ) ); putchar( get_ownertrust_info(pk) );
putchar(':'); putchar(':');
} }
@ -490,7 +490,7 @@ list_keyblock_colon( KBNODE keyblock, int secret )
rmd160_hash_buffer( namehash, rmd160_hash_buffer( namehash,
node->pkt->pkt.user_id->name, node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len ); node->pkt->pkt.user_id->len );
trustletter = query_trust_info( pk, namehash ); trustletter = get_validity_info( pk, namehash );
} }
else else
trustletter = 'u'; trustletter = 'u';

View File

@ -678,7 +678,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
int save_mode; int save_mode;
off_t offset, main_offset; off_t offset, main_offset;
size_t n; size_t n;
int need_uid, need_words, need_keyid, need_fpr; int need_uid, need_words, need_keyid, need_fpr, any_skip;
int pk_no, uid_no; int pk_no, uid_no;
int initial_skip; int initial_skip;
PKT_user_id *uid = NULL; PKT_user_id *uid = NULL;
@ -686,7 +686,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
PKT_secret_key *sk = NULL; PKT_secret_key *sk = NULL;
/* figure out what information we need */ /* figure out what information we need */
need_uid = need_words = need_keyid = need_fpr = 0; need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
for (n=0; n < ndesc; n++) { for (n=0; n < ndesc; n++) {
switch (desc[n].mode) { switch (desc[n].mode) {
case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_EXACT:
@ -715,6 +715,10 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
break; break;
default: break; default: break;
} }
if (desc[n].skipfnc) {
any_skip = 1;
need_keyid = 1;
}
} }
rc = prepare_search (hd); rc = prepare_search (hd);
@ -797,9 +801,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
case KEYDB_SEARCH_MODE_NONE: case KEYDB_SEARCH_MODE_NONE:
BUG (); BUG ();
break; break;
case KEYDB_SEARCH_MODE_TDBIDX:
BUG();
break;
case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_EXACT:
case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_SUBSTR:
case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAIL:
@ -831,6 +832,9 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
goto found; goto found;
break; break;
case KEYDB_SEARCH_MODE_FIRST: case KEYDB_SEARCH_MODE_FIRST:
if (pk||sk)
goto found;
break;
case KEYDB_SEARCH_MODE_NEXT: case KEYDB_SEARCH_MODE_NEXT:
if (pk||sk) if (pk||sk)
goto found; goto found;
@ -840,10 +844,19 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
goto found; goto found;
} }
} }
free_packet (&pkt);
continue;
found:
for (n=any_skip?0:ndesc; n < ndesc; n++) {
if (desc[n].skipfnc
&& desc[n].skipfnc (desc[n].skipfncvalue, aki))
break;
}
if (n == ndesc)
goto real_found;
free_packet (&pkt); free_packet (&pkt);
} }
found: real_found:
if( !rc ) { if( !rc ) {
hd->found.offset = main_offset; hd->found.offset = main_offset;
hd->found.kr = hd->current.kr; hd->found.kr = hd->current.kr;

Binary file not shown.

View File

@ -748,7 +748,7 @@ list_node( CTX c, KBNODE node )
if( mainkey ) { if( mainkey ) {
c->local_id = pk->local_id; c->local_id = pk->local_id;
c->trustletter = opt.fast_list_mode? c->trustletter = opt.fast_list_mode?
0 : query_trust_info( pk, NULL ); 0 : get_validity_info( pk, NULL );
} }
printf("%s:", mainkey? "pub":"sub" ); printf("%s:", mainkey? "pub":"sub" );
if( c->trustletter ) if( c->trustletter )
@ -762,8 +762,8 @@ list_node( CTX c, KBNODE node )
if( c->local_id ) if( c->local_id )
printf("%lu", c->local_id ); printf("%lu", c->local_id );
putchar(':'); putchar(':');
if( c->local_id && !opt.fast_list_mode ) if( mainkey && !opt.fast_list_mode )
putchar( get_ownertrust_info( c->local_id ) ); putchar( get_ownertrust_info (pk) );
putchar(':'); putchar(':');
if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) { if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) {
putchar('\n'); any=1; putchar('\n'); any=1;

View File

@ -114,6 +114,7 @@ struct {
int no_expensive_trust_checks; int no_expensive_trust_checks;
int no_sig_cache; int no_sig_cache;
int no_sig_create_check; int no_sig_create_check;
int no_auto_check_trustdb;
int preserve_permissions; int preserve_permissions;
int no_homedir_creation; int no_homedir_creation;
} opt; } opt;

View File

@ -149,8 +149,10 @@ show_revocation_reason( PKT_public_key *pk )
static void static void
show_paths( ulong lid, int only_first ) show_paths (const PKT_public_key *pk, int only_first )
{ {
#warning must change enum_cert_paths to use pk
#if 0
void *context = NULL; void *context = NULL;
unsigned otrust, validity; unsigned otrust, validity;
int last_level, level; int last_level, level;
@ -168,6 +170,7 @@ show_paths( ulong lid, int only_first )
last_level = level; last_level = level;
rc = keyid_from_lid( lid, keyid ); rc = keyid_from_lid( lid, keyid );
if( rc ) { if( rc ) {
log_error("ooops: can't get keyid for lid %lu\n", lid); log_error("ooops: can't get keyid for lid %lu\n", lid);
return; return;
@ -206,6 +209,7 @@ show_paths( ulong lid, int only_first )
free_public_key( pk ); free_public_key( pk );
} }
enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */ enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
#endif
tty_printf("\n"); tty_printf("\n");
} }
@ -213,44 +217,37 @@ show_paths( ulong lid, int only_first )
/**************** /****************
* Returns true if an ownertrust has changed. * mode: 0 = standard
* 1 = Without key info and additional menu option 'm'
* Returns:
* -2 = nothing changed - caller should show some additional info
* -1 = quit operation
* 0 = nothing changed
* 1 = new ownertrust now ion new_trust
*/ */
static int static int
do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help ) do_edit_ownertrust (PKT_public_key *pk, int mode,
unsigned *new_trust, int defer_help )
{ {
char *p; char *p;
int rc;
size_t n; size_t n;
u32 keyid[2]; u32 keyid[2];
PKT_public_key *pk ;
int changed=0; int changed=0;
int quit=0; int quit=0;
int show=0; int show=0;
int did_help=defer_help; int did_help=defer_help;
rc = keyid_from_lid( lid, keyid ); keyid_from_pk (pk, keyid);
if( rc ) {
log_error("ooops: can't get keyid for lid %lu\n", lid);
return 0;
}
pk = m_alloc_clear( sizeof *pk );
rc = get_pubkey( pk, keyid );
if( rc ) {
log_error("key %08lX: public key not found: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
return 0;
}
for(;;) { for(;;) {
/* a string with valid answers */ /* a string with valid answers */
const char *ans = _("sSmMqQ"); const char *ans = _("sSmMqQ");
if( !did_help ) { if( !did_help )
if( !mode ) { {
tty_printf(_("No trust value assigned to %lu:\n" if( !mode )
"%4u%c/%08lX %s \""), lid, {
tty_printf(_("No trust value assigned to:\n"
"%4u%c/%08lX %s \""),
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk( pk ) ); (ulong)keyid[1], datestr_from_pk( pk ) );
p = get_user_id( keyid, &n ); p = get_user_id( keyid, &n );
@ -285,9 +282,11 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help )
did_help = 0; did_help = 0;
else if( *p && p[1] ) else if( *p && p[1] )
; ;
else if( !p[1] && (*p >= '1' && *p <= '4') ) { else if( !p[1] && (*p >= '1' && *p <= '4') )
{
unsigned trust; unsigned trust;
switch( *p ) { switch( *p )
{
case '1': trust = TRUST_UNDEFINED; break; case '1': trust = TRUST_UNDEFINED; break;
case '2': trust = TRUST_NEVER ; break; case '2': trust = TRUST_NEVER ; break;
case '3': trust = TRUST_MARGINAL ; break; case '3': trust = TRUST_MARGINAL ; break;
@ -298,46 +297,52 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help )
changed = 1; changed = 1;
break; break;
} }
else if( *p == ans[0] || *p == ans[1] ) { else if( *p == ans[0] || *p == ans[1] )
tty_printf(_( {
"Certificates leading to an ultimately trusted key:\n")); tty_printf(_("Certificates leading to an ultimately trusted key:\n"));
show = 1; show = 1;
break; break;
} }
else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) { else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) )
{
break ; /* back to the menu */ break ; /* back to the menu */
} }
else if( !mode && (*p == ans[4] || *p == ans[5] ) ) { else if( !mode && (*p == ans[4] || *p == ans[5] ) )
{
quit = 1; quit = 1;
break ; /* back to the menu */ break ; /* back to the menu */
} }
m_free(p); p = NULL; m_free(p); p = NULL;
} }
m_free(p); m_free(p);
m_free(pk);
return show? -2: quit? -1 : changed; return show? -2: quit? -1 : changed;
} }
/*
* Display a menu to change the ownertrust of the key PK (which should
* be a primary key).
* For mode values see do_edit_ownertrust ()
*/
int int
edit_ownertrust( ulong lid, int mode ) edit_ownertrust (PKT_public_key *pk, int mode )
{ {
unsigned int trust; unsigned int trust;
int no_help = 0; int no_help = 0;
for(;;) { for(;;)
switch( do_edit_ownertrust( lid, mode, &trust, no_help ) ) { {
case -1: switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) )
{
case -1: /* quit */
return 0; return 0;
case -2: case -2: /* show info */
show_paths( lid, 1 ); show_paths(pk, 1);
no_help = 1; no_help = 1;
break; break;
case 1: case 1: /* trust value set */
trust &= ~TRUST_FLAG_DISABLED; trust &= ~TRUST_FLAG_DISABLED;
trust |= get_ownertrust( lid ) & TRUST_FLAG_DISABLED; trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED;
if( !update_ownertrust( lid, trust ) ) update_ownertrust (pk, trust );
return 1;
return 0; return 0;
default: default:
return 0; return 0;
@ -346,10 +351,10 @@ edit_ownertrust( ulong lid, int mode )
} }
static int static int
add_ownertrust_cb( ulong lid ) add_ownertrust_cb (PKT_public_key *pk )
{ {
unsigned trust; unsigned int trust;
int rc = do_edit_ownertrust( lid, 0, &trust, 0 ); int rc = do_edit_ownertrust (pk, 0, &trust, 0 );
if( rc == 1 ) if( rc == 1 )
return trust & TRUST_MASK; return trust & TRUST_MASK;
@ -368,13 +373,14 @@ add_ownertrust( PKT_public_key *pk, int *quit, int *trustlevel )
int rc; int rc;
unsigned flags = 0; unsigned flags = 0;
#warning This function does not make sense anymore
*quit = 0; *quit = 0;
*trustlevel = 0; *trustlevel = 0;
tty_printf( tty_printf(
_("Could not find a valid trust path to the key. Let's see whether we\n" _("Could not find a valid trust path to the key. Let's see whether we\n"
"can assign some missing owner trust values.\n\n")); "can assign some missing owner trust values.\n\n"));
rc = check_trust( pk, trustlevel, NULL, add_ownertrust_cb, &flags ); *trustlevel = get_validity ( pk, NULL);
if( !(flags & 1) ) if( !(flags & 1) )
tty_printf(_("No path leading to one of our keys found.\n\n") ); tty_printf(_("No path leading to one of our keys found.\n\n") );
@ -436,17 +442,8 @@ do_we_trust( PKT_public_key *pk, int *trustlevel )
switch( (*trustlevel & TRUST_MASK) ) { switch( (*trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */ case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record_by_pk( pk ); *trustlevel = get_validity (pk, NULL);
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
return 0; /* no */
}
rc = check_trust( pk, trustlevel, NULL, NULL, NULL );
*trustlevel &= ~trustmask; *trustlevel &= ~trustmask;
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) { if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) {
log_debug("do_we_trust: oops at %d\n", __LINE__ ); log_debug("do_we_trust: oops at %d\n", __LINE__ );
return 0; return 0;
@ -587,11 +584,7 @@ check_signatures_trust( PKT_signature *sig )
goto leave; goto leave;
} }
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL ); trustlevel = get_validity (pk, NULL);
if( rc ) {
log_error("check trust failed: %s\n", g10_errstr(rc));
goto leave;
}
retry: retry:
if( (trustlevel & TRUST_FLAG_REVOKED) ) { if( (trustlevel & TRUST_FLAG_REVOKED) ) {
@ -609,16 +602,7 @@ check_signatures_trust( PKT_signature *sig )
switch( (trustlevel & TRUST_MASK) ) { switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */ case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record_by_pk( pk ); trustlevel = get_validity (pk, NULL);
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
goto leave;
}
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
BUG(); BUG();
goto retry; goto retry;
@ -851,13 +835,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else { else {
int trustlevel; int trustlevel;
rc = check_trust( pk, &trustlevel, pk->namehash, trustlevel = get_validity (pk, NULL);
NULL, NULL ); if( (trustlevel & TRUST_FLAG_DISABLED) ) {
if( rc ) {
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
}
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
tty_printf(_("Public key is disabled.\n") ); tty_printf(_("Public key is disabled.\n") );
} }
else if( do_we_trust_pre( pk, trustlevel ) ) { else if( do_we_trust_pre( pk, trustlevel ) ) {
@ -929,17 +908,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
int trustlevel; int trustlevel;
rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL ); trustlevel = get_validity (pk, pk->namehash);
if( rc ) { if( (trustlevel & TRUST_FLAG_DISABLED) ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: error checking key: %s\n"),
remusr->d, g10_errstr(rc) );
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
remusr->d,
strlen (remusr->d),
-1);
}
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
free_public_key(pk); pk = NULL; free_public_key(pk); pk = NULL;
log_info(_("%s: skipped: public key is disabled\n"), log_info(_("%s: skipped: public key is disabled\n"),
remusr->d); remusr->d);

View File

@ -46,22 +46,7 @@
#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \ #define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \
(x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10)) (x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
/****************
* Read a record but die if it does not exist
* fixme: duplicate: remove it
*/
#if 0
static void
read_record( ulong recno, TRUSTREC *rec, int rectype )
{
int rc = tdbio_read_record( recno, rec, rectype );
if( !rc )
return;
log_error(_("trust record %lu, req type %d: read failed: %s\n"),
recno, rectype, g10_errstr(rc) );
tdbio_invalid();
}
#endif
/**************** /****************
* Wirte a record but die on error * Wirte a record but die on error
*/ */
@ -77,256 +62,6 @@ write_record( TRUSTREC *rec )
} }
/****************
* sync the db
*/
static void
do_sync(void)
{
int rc = tdbio_sync();
if( !rc )
return;
log_error(_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
g10_exit(2);
}
#if 0
static int
print_sigflags( FILE *fp, unsigned flags )
{
if( flags & SIGF_CHECKED ) {
fprintf(fp,"%c%c%c",
(flags & SIGF_VALID) ? 'V':'-',
(flags & SIGF_EXPIRED) ? 'E':'-',
(flags & SIGF_REVOKED) ? 'R':'-');
}
else if( flags & SIGF_NOPUBKEY)
fputs("?--", fp);
else
fputs("---", fp);
return 3;
}
#endif
/****************
* Walk through the signatures of a public key.
* The caller must provide a context structure, with all fields set
* to zero, but the local_id field set to the requested key;
* This function does not change this field. On return the context
* is filled with the local-id of the signature and the signature flag.
* No fields should be changed (clearing all fields and setting
* pubkeyid is okay to continue with an other pubkey)
* Returns: 0 - okay, -1 for eof (no more sigs) or any other errorcode
* FIXME: Do we really need this large and complicated function?
*/
#if 0
static int
walk_sigrecs( SIGREC_CONTEXT *c )
{
TRUSTREC *r;
ulong rnum;
if( c->ctl.eof )
return -1;
r = &c->ctl.rec;
if( !c->ctl.init_done ) {
c->ctl.init_done = 1;
read_record( c->lid, r, 0 );
if( r->rectype != RECTYPE_DIR ) {
c->ctl.eof = 1;
return -1; /* return eof */
}
c->ctl.nextuid = r->r.dir.uidlist;
/* force a read */
c->ctl.index = SIGS_PER_RECORD;
r->r.sig.next = 0;
}
/* need a loop to skip over deleted sigs */
do {
if( c->ctl.index >= SIGS_PER_RECORD ) { /* read the record */
rnum = r->r.sig.next;
if( !rnum && c->ctl.nextuid ) { /* read next uid record */
read_record( c->ctl.nextuid, r, RECTYPE_UID );
c->ctl.nextuid = r->r.uid.next;
rnum = r->r.uid.siglist;
}
if( !rnum ) {
c->ctl.eof = 1;
return -1; /* return eof */
}
read_record( rnum, r, RECTYPE_SIG );
if( r->r.sig.lid != c->lid ) {
log_error(_("chained sigrec %lu has a wrong owner\n"), rnum );
c->ctl.eof = 1;
tdbio_invalid();
}
c->ctl.index = 0;
}
} while( !r->r.sig.sig[c->ctl.index++].lid );
c->sig_lid = r->r.sig.sig[c->ctl.index-1].lid;
c->sig_flag = r->r.sig.sig[c->ctl.index-1].flag;
return 0;
}
#endif
#if 0
static int
do_list_sigs( ulong root, ulong pk_lid, int depth,
LOCAL_ID_TABLE lids, unsigned *lineno )
{
SIGREC_CONTEXT sx;
int rc;
u32 keyid[2];
memset( &sx, 0, sizeof sx );
sx.lid = pk_lid;
for(;;) {
rc = walk_sigrecs( &sx ); /* should we replace it and use */
if( rc )
break;
rc = keyid_from_lid( sx.sig_lid, keyid );
if( rc ) {
printf("%6u: %*s????????.%lu:", *lineno, depth*4, "", sx.sig_lid );
print_sigflags( stdout, sx.sig_flag );
putchar('\n');
++*lineno;
}
else {
printf("%6u: %*s%08lX.%lu:", *lineno, depth*4, "",
(ulong)keyid[1], sx.sig_lid );
print_sigflags( stdout, sx.sig_flag );
putchar(' ');
/* check whether we already checked this pk_lid */
if( !qry_lid_table_flag( ultikey_table, sx.sig_lid, NULL ) ) {
print_user_id("[ultimately trusted]", keyid);
++*lineno;
}
else if( sx.sig_lid == pk_lid ) {
printf("[self-signature]\n");
++*lineno;
}
else if( sx.sig_lid == root ) {
printf("[closed]\n");
++*lineno;
}
else if( ins_lid_table_item( lids, sx.sig_lid, *lineno ) ) {
unsigned refline;
qry_lid_table_flag( lids, sx.sig_lid, &refline );
printf("[see line %u]\n", refline);
++*lineno;
}
else if( depth+1 >= MAX_LIST_SIGS_DEPTH ) {
print_user_id( "[too deeply nested]", keyid );
++*lineno;
}
else {
print_user_id( "", keyid );
++*lineno;
rc = do_list_sigs( root, sx.sig_lid, depth+1, lids, lineno );
if( rc )
break;
}
}
}
return rc==-1? 0 : rc;
}
#endif
/****************
* List all signatures of a public key
*/
static int
list_sigs( ulong pubkey_id )
{
int rc=0;
#if 0
u32 keyid[2];
LOCAL_ID_TABLE lids;
unsigned lineno = 1;
rc = keyid_from_lid( pubkey_id, keyid );
if( rc )
return rc;
printf("Signatures of %08lX.%lu ", (ulong)keyid[1], pubkey_id );
print_user_id("", keyid);
printf("----------------------\n");
lids = new_lid_table();
rc = do_list_sigs( pubkey_id, pubkey_id, 0, lids, &lineno );
putchar('\n');
release_lid_table(lids);
#endif
return rc;
}
/****************
* List all records of a public key
*/
static int
list_records( ulong lid )
{
int rc;
TRUSTREC dr, ur, rec;
ulong recno;
rc = tdbio_read_record( lid, &dr, RECTYPE_DIR );
if( rc ) {
log_error(_("lid %lu: read dir record failed: %s\n"),
lid, g10_errstr(rc));
return rc;
}
tdbio_dump_record( &dr, stdout );
for( recno=dr.r.dir.keylist; recno; recno = rec.r.key.next ) {
rc = tdbio_read_record( recno, &rec, 0 );
if( rc ) {
log_error(_("lid %lu: read key record failed: %s\n"),
lid, g10_errstr(rc));
return rc;
}
tdbio_dump_record( &rec, stdout );
}
for( recno=dr.r.dir.uidlist; recno; recno = ur.r.uid.next ) {
rc = tdbio_read_record( recno, &ur, RECTYPE_UID );
if( rc ) {
log_error(_("lid %lu: read uid record failed: %s\n"),
lid, g10_errstr(rc));
return rc;
}
tdbio_dump_record( &ur, stdout );
/* preference records */
for(recno=ur.r.uid.prefrec; recno; recno = rec.r.pref.next ) {
rc = tdbio_read_record( recno, &rec, RECTYPE_PREF );
if( rc ) {
log_error(_("lid %lu: read pref record failed: %s\n"),
lid, g10_errstr(rc));
return rc;
}
tdbio_dump_record( &rec, stdout );
}
/* sig records */
for(recno=ur.r.uid.siglist; recno; recno = rec.r.sig.next ) {
rc = tdbio_read_record( recno, &rec, RECTYPE_SIG );
if( rc ) {
log_error(_("lid %lu: read sig record failed: %s\n"),
lid, g10_errstr(rc));
return rc;
}
tdbio_dump_record( &rec, stdout );
}
}
/* add cache record dump here */
return rc;
}
/**************** /****************
* Dump the entire trustdb or only the entries of one key. * Dump the entire trustdb or only the entries of one key.
*/ */
@ -336,38 +71,8 @@ list_trustdb( const char *username )
TRUSTREC rec; TRUSTREC rec;
init_trustdb(); init_trustdb();
/* for now we ignore the user ID */
if( username && *username == '#' ) { if (1) {
int rc;
ulong lid = atoi(username+1);
if( (rc = list_records( lid)) )
log_error(_("user '%s' read problem: %s\n"),
username, g10_errstr(rc));
else if( (rc = list_sigs( lid )) )
log_error(_("user '%s' list problem: %s\n"),
username, g10_errstr(rc));
}
else if( username ) {
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
int rc;
if( (rc = get_pubkey_byname( pk, username, NULL, NULL )) )
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
log_error(_("problem finding '%s' in trustdb: %s\n"),
username, g10_errstr(rc));
else if( rc == -1 )
log_error(_("user '%s' not in trustdb\n"), username);
else if( (rc = list_records( pk->local_id)) )
log_error(_("user '%s' read problem: %s\n"),
username, g10_errstr(rc));
else if( (rc = list_sigs( pk->local_id )) )
log_error(_("user '%s' list problem: %s\n"),
username, g10_errstr(rc));
free_public_key( pk );
}
else {
ulong recnum; ulong recnum;
int i; int i;
@ -391,33 +96,22 @@ void
export_ownertrust() export_ownertrust()
{ {
TRUSTREC rec; TRUSTREC rec;
TRUSTREC rec2;
ulong recnum; ulong recnum;
int i; int i;
byte *p; byte *p;
int rc;
init_trustdb(); init_trustdb();
printf(_("# List of assigned trustvalues, created %s\n" printf(_("# List of assigned trustvalues, created %s\n"
"# (Use \"gpg --import-ownertrust\" to restore them)\n"), "# (Use \"gpg --import-ownertrust\" to restore them)\n"),
asctimestamp( make_timestamp() ) ); asctimestamp( make_timestamp() ) );
for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) { for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
if( rec.rectype == RECTYPE_DIR ) { if( rec.rectype == RECTYPE_TRUST ) {
if( !rec.r.dir.keylist ) { if( !rec.r.trust.ownertrust )
log_error(_("directory record w/o primary key\n"));
continue; continue;
} p = rec.r.trust.fingerprint;
if( !rec.r.dir.ownertrust ) for(i=0; i < 20; i++, p++ )
continue;
rc = tdbio_read_record( rec.r.dir.keylist, &rec2, RECTYPE_KEY);
if( rc ) {
log_error(_("error reading key record: %s\n"), g10_errstr(rc));
continue;
}
p = rec2.r.key.fingerprint;
for(i=0; i < rec2.r.key.fingerprint_len; i++, p++ )
printf("%02X", *p ); printf("%02X", *p );
printf(":%u:\n", (unsigned)rec.r.dir.ownertrust ); printf(":%u:\n", (unsigned int)rec.r.trust.ownertrust );
} }
} }
} }
@ -431,7 +125,9 @@ import_ownertrust( const char *fname )
char line[256]; char line[256];
char *p; char *p;
size_t n, fprlen; size_t n, fprlen;
unsigned otrust; unsigned int otrust;
byte fpr[20];
int any = 0;
init_trustdb(); init_trustdb();
if( !fname || (*fname == '-' && !fname[1]) ) { if( !fname || (*fname == '-' && !fname[1]) ) {
@ -475,51 +171,45 @@ import_ownertrust( const char *fname )
if( !otrust ) if( !otrust )
continue; /* no otrust defined - no need to update or insert */ continue; /* no otrust defined - no need to update or insert */
/* convert the ascii fingerprint to binary */ /* convert the ascii fingerprint to binary */
for(p=line, fprlen=0; *p != ':'; p += 2 ) for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 )
line[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
line[fprlen] = 0; while (fprlen < 20)
fpr[fprlen++] = 0;
repeat: rc = tdbio_search_trust_byfpr (fpr, &rec);
rc = tdbio_search_dir_byfpr( line, fprlen, 0, &rec );
if( !rc ) { /* found: update */ if( !rc ) { /* found: update */
if( rec.r.dir.ownertrust ) if (rec.r.trust.ownertrust != otrust)
log_info("LID %lu: changing trust from %u to %u\n", {
rec.r.dir.lid, rec.r.dir.ownertrust, otrust ); if( rec.r.trust.ownertrust )
log_info("changing ownertrust from %u to %u\n",
rec.r.trust.ownertrust, otrust );
else else
log_info("LID %lu: setting trust to %u\n", log_info("setting ownertrust to %u\n", otrust );
rec.r.dir.lid, otrust ); rec.r.trust.ownertrust = otrust;
rec.r.dir.ownertrust = otrust;
write_record (&rec ); write_record (&rec );
} any = 1;
else if( rc == -1 ) { /* not found; get the key from the ring */
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
log_info_f(fname, _("key not in trustdb, searching ring.\n"));
rc = get_pubkey_byfprint( pk, line, fprlen );
if( rc )
log_info_f(fname, _("key not in ring: %s\n"), g10_errstr(rc));
else {
rc = query_trust_record( pk ); /* only as assertion */
if( rc != -1 )
log_error_f(fname, _("Oops: key is now in trustdb???\n"));
else {
rc = insert_trust_record_by_pk( pk );
if( !rc )
goto repeat; /* update the ownertrust */
log_error_f(fname, _("insert trust record failed: %s\n"),
g10_errstr(rc) );
} }
} }
else if( rc == -1 ) { /* not found: insert */
log_info("inserting ownertrust of %u\n", otrust );
memset (&rec, 0, sizeof rec);
rec.recnum = tdbio_new_recnum ();
rec.rectype = RECTYPE_TRUST;
memcpy (rec.r.trust.fingerprint, fpr, 20);
rec.r.trust.ownertrust = otrust;
write_record (&rec );
any = 1;
} }
else /* error */ else /* error */
log_error_f(fname, _("error finding dir record: %s\n"), log_error_f(fname, _("error finding trust record: %s\n"),
g10_errstr(rc)); g10_errstr(rc));
} }
if( ferror(fp) ) if( ferror(fp) )
log_error_f(fname, _("read error: %s\n"), strerror(errno) ); log_error_f(fname, _("read error: %s\n"), strerror(errno) );
if( !is_stdin ) if( !is_stdin )
fclose(fp); fclose(fp);
do_sync();
sync_trustdb(); if (any)
revalidation_mark ();
} }

View File

@ -83,6 +83,8 @@ static int db_fd = -1;
static int in_transaction; static int in_transaction;
static void open_db(void); static void open_db(void);
static void migrate_from_v2 (void);
/************************************* /*************************************
@ -406,6 +408,28 @@ cleanup(void)
} }
} }
static int
create_version_record (void)
{
TRUSTREC rec;
int rc;
memset( &rec, 0, sizeof rec );
rec.r.ver.version = 3;
rec.r.ver.created = make_timestamp();
rec.r.ver.marginals = opt.marginals_needed;
rec.r.ver.completes = opt.completes_needed;
rec.r.ver.cert_depth = opt.max_cert_depth;
rec.rectype = RECTYPE_VER;
rec.recnum = 0;
rc = tdbio_write_record( &rec );
if( !rc )
tdbio_sync();
return rc;
}
int int
tdbio_set_dbname( const char *new_dbname, int create ) tdbio_set_dbname( const char *new_dbname, int create )
{ {
@ -469,17 +493,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
log_fatal( _("%s: can't create lock\n"), db_name ); log_fatal( _("%s: can't create lock\n"), db_name );
#endif /* !__riscos__ */ #endif /* !__riscos__ */
memset( &rec, 0, sizeof rec ); rc = create_version_record ();
rec.r.ver.version = 2;
rec.r.ver.created = make_timestamp();
rec.r.ver.marginals = opt.marginals_needed;
rec.r.ver.completes = opt.completes_needed;
rec.r.ver.cert_depth = opt.max_cert_depth;
rec.rectype = RECTYPE_VER;
rec.recnum = 0;
rc = tdbio_write_record( &rec );
if( !rc )
tdbio_sync();
if( rc ) if( rc )
log_fatal( _("%s: failed to create version record: %s"), log_fatal( _("%s: failed to create version record: %s"),
fname, g10_errstr(rc)); fname, g10_errstr(rc));
@ -510,7 +524,10 @@ tdbio_get_dbname()
static void static void
open_db() open_db()
{ {
byte buf[10];
int n;
TRUSTREC rec; TRUSTREC rec;
assert( db_fd == -1 ); assert( db_fd == -1 );
if (!lockhandle ) if (!lockhandle )
@ -528,13 +545,24 @@ open_db()
#endif #endif
if ( db_fd == -1 ) if ( db_fd == -1 )
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
/* check whether we need to do a version migration */
do
n = read (db_fd, buf, 5);
while (n==-1 && errno == EINTR);
if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5))
{
migrate_from_v2 ();
}
/* read the version record */
if (tdbio_read_record (0, &rec, RECTYPE_VER ) ) if (tdbio_read_record (0, &rec, RECTYPE_VER ) )
log_fatal( _("%s: invalid trustdb\n"), db_name ); log_fatal( _("%s: invalid trustdb\n"), db_name );
} }
/**************** /****************
* Make a hashtable: type 0 = key hash, 1 = sdir hash * Make a hashtable: type 0 = trust hash
*/ */
static void static void
create_hashtable( TRUSTREC *vr, int type ) create_hashtable( TRUSTREC *vr, int type )
@ -551,9 +579,8 @@ create_hashtable( TRUSTREC *vr, int type )
assert(recnum); /* this is will never be the first record */ assert(recnum); /* this is will never be the first record */
if( !type ) if( !type )
vr->r.ver.keyhashtbl = recnum; vr->r.ver.trusthashtbl = recnum;
else
vr->r.ver.sdirhashtbl = recnum;
/* Now write the records */ /* Now write the records */
n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD; n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
for(i=0; i < n; i++, recnum++ ) { for(i=0; i < n; i++, recnum++ ) {
@ -612,50 +639,36 @@ tdbio_db_matches_options()
/**************** /****************
* Return the modifiy stamp. * Return the nextstamp value.
* if modify_down is true, the modify_down stamp will be
* returned, otherwise the modify_up stamp.
*/ */
ulong ulong
tdbio_read_modify_stamp( int modify_down ) tdbio_read_nextcheck ()
{ {
TRUSTREC vr; TRUSTREC vr;
int rc; int rc;
ulong mod;
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal( _("%s: error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
db_name, g10_errstr(rc) ); db_name, g10_errstr(rc) );
return vr.r.ver.nextcheck;
mod = modify_down? vr.r.ver.mod_down : vr.r.ver.mod_up;
/* Always return at least 1 to make comparison easier;
* this is still far back in history (before Led Zeppelin III :-) */
return mod ? mod : 1;
} }
void void
tdbio_write_modify_stamp( int up, int down ) tdbio_write_nextcheck (ulong stamp)
{ {
TRUSTREC vr; TRUSTREC vr;
int rc; int rc;
ulong stamp;
if( !(up || down) )
return;
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal( _("%s: error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
db_name, g10_errstr(rc) ); db_name, g10_errstr(rc) );
stamp = make_timestamp(); if (vr.r.ver.nextcheck == stamp)
if( down ) return;
vr.r.ver.mod_down = stamp;
if( up )
vr.r.ver.mod_up = stamp;
vr.r.ver.nextcheck = stamp;
rc = tdbio_write_record( &vr ); rc = tdbio_write_record( &vr );
if( rc ) if( rc )
log_fatal( _("%s: error writing version record: %s\n"), log_fatal( _("%s: error writing version record: %s\n"),
@ -663,15 +676,16 @@ tdbio_write_modify_stamp( int up, int down )
} }
/**************** /****************
* Return the record number of the keyhash tbl or create a new one. * Return the record number of the trusthash tbl or create a new one.
*/ */
static ulong static ulong
get_keyhashrec(void) get_trusthashrec(void)
{ {
static ulong keyhashtbl; /* record number of the key hashtable */ static ulong trusthashtbl; /* record number of the trust hashtable */
if( !keyhashtbl ) { if( !trusthashtbl ) {
TRUSTREC vr; TRUSTREC vr;
int rc; int rc;
@ -679,38 +693,14 @@ get_keyhashrec(void)
if( rc ) if( rc )
log_fatal( _("%s: error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
db_name, g10_errstr(rc) ); db_name, g10_errstr(rc) );
if( !vr.r.ver.keyhashtbl ) if( !vr.r.ver.trusthashtbl )
create_hashtable( &vr, 0 ); create_hashtable( &vr, 0 );
keyhashtbl = vr.r.ver.keyhashtbl; trusthashtbl = vr.r.ver.trusthashtbl;
} }
return keyhashtbl; return trusthashtbl;
} }
/****************
* Return the record number of the shadow direcory hash table
* or create a new one.
*/
static ulong
get_sdirhashrec(void)
{
static ulong sdirhashtbl; /* record number of the hashtable */
if( !sdirhashtbl ) {
TRUSTREC vr;
int rc;
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc )
log_fatal( _("%s: error reading version record: %s\n"),
db_name, g10_errstr(rc) );
if( !vr.r.ver.sdirhashtbl )
create_hashtable( &vr, 1 );
sdirhashtbl = vr.r.ver.sdirhashtbl;
}
return sdirhashtbl;
}
/**************** /****************
@ -827,9 +817,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
} }
} /* end loop over hlst slots */ } /* end loop over hlst slots */
} }
else if( rec.rectype == RECTYPE_KEY else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */
|| rec.rectype == RECTYPE_DIR
|| rec.rectype == RECTYPE_SDIR ) { /* insert a list record */
if( rec.recnum == newrecnum ) { if( rec.recnum == newrecnum ) {
return 0; return 0;
} }
@ -1036,57 +1024,16 @@ lookup_hashtable( ulong table, const byte *key, size_t keylen,
} }
/**************** /****************
* Update the key hashtbl or create the table if it does not exist * Update the trust hashtbl or create the table if it does not exist
*/ */
static int static int
update_keyhashtbl( TRUSTREC *kr ) update_trusthashtbl( TRUSTREC *tr )
{ {
return upd_hashtable( get_keyhashrec(), return upd_hashtable( get_trusthashrec(),
kr->r.key.fingerprint, tr->r.trust.fingerprint, 20, tr->recnum );
kr->r.key.fingerprint_len, kr->recnum );
} }
/****************
* Update the shadow dir hashtbl or create the table if it does not exist
*/
static int
update_sdirhashtbl( TRUSTREC *sr )
{
byte key[8];
u32tobuf( key , sr->r.sdir.keyid[0] );
u32tobuf( key+4 , sr->r.sdir.keyid[1] );
return upd_hashtable( get_sdirhashrec(), key, 8, sr->recnum );
}
/****************
* Drop the records from the key-hashtbl
*/
static int
drop_from_keyhashtbl( TRUSTREC *kr )
{
return drop_from_hashtable( get_keyhashrec(),
kr->r.key.fingerprint,
kr->r.key.fingerprint_len, kr->recnum );
}
/****************
* Drop record drom the shadow dir hashtbl
*/
static int
drop_from_sdirhashtbl( TRUSTREC *sr )
{
byte key[8];
u32tobuf( key , sr->r.sdir.keyid[0] );
u32tobuf( key+4 , sr->r.sdir.keyid[1] );
return drop_from_hashtable( get_sdirhashrec(), key, 8, sr->recnum );
}
void void
@ -1094,7 +1041,6 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
{ {
int i; int i;
ulong rnum = rec->recnum; ulong rnum = rec->recnum;
byte *p;
fprintf(fp, "rec %5lu, ", rnum ); fprintf(fp, "rec %5lu, ", rnum );
@ -1102,116 +1048,18 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
case 0: fprintf(fp, "blank\n"); case 0: fprintf(fp, "blank\n");
break; break;
case RECTYPE_VER: fprintf(fp, case RECTYPE_VER: fprintf(fp,
"version, kd=%lu, sd=%lu, free=%lu, m/c/d=%d/%d/%d down=%s", "version, td=%lu, f=%lu, m/c/d=%d/%d/%d nc=%lu (%s)\n",
rec->r.ver.keyhashtbl, rec->r.ver.sdirhashtbl, rec->r.ver.trusthashtbl,
rec->r.ver.firstfree, rec->r.ver.firstfree,
rec->r.ver.marginals, rec->r.ver.marginals,
rec->r.ver.completes, rec->r.ver.completes,
rec->r.ver.cert_depth, rec->r.ver.cert_depth,
strtimestamp(rec->r.ver.mod_down) ); rec->r.ver.nextcheck,
fprintf(fp, ", up=%s\n", strtimestamp(rec->r.ver.mod_up) ); strtimestamp(rec->r.ver.nextcheck)
);
break; break;
case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next ); case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next );
break; break;
case RECTYPE_DIR:
fprintf(fp, "dir %lu, keys=%lu, uids=%lu, t=%02x",
rec->r.dir.lid,
rec->r.dir.keylist,
rec->r.dir.uidlist,
rec->r.dir.ownertrust );
if( rec->r.dir.valcheck )
fprintf( fp, ", v=%02x/%s", rec->r.dir.validity,
strtimestamp(rec->r.dir.valcheck) );
if( rec->r.dir.checkat )
fprintf( fp, ", a=%s", strtimestamp(rec->r.dir.checkat) );
if( rec->r.dir.dirflags & DIRF_CHECKED ) {
if( rec->r.dir.dirflags & DIRF_VALID )
fputs(", valid", fp );
if( rec->r.dir.dirflags & DIRF_EXPIRED )
fputs(", expired", fp );
if( rec->r.dir.dirflags & DIRF_REVOKED )
fputs(", revoked", fp );
if( rec->r.dir.dirflags & DIRF_NEWKEYS )
fputs(", newkeys", fp );
}
putc('\n', fp);
break;
case RECTYPE_KEY:
fprintf(fp, "key %lu, n=%lu a=%d ",
rec->r.key.lid,
rec->r.key.next,
rec->r.key.pubkey_algo );
for(i=0; i < rec->r.key.fingerprint_len; i++ )
fprintf(fp, "%02X", rec->r.key.fingerprint[i] );
if( rec->r.key.keyflags & KEYF_CHECKED ) {
if( rec->r.key.keyflags & KEYF_VALID )
fputs(", valid", fp );
if( rec->r.key.keyflags & KEYF_EXPIRED )
fputs(", expired", fp );
if( rec->r.key.keyflags & KEYF_REVOKED )
fputs(", revoked", fp );
}
putc('\n', fp);
break;
case RECTYPE_UID:
fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X",
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]);
fprintf( fp, ", v=%02x", rec->r.uid.validity );
if( rec->r.uid.uidflags & UIDF_CHECKED ) {
if( rec->r.uid.uidflags & UIDF_VALID )
fputs(", valid", fp );
if( rec->r.uid.uidflags & UIDF_REVOKED )
fputs(", revoked", fp );
}
putc('\n', fp);
break;
case RECTYPE_PREF:
fprintf(fp, "pref %lu, next=%lu,",
rec->r.pref.lid, rec->r.pref.next);
for(i=0,p=rec->r.pref.data; i < ITEMS_PER_PREF_RECORD; i+=2,p+=2 ) {
if( *p )
fprintf(fp, " %c%d", *p == PREFTYPE_SYM ? 'S' :
*p == PREFTYPE_HASH ? 'H' :
*p == PREFTYPE_ZIP ? 'Z' : '?', p[1]);
}
putc('\n', fp);
break;
case RECTYPE_SIG:
fprintf(fp, "sig %lu, next=%lu,",
rec->r.sig.lid, rec->r.sig.next );
for(i=0; i < SIGS_PER_RECORD; i++ ) {
if( rec->r.sig.sig[i].lid ) {
fprintf(fp, " %lu:", rec->r.sig.sig[i].lid );
if( rec->r.sig.sig[i].flag & SIGF_CHECKED ) {
fprintf(fp,"%c%c%c",
(rec->r.sig.sig[i].flag & SIGF_VALID) ? 'V':
(rec->r.sig.sig[i].flag & SIGF_IGNORED) ? 'I':'-',
(rec->r.sig.sig[i].flag & SIGF_EXPIRED) ? 'E':'-',
(rec->r.sig.sig[i].flag & SIGF_REVOKED) ? 'R':'-');
}
else if( rec->r.sig.sig[i].flag & SIGF_NOPUBKEY)
fputs("?--", fp);
else
fputs("---", fp);
}
}
putc('\n', fp);
break;
case RECTYPE_SDIR:
fprintf(fp, "sdir %lu, keyid=%08lX%08lX, algo=%d, hint=%lu\n",
rec->r.sdir.lid,
(ulong)rec->r.sdir.keyid[0],
(ulong)rec->r.sdir.keyid[1],
rec->r.sdir.pubkey_algo,
(ulong)rec->r.sdir.hintlist );
break;
case RECTYPE_CACH:
fprintf(fp, "cach\n");
break;
case RECTYPE_HTBL: case RECTYPE_HTBL:
fprintf(fp, "htbl,"); fprintf(fp, "htbl,");
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ )
@ -1224,6 +1072,20 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
fprintf(fp, " %lu", rec->r.hlst.rnum[i] ); fprintf(fp, " %lu", rec->r.hlst.rnum[i] );
putc('\n', fp); putc('\n', fp);
break; break;
case RECTYPE_TRUST:
fprintf(fp, "trust ");
for(i=0; i < 20; i++ )
fprintf(fp, "%02X", rec->r.trust.fingerprint[i] );
fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust,
rec->r.trust.depth, rec->r.trust.validlist);
break;
case RECTYPE_VALID:
fprintf(fp, "valid ");
for(i=0; i < 20; i++ )
fprintf(fp, "%02X", rec->r.valid.namehash[i] );
fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity,
rec->r.valid.next);
break;
default: default:
fprintf(fp, "unknown type %d\n", rec->rectype ); fprintf(fp, "unknown type %d\n", rec->rectype );
break; break;
@ -1279,24 +1141,25 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
log_error( _("%s: not a trustdb file\n"), db_name ); log_error( _("%s: not a trustdb file\n"), db_name );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
p += 2; /* skip "pgp" */ p += 2; /* skip "gpg" */
rec->r.ver.version = *p++; rec->r.ver.version = *p++;
rec->r.ver.marginals = *p++; rec->r.ver.marginals = *p++;
rec->r.ver.completes = *p++; rec->r.ver.completes = *p++;
rec->r.ver.cert_depth = *p++; rec->r.ver.cert_depth = *p++;
p += 4; /* lock flags */ p += 4; /* lock flags */
rec->r.ver.created = buftoulong(p); p += 4; rec->r.ver.created = buftoulong(p); p += 4;
rec->r.ver.mod_down = buftoulong(p); p += 4; rec->r.ver.nextcheck = buftoulong(p); p += 4;
rec->r.ver.mod_up = buftoulong(p); p += 4; p += 4;
rec->r.ver.keyhashtbl=buftoulong(p); p += 4; p += 4;
rec->r.ver.firstfree =buftoulong(p); p += 4; rec->r.ver.firstfree =buftoulong(p); p += 4;
rec->r.ver.sdirhashtbl =buftoulong(p); p += 4; p += 4;
rec->r.ver.trusthashtbl =buftoulong(p); p += 4;
if( recnum ) { if( recnum ) {
log_error( _("%s: version record with recnum %lu\n"), db_name, log_error( _("%s: version record with recnum %lu\n"), db_name,
(ulong)recnum ); (ulong)recnum );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
else if( rec->r.ver.version != 2 ) { else if( rec->r.ver.version != 3 ) {
log_error( _("%s: invalid file version %d\n"), db_name, log_error( _("%s: invalid file version %d\n"), db_name,
rec->r.ver.version ); rec->r.ver.version );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
@ -1305,95 +1168,6 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
case RECTYPE_FREE: case RECTYPE_FREE:
rec->r.free.next = buftoulong(p); p += 4; rec->r.free.next = buftoulong(p); p += 4;
break; break;
case RECTYPE_DIR: /*directory record */
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.dirflags = *p++;
rec->r.dir.validity = *p++;
rec->r.dir.valcheck = buftoulong(p); p += 4;
rec->r.dir.checkat = buftoulong(p); p += 4;
switch( rec->r.dir.validity ) {
case 0:
case TRUST_UNDEFINED:
case TRUST_NEVER:
case TRUST_MARGINAL:
case TRUST_FULLY:
case TRUST_ULTIMATE:
break;
default:
log_info("lid %lu: invalid validity value - cleared\n", recnum);
}
if( rec->r.dir.lid != recnum ) {
log_error( "%s: dir LID != recnum (%lu,%lu)\n",
db_name, rec->r.dir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_KEY: /* public key record */
rec->r.key.lid = buftoulong(p); p += 4;
rec->r.key.next = buftoulong(p); p += 4;
p += 7;
rec->r.key.keyflags = *p++;
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);
break;
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;
rec->r.uid.uidflags = *p++;
rec->r.uid.validity = *p++;
switch( rec->r.uid.validity ) {
case 0:
case TRUST_UNDEFINED:
case TRUST_NEVER:
case TRUST_MARGINAL:
case TRUST_FULLY:
case TRUST_ULTIMATE:
break;
default:
log_info("lid %lu: invalid validity value - cleared\n", recnum);
}
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;
memcpy( rec->r.pref.data, p, 30 );
break;
case RECTYPE_SIG:
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].lid = buftoulong(p); p += 4;
rec->r.sig.sig[i].flag = *p++;
}
break;
case RECTYPE_SDIR: /* shadow directory record */
rec->r.sdir.lid = buftoulong(p); p += 4;
rec->r.sdir.keyid[0]= buftou32(p); p += 4;
rec->r.sdir.keyid[1]= buftou32(p); p += 4;
rec->r.sdir.pubkey_algo = *p++;
p += 3;
rec->r.sdir.hintlist = buftoulong(p);
if( rec->r.sdir.lid != recnum ) {
log_error( "%s: sdir LID != recnum (%lu,%lu)\n",
db_name, rec->r.sdir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_CACH: /* cache record */
rec->r.cache.lid = buftoulong(p); p += 4;
memcpy(rec->r.cache.blockhash, p, 20); p += 20;
rec->r.cache.trustlevel = *p++;
break;
case RECTYPE_HTBL: case RECTYPE_HTBL:
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
rec->r.htbl.item[i] = buftoulong(p); p += 4; rec->r.htbl.item[i] = buftoulong(p); p += 4;
@ -1405,6 +1179,18 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
rec->r.hlst.rnum[i] = buftoulong(p); p += 4; rec->r.hlst.rnum[i] = buftoulong(p); p += 4;
} }
break; break;
case RECTYPE_TRUST:
memcpy( rec->r.trust.fingerprint, p, 20); p+=20;
rec->r.trust.ownertrust = *p++;
rec->r.trust.depth = *p++;
p += 2;
rec->r.trust.validlist = buftoulong(p); p += 4;
break;
case RECTYPE_VALID:
memcpy( rec->r.valid.namehash, p, 20); p+=20;
rec->r.valid.validity = *p++;
rec->r.valid.next = buftoulong(p); p += 4;
break;
default: default:
log_error( "%s: invalid record type %d at recnum %lu\n", log_error( "%s: invalid record type %d at recnum %lu\n",
db_name, rec->rectype, (ulong)recnum ); db_name, rec->rectype, (ulong)recnum );
@ -1445,79 +1231,18 @@ tdbio_write_record( TRUSTREC *rec )
*p++ = rec->r.ver.cert_depth; *p++ = rec->r.ver.cert_depth;
p += 4; /* skip lock flags */ p += 4; /* skip lock flags */
ulongtobuf(p, rec->r.ver.created); p += 4; ulongtobuf(p, rec->r.ver.created); p += 4;
ulongtobuf(p, rec->r.ver.mod_down); p += 4; ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
ulongtobuf(p, rec->r.ver.mod_up); p += 4; p += 4;
ulongtobuf(p, rec->r.ver.keyhashtbl); p += 4; p += 4;
ulongtobuf(p, rec->r.ver.firstfree ); p += 4; ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
ulongtobuf(p, rec->r.ver.sdirhashtbl ); p += 4; p += 4;
ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
break; break;
case RECTYPE_FREE: case RECTYPE_FREE:
ulongtobuf(p, rec->r.free.next); p += 4; ulongtobuf(p, rec->r.free.next); p += 4;
break; break;
case RECTYPE_DIR: /*directory record */
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.dirflags;
*p++ = rec->r.dir.validity;
ulongtobuf(p, rec->r.dir.valcheck); p += 4;
ulongtobuf(p, rec->r.dir.checkat); p += 4;
assert( rec->r.dir.lid == recnum );
break;
case RECTYPE_KEY:
ulongtobuf(p, rec->r.key.lid); p += 4;
ulongtobuf(p, rec->r.key.next); p += 4;
p += 7;
*p++ = rec->r.key.keyflags;
*p++ = rec->r.key.pubkey_algo;
*p++ = rec->r.key.fingerprint_len;
memcpy( p, rec->r.key.fingerprint, 20); p += 20;
break;
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++ = rec->r.uid.uidflags;
*p++ = rec->r.uid.validity;
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;
memcpy( p, rec->r.pref.data, 30 );
break;
case RECTYPE_SIG:
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].lid); p += 4;
*p++ = rec->r.sig.sig[i].flag;
}
break;
case RECTYPE_SDIR:
ulongtobuf( p, rec->r.sdir.lid); p += 4;
u32tobuf( p, rec->r.sdir.keyid[0] ); p += 4;
u32tobuf( p, rec->r.sdir.keyid[1] ); p += 4;
*p++ = rec->r.sdir.pubkey_algo;
p += 3;
ulongtobuf( p, rec->r.sdir.hintlist );
break;
case RECTYPE_CACH:
ulongtobuf(p, rec->r.cache.lid); p += 4;
memcpy(p, rec->r.cache.blockhash, 20); p += 20;
*p++ = rec->r.cache.trustlevel;
break;
case RECTYPE_HTBL: case RECTYPE_HTBL:
for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
@ -1532,6 +1257,20 @@ tdbio_write_record( TRUSTREC *rec )
} }
break; break;
case RECTYPE_TRUST:
memcpy( p, rec->r.trust.fingerprint, 20); p += 20;
*p++ = rec->r.trust.ownertrust;
*p++ = rec->r.trust.depth;
p += 2;
ulongtobuf( p, rec->r.trust.validlist); p += 4;
break;
case RECTYPE_VALID:
memcpy( p, rec->r.valid.namehash, 20); p += 20;
*p++ = rec->r.valid.validity;
ulongtobuf( p, rec->r.valid.next); p += 4;
break;
default: default:
BUG(); BUG();
} }
@ -1539,10 +1278,8 @@ tdbio_write_record( TRUSTREC *rec )
rc = put_record_into_cache( recnum, buf ); rc = put_record_into_cache( recnum, buf );
if( rc ) if( rc )
; ;
else if( rec->rectype == RECTYPE_KEY ) else if( rec->rectype == RECTYPE_TRUST )
rc = update_keyhashtbl( rec ); rc = update_trusthashtbl( rec );
else if( rec->rectype == RECTYPE_SDIR )
rc = update_sdirhashtbl( rec );
return rc; return rc;
} }
@ -1557,10 +1294,10 @@ tdbio_delete_record( ulong recnum )
rc = tdbio_read_record( recnum, &rec, 0 ); rc = tdbio_read_record( recnum, &rec, 0 );
if( rc ) if( rc )
; ;
else if( rec.rectype == RECTYPE_KEY ) else if( rec.rectype == RECTYPE_TRUST ) {
rc = drop_from_keyhashtbl( &rec ); rc = drop_from_hashtable( get_trusthashrec(),
else if( rec.rectype == RECTYPE_SDIR ) rec.r.trust.fingerprint, 20, rec.recnum );
rc = drop_from_sdirhashtbl( &rec ); }
if( rc ) if( rc )
return rc; return rc;
@ -1657,104 +1394,38 @@ tdbio_new_recnum()
/**************** static int
* Search the trustdb for a key which matches PK and return the dir record cmp_trec_fpr ( void *fpr, const TRUSTREC *rec )
* The local_id of PK is set to the correct value {
*/ return rec->rectype == RECTYPE_TRUST
&& !memcmp( rec->r.trust.fingerprint, fpr, 20);
}
int int
tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ) tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec )
{
int rc;
/* locate the trust record using the hash table */
rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20,
cmp_trec_fpr, (void*)fingerprint, rec );
return rc;
}
int
tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
{ {
byte fingerprint[MAX_FINGERPRINT_LEN]; byte fingerprint[MAX_FINGERPRINT_LEN];
size_t fingerlen; size_t fingerlen;
u32 keyid[2];
int rc;
keyid_from_pk( pk, keyid );
fingerprint_from_pk( pk, fingerprint, &fingerlen ); fingerprint_from_pk( pk, fingerprint, &fingerlen );
rc = tdbio_search_dir_byfpr( fingerprint, fingerlen, for (; fingerlen < 20; fingerlen++ )
pk->pubkey_algo, rec ); fingerprint[fingerlen] = 0;
return tdbio_search_trust_byfpr (fingerprint, rec);
if( !rc ) {
if( pk->local_id && pk->local_id != rec->recnum )
log_error("%s: found record, but LID from memory does "
"not match recnum (%lu,%lu)\n",
db_name, pk->local_id, rec->recnum );
pk->local_id = rec->recnum;
}
return rc;
} }
static int
cmp_krec_fpr( void *dataptr, const TRUSTREC *rec )
{
const struct cmp_krec_fpr_struct *d = dataptr;
return rec->rectype == RECTYPE_KEY
&& ( !d->pubkey_algo || rec->r.key.pubkey_algo == d->pubkey_algo )
&& rec->r.key.fingerprint_len == d->fprlen
&& !memcmp( rec->r.key.fingerprint, d->fpr, d->fprlen );
}
int
tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
int pubkey_algo, TRUSTREC *rec )
{
struct cmp_krec_fpr_struct cmpdata;
ulong recnum;
int rc;
assert( fingerlen == 20 || fingerlen == 16 );
/* locate the key using the hash table */
cmpdata.pubkey_algo = pubkey_algo;
cmpdata.fpr = fingerprint;
cmpdata.fprlen = fingerlen;
rc = lookup_hashtable( get_keyhashrec(), fingerprint, fingerlen,
cmp_krec_fpr, &cmpdata, rec );
if( !rc ) {
recnum = rec->r.key.lid;
/* Now read the dir record */
rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
if( rc )
log_error("%s: can't read dirrec %lu: %s\n",
db_name, recnum, g10_errstr(rc) );
}
return rc;
}
static int
cmp_sdir( void *dataptr, const TRUSTREC *rec )
{
const struct cmp_xdir_struct *d = dataptr;
return rec->rectype == RECTYPE_SDIR
&& ( !d->pubkey_algo || rec->r.sdir.pubkey_algo == d->pubkey_algo )
&& rec->r.sdir.keyid[0] == d->keyid[0]
&& rec->r.sdir.keyid[1] == d->keyid[1];
}
int
tdbio_search_sdir( u32 *keyid, int pubkey_algo, TRUSTREC *rec )
{
struct cmp_xdir_struct cmpdata;
int rc;
byte key[8];
/* locate the shadow dir record using the hash table */
u32tobuf( key , keyid[0] );
u32tobuf( key+4 , keyid[1] );
cmpdata.pubkey_algo = pubkey_algo;
cmpdata.keyid[0] = keyid[0];
cmpdata.keyid[1] = keyid[1];
rc = lookup_hashtable( get_sdirhashrec(), key, 8,
cmp_sdir, &cmpdata, rec );
return rc;
}
void void
tdbio_invalid(void) tdbio_invalid(void)
@ -1764,4 +1435,130 @@ tdbio_invalid(void)
g10_exit(2); g10_exit(2);
} }
/*
* Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
* to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
* only to scan the tdb and insert new the new trust records. The old ones are
* obsolte from now on
*/
static void
migrate_from_v2 ()
{
TRUSTREC rec;
int i, n;
struct {
ulong keyrecno;
byte ot;
byte okay;
byte fpr[20];
} *ottable;
int ottable_size, ottable_used;
byte oldbuf[40];
ulong recno;
int count;
ottable_size = 5;
ottable = m_alloc (ottable_size * sizeof *ottable);
ottable_used = 0;
/* We have some restrictions here. We can't use the version record
* and we can't use any of the old hashtables because we dropped the
* code. So we first collect all ownertrusts and then use a second
* pass fo find the associated keys. We have to do this all without using
* the regular record read functions.
*/
/* get all the ownertrusts */
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
for (recno=0;;recno++)
{
do
n = read (db_fd, oldbuf, 40);
while (n==-1 && errno == EINTR);
if (!n)
break; /* eof */
if (n != 40)
log_fatal ("migrate_vfrom_v2: read error or short read\n");
if (*oldbuf != 2)
continue;
/* v2 dir record */
if (ottable_used == ottable_size)
{
ottable_size += 1000;
ottable = m_realloc (ottable, ottable_size * sizeof *ottable);
}
ottable[ottable_used].keyrecno = buftoulong (oldbuf+6);
ottable[ottable_used].ot = oldbuf[17];
ottable[ottable_used].okay = 0;
memset (ottable[ottable_used].fpr,0, 20);
if (ottable[ottable_used].keyrecno)
ottable_used++;
}
log_info ("found %d ownertrust records\n", ottable_used);
/* Read again and find the fingerprints */
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
for (recno=0;;recno++)
{
do
n = read (db_fd, oldbuf, 40);
while (n==-1 && errno == EINTR);
if (!n)
break; /* eof */
if (n != 40)
log_fatal ("migrate_from_v2: read error or short read\n");
if (*oldbuf != 3)
continue;
/* v2 key record */
for (i=0; i < ottable_used; i++)
{
if (ottable[i].keyrecno == recno)
{
memcpy (ottable[i].fpr, oldbuf+20, 20);
ottable[i].okay = 1;
break;
}
}
}
/* got everything - create the v3 trustdb */
if (ftruncate (db_fd, 0))
log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) );
if (create_version_record ())
log_fatal ("failed to recreate version record of `%s'\n", db_name);
/* access the hash table, so it is store just after the version record,
* this is not needed put a dump is more pretty */
get_trusthashrec ();
/* And insert the old ownertrust values */
count = 0;
for (i=0; i < ottable_used; i++)
{
if (!ottable[i].okay)
continue;
memset (&rec, 0, sizeof rec);
rec.recnum = tdbio_new_recnum ();
rec.rectype = RECTYPE_TRUST;
memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20);
rec.r.trust.ownertrust = ottable[i].ot;
if (tdbio_write_record (&rec))
log_fatal ("failed to write trust record of `%s'\n", db_name);
count++;
}
revalidation_mark ();
tdbio_sync ();
log_info ("migrated %d version 2 ownertrusts\n", count);
m_free (ottable);
}

View File

@ -35,41 +35,13 @@
#define RECTYPE_VER 1 #define RECTYPE_VER 1
#define RECTYPE_DIR 2
#define RECTYPE_KEY 3
#define RECTYPE_UID 4
#define RECTYPE_PREF 5
#define RECTYPE_SIG 6
#define RECTYPE_SDIR 8
#define RECTYPE_CACH 9
#define RECTYPE_HTBL 10 #define RECTYPE_HTBL 10
#define RECTYPE_HLST 11 #define RECTYPE_HLST 11
#define RECTYPE_TRUST 12
#define RECTYPE_VALID 13
#define RECTYPE_FREE 254 #define RECTYPE_FREE 254
#define DIRF_CHECKED 1 /* has been checked - bits 1,2,3 are valid */
#define DIRF_VALID 2 /* This key is valid: There is at least */
/* one uid with a selfsignature or an revocation */
#define DIRF_EXPIRED 4 /* the complete key has expired */
#define DIRF_REVOKED 8 /* the complete key has been revoked */
#define DIRF_NEWKEYS 128 /* new keys are available: we can check the sigs */
#define KEYF_CHECKED 1 /* This key has been checked */
#define KEYF_VALID 2 /* This is a valid (sub)key */
#define KEYF_EXPIRED 4 /* this key is expired */
#define KEYF_REVOKED 8 /* this key has been revoked */
#define UIDF_CHECKED 1 /* user id has been checked - other bits are valid */
#define UIDF_VALID 2 /* this is a valid user id */
#define UIDF_REVOKED 8 /* this user id has been revoked */
#define SIGF_CHECKED 1 /* signature has been checked - bits 0..6 are valid */
#define SIGF_VALID 2 /* the signature is valid */
#define SIGF_EXPIRED 4 /* the key of this signature has expired */
#define SIGF_REVOKED 8 /* this signature has been revoked */
#define SIGF_IGNORED 64 /* this signature is ignored by the system */
#define SIGF_NOPUBKEY 128 /* there is no pubkey for this sig */
struct trust_record { struct trust_record {
int rectype; int rectype;
int mark; int mark;
@ -78,73 +50,21 @@ struct trust_record {
ulong recnum; ulong recnum;
union { union {
struct { /* version record: */ struct { /* version record: */
byte version; /* should be 2 */ byte version; /* should be 3 */
byte marginals; byte marginals;
byte completes; byte completes;
byte cert_depth; byte cert_depth;
ulong created; /* timestamp of trustdb creation */ ulong created; /* timestamp of trustdb creation */
ulong mod_down; /* timestamp of last modification downward */ ulong nextcheck; /* timestamp of next scheduled check */
ulong mod_up; /* timestamp of last modification upward */ ulong reserved;
ulong keyhashtbl; ulong reserved2;
ulong firstfree; ulong firstfree;
ulong sdirhashtbl; ulong reserved3;
ulong trusthashtbl;
} ver; } ver;
struct { /* free record */ struct { /* free record */
ulong next; ulong next;
} free; } free;
struct { /* directory record */
ulong lid;
ulong keylist; /* List of keys (the first is the primary key)*/
ulong uidlist; /* list of uid records */
ulong cacherec; /* the cache record */
byte ownertrust;
byte dirflags;
byte validity; /* calculated trustlevel over all uids */
ulong valcheck; /* timestamp of last validation check */
ulong checkat; /* Check key when this time has been reached*/
} dir;
struct { /* primary public key record */
ulong lid;
ulong next; /* next key */
byte keyflags;
byte pubkey_algo;
byte fingerprint_len;
byte fingerprint[20];
} key;
struct { /* user id reord */
ulong lid; /* point back to the directory record */
ulong next; /* points to next user id record */
ulong prefrec; /* recno of preference record */
ulong siglist; /* list of valid signatures (w/o self-sig)*/
byte uidflags;
byte validity; /* calculated trustlevel of this uid */
byte namehash[20]; /* ripemd hash of the username */
} uid;
struct { /* preference record */
ulong lid; /* point back to the directory record */
/* or 0 for a global pref record */
ulong next; /* points to next pref record */
byte data[ITEMS_PER_PREF_RECORD];
} pref; /* pref records are not anymore used! */
struct { /* signature record */
ulong lid;
ulong next; /* recnno of next record or NULL for last one */
struct {
ulong lid; /* of pubkey record of signator (0=unused) */
byte flag; /* SIGF_xxxxx */
} sig[SIGS_PER_RECORD];
} sig;
struct {
ulong lid;
u32 keyid[2];
byte pubkey_algo;
u32 hintlist;
} sdir;
struct { /* cache record */
ulong lid;
byte blockhash[20];
byte trustlevel; /* calculated trustlevel */
} cache;
struct { struct {
ulong item[ITEMS_PER_HTBL_RECORD]; ulong item[ITEMS_PER_HTBL_RECORD];
} htbl; } htbl;
@ -152,25 +72,21 @@ struct trust_record {
ulong next; ulong next;
ulong rnum[ITEMS_PER_HLST_RECORD]; /* of another record */ ulong rnum[ITEMS_PER_HLST_RECORD]; /* of another record */
} hlst; } hlst;
struct {
byte fingerprint[20];
byte ownertrust;
byte depth;
ulong validlist;
} trust;
struct {
byte namehash[20];
ulong next;
byte validity;
} valid;
} r; } r;
}; };
typedef struct trust_record TRUSTREC; typedef struct trust_record TRUSTREC;
typedef struct {
ulong lid; /* localid */
ulong sigrec;
ulong sig_lid; /* returned signatures LID */
unsigned sig_flag; /* returned signature record flag */
struct { /* internal data */
int init_done;
int eof;
TRUSTREC rec;
ulong nextuid;
int index;
} ctl;
} SIGREC_CONTEXT;
/*-- tdbio.c --*/ /*-- tdbio.c --*/
int tdbio_set_dbname( const char *new_dbname, int create ); int tdbio_set_dbname( const char *new_dbname, int create );
const char *tdbio_get_dbname(void); const char *tdbio_get_dbname(void);
@ -178,8 +94,8 @@ void tdbio_dump_record( TRUSTREC *rec, FILE *fp );
int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
int tdbio_write_record( TRUSTREC *rec ); int tdbio_write_record( TRUSTREC *rec );
int tdbio_db_matches_options(void); int tdbio_db_matches_options(void);
ulong tdbio_read_modify_stamp( int modify_down ); ulong tdbio_read_nextcheck (void);
void tdbio_write_modify_stamp( int up, int down ); void tdbio_write_nextcheck (ulong stamp);
int tdbio_is_dirty(void); int tdbio_is_dirty(void);
int tdbio_sync(void); int tdbio_sync(void);
int tdbio_begin_transaction(void); int tdbio_begin_transaction(void);
@ -187,11 +103,8 @@ int tdbio_end_transaction(void);
int tdbio_cancel_transaction(void); int tdbio_cancel_transaction(void);
int tdbio_delete_record( ulong recnum ); int tdbio_delete_record( ulong recnum );
ulong tdbio_new_recnum(void); ulong tdbio_new_recnum(void);
int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ); int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec );
int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec );
int pubkey_algo, TRUSTREC *rec );
int tdbio_search_dir( u32 *keyid, int pubkey_algo, TRUSTREC *rec );
int tdbio_search_sdir( u32 *keyid, int pubkey_algo, TRUSTREC *rec );
void tdbio_invalid(void); void tdbio_invalid(void);

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
/* Trust values must be sorted in ascending order */ /* Trust values must be sorted in ascending order */
#define TRUST_MASK 15 #define TRUST_MASK 15
#define TRUST_UNKNOWN 0 /* o: not yet calculated */ #define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */
#define TRUST_EXPIRED 1 /* e: calculation may be invalid */ #define TRUST_EXPIRED 1 /* e: calculation may be invalid */
#define TRUST_UNDEFINED 2 /* q: not enough information for calculation */ #define TRUST_UNDEFINED 2 /* q: not enough information for calculation */
#define TRUST_NEVER 3 /* n: never trust this pubkey */ #define TRUST_NEVER 3 /* n: never trust this pubkey */
@ -38,31 +38,31 @@
/*-- trustdb.c --*/ /*-- trustdb.c --*/
void list_trust_path( const char *username );
void register_trusted_key( const char *string ); void register_trusted_key( const char *string );
void check_trustdb( const char *username ); void check_trustdb (void);
void update_trustdb (void); void update_trustdb (void);
int setup_trustdb( int level, const char *dbname ); int setup_trustdb( int level, const char *dbname );
void init_trustdb( void ); void init_trustdb( void );
void sync_trustdb( void ); void sync_trustdb( void );
int check_trust( PKT_public_key *pk, int *r_trustlevel,
const byte* nh, int (*add_fnc)(ulong), unsigned *retflgs ); int trust_letter( unsigned value );
int query_trust_info( PKT_public_key *pk, const byte *nh );
void revalidation_mark (void);
unsigned int get_validity (PKT_public_key *pk, const byte *namehash);
int get_validity_info (PKT_public_key *pk, const byte *namehash);
void list_trust_path( const char *username );
int enum_cert_paths( void **context, ulong *lid, int enum_cert_paths( void **context, ulong *lid,
unsigned *ownertrust, unsigned *validity ); unsigned *ownertrust, unsigned *validity );
void enum_cert_paths_print( void **context, FILE *fp, void enum_cert_paths_print( void **context, FILE *fp,
int refresh, ulong selected_lid ); int refresh, ulong selected_lid );
unsigned get_ownertrust( ulong lid );
int get_ownertrust_info( ulong lid ); unsigned int get_ownertrust (PKT_public_key *pk);
int keyid_from_lid( ulong lid, u32 *keyid ); int get_ownertrust_info (PKT_public_key *pk);
ulong lid_from_keyblock( KBNODE keyblock ); void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
int query_trust_record( PKT_public_key *pk );
int clear_trust_checked_flag( PKT_public_key *pk );
int update_trust_record( KBNODE keyblock, int fast, int *modified );
int insert_trust_record( KBNODE keyblock );
int insert_trust_record_by_pk( PKT_public_key *pk );
int update_ownertrust( ulong lid, unsigned new_trust );
int trust_letter( unsigned value );
/*-- tdbdump.c --*/ /*-- tdbdump.c --*/
void list_trustdb(const char *username); void list_trustdb(const char *username);
@ -70,6 +70,6 @@ void export_ownertrust(void);
void import_ownertrust(const char *fname); void import_ownertrust(const char *fname);
/*-- pkclist.c --*/ /*-- pkclist.c --*/
int edit_ownertrust( ulong lid, int mode ); int edit_ownertrust (PKT_public_key *pk, int mode );
#endif /*G10_TRUSTDB_H*/ #endif /*G10_TRUSTDB_H*/